Showing posts with label COMMAND LINE. Show all posts
Showing posts with label COMMAND LINE. Show all posts

Friday, 21 September 2012

Java under Mac OS X 10.7 Lion

Lion is the first version of Mac OS X that doesn't come with Java already installed. Earlier versions not only had the Java Virtual Machine or runtime element installed, but they also had the JDK installed, which is the part that lets you write your own Java programs.

Once, Java was an important part of Apple's strategy. They maintained their own version of Java for the Mac and encouraged its use by developers every bit as much as they encouraged the use of Objective-C.

The success of the iPhone and the iPad have changed that, however. Apple decided that Java would not be part of those platforms. The lack of Java is the very reason I've chosen not to get an iPhone. Instead, I get phones with Java so that I can run my own Java applications that I write for my own use.

Now that Lion doesn't have Java pre-installed, what do you do? Fortunately, a deal has been struck where Java is still available for the Mac. It's much the same arrangement as Java for other platforms. In fact, it's easier to install Java on your Mac than any other platform. And you get the JDK along with the runtime (JVM) environment.

Simply use Finder to go to Applications=>Utilities. There, start Terminal. Once Terminal starts, type in the command 'javac'. Your Mac will tell you that Java isn't installed, and let you install it.

I'm pleased that the Mac has not entirely forsaken Java, even if it's not an integral part as it has been. The basic software supplied with the Mac has declined severely over the past few years, but fortunately Java is still available and easy to install when you want it.

Saturday, 15 September 2012

Java's File Names and Class Names

Java is picky about the file names you use.

Each source file can contain one public class. The source file's name has to be the name of that class. By convention, the source file uses a .java filename extension (a tail end of a file name that marks the file as being of a particular type of file.)

So, for a class declared as such:
public class HelloWorld{
...

The file it is stored in should be named HelloWorld.java.

The capitalization should be the same in both cases. Some operating systems don't notice whether file names are capitalized or not. It doesn't matter, you should be in the habit of using the correct capitalization in case you work on a system that does care about capitalization.

When you compile your file with javac, you pass the full file name to javac:

javac HelloWorld.java

Let's say we save the file under a different name. We write the following program:

public class HelloThere{
    public static void main(String arg[]){
        System.out.println("Hello There.");
    }
}

Then we save it as HelloWorld.java, and try to compile it:
>javac HelloWorld.java
FileName.java:1: class HelloThere is public, should be declared 
in a file named HelloThere.java
public class HelloThere{
       ^
1 error


Java lets us know that it won't compile until we rename the file appropriately (according to its rules.)

So let's rename the file. Let's call it HelloThere.javasource. Seems a bit more explicit than just .java, right? Let's run the compiler:

>javac HelloThere.javasource 
error: Class names, 'HelloThere.javasource', are only accepted 
if annotation processing is explicitly requested
1 error

Java's still not happy with us. Annotation processing? That's when we include extra information in the program about the program itself. We're not bothering with that just now. So we should just name the file HelloThere.java, and not get fancy with our file names.

But, under the right circumstances, javac does allow file name extensions other than .java. That's why we always type in the full file name, including .java, when we use javac. We say 'javac HelloThere.java', not just 'javac HelloThere'. Javac can't assume that we mean a .java file, though that's what it will usually be.

The Class File

Once we make javac happy with a proper file name, and a program with no errors, javac produces a new file. This file will have the original file name, but with .java replaced with .class. This is your bytecode file, the file that the Java Virtual Machine can run.

When we run the program with Java, we're running the .class file. In the case of HelloThere, we're running the HelloThere.class file. But we don't type in the full file name. Why?

Unlike javac, java requires a .class file. That's all it will work with. There's no opportunity to have a different extension to the file name. So it assumes the .class part of the file name. But that's not the whole story.

If you add .class yourself, here's what you'll get:
>java HelloThere.class
Exception in thread "main" java.lang.NoClassDefFoundError: 
 HelloThere/class
Caused by: java.lang.ClassNotFoundException: HelloThere.class
 at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

Pretty ugly. What we're actually doing when we type "java HelloThere" is telling Java to run the class HelloThere. Java assumes that it will find this in a file called "HelloThere.class", so that's what it's looking for first.

We're not telling Java to run the file HelloThere.class, we're telling it to run the class HelloThere, which it expects to find in the file HelloThere.class.

But what if we ask for another class that doesn't have its own .class file?

Just for fun, let's change HelloThere.java like this, and see what happens:

public class HelloThere{
 public static void main(String[] arg){
  System.out.println("Hello.");
 }
}

class HelloZoik{
 public static void main(String[] arg){
  System.out.println("Zoiks!");
 }
}

After we edit it, we compile with 'javac HelloThere.java' and hold our breath.

Hurray! No errors!

Now we have a second class, HelloZoik, in the HelloThere.class file. Can Java find it?

Let's try:

 java HelloZoik
Zoiks!

It worked! Java found our class inside HelloThere.class.

This shows it's not the file name that we're calling with the 'java' command, it's the class name.

If Java doesn't find the class inside a file with the same name as the class followed by .class, it'll look in the other .class files available.

Calling System Commands in Java

Let's suppose you want to run another program on your system from within Java. Personally, I first decided I wanted to do this for the sake of a prank. You may have more businesslike purposes in mind, yourself.

It's not too hard to do this since Java 1.5, which added the Process and ProcessBuilder classes.

Here's an example program that starts up Firefox at a particular website:

public class OpenSite{
  public static void main(String arg[]){
    try { Process p = new ProcessBuilder("firefox", 
            "http://beginwithjava.blogspot.com/").start(); }
   catch(java.io.IOException io){ }
  }
}

I've compressed the various parts of the action down to one line here:

Process p = new ProcessBuilder("firefox", "http://beginwithjava.blogspot.com/").start();

I'm creating an "anonymous" ProcessBuilder object, calling its start() method, which returns a Process, which I name simply "p".

The whole thing is wrapped up in a try...catch structure because javac wants to see us deal with any I/O errors that result. In this program, I just ignore them.

So you'll want to make sure that you either catch those errors and deal with them, or that they will be unimportant enough that they don't matter.

Also note that the Java program's process will last as long as the external program you call. So if you don't shut down this instance of the firefox process, you'll have Java still running.

If you want to see something fun you can do with this on Mac, check out this article about adding speech to the Simple Video Game Kernel.

Friday, 14 September 2012

Mini-Review: Beginning Programming with Java for Dummies by Barry Burd

Of the books currently available, this one is my favorite for teaching non-programmers the basics of programming. This is in spite of the fact that it goes against a few strongly-held opinions of mine. I have worked through the book myself, and had a student with no prior programming experience use the book for self-study. So the opinions here are based on my own experience as an instructor and the feedback I've gotten from the student.

The writing style of this book is fun and easy to read. This is always a big plus for books that teach a complex and unfamiliar subject. The material is also varied from chapter to chapter, meaning that you won't be going to sleep writing different kinds of loops for three straight chapters. Subjects are interleaved, for example, there is a section on using files that breaks up material on loops and iteration.

The start of the book is quite leisurely. This is valuable in a book for non-programmers, I feel. The pace of the book picks up as it goes, so don't be fooled into thinking the book is just a brief tutorial that's been padded out into book length. The early sections are also quick reads, and sections on installing Java can be scanned or skipped over as appropriate. The pages dedicated to installing the JDK are there for a good reason, though. My experience is that just getting the JDK installed and running is one of the biggest hurdles for non-programmers who want to learn Java.

The differences I have with this book are few, but significant. The first is that graphics are left until the very tail end of the book. As I've stated elsewhere, I'm a proponent of teaching graphics early. I feel they're a good motivator for new programmers, and they allow new programmers to visualize the effects of their program's flow control structures in a way that rows of numbers can't equal.

The second difference I have with this book's approach is the use of an integrated development environment (IDE) right from the start. I've also commented in a prior article why I think it's a good idea to at least be familiar with common command line operations before starting with the IDE. I feel that starting with an IDE right off glosses over some skills that are crucial to programmers at any skill level.

The third concern I have with the book is that it recommends the use of a Windows-only IDE for use with the book. Now, if this were a .Net book or something similarly tied to a single platform I wouldn't have any problem with this. But this is a Java book! Why not a good multiplatform IDE written in Java? It's not like there aren't any good choices. My student was working on a Mac, and was able to complete the work in the book with no problem using, primarily, Arachnophilia but also using BlueJ for the latter part of the book.

I would also be concerned that people seeing the recommendation of a platform-specific IDE early in the book would think that therefore the book itself contains a substantial measure of platform-specific content. It doesn't, but flipping through the start of the book isn't enough to make that clear.

The focus of the book is on the basics of programming. It does not dip heavily into object oriented programming. It simply uses Java and its facilities to teach introductory programming in much the same way as one might use C or Pascal for the same purpose. I don't yet consider this a problem, though Greenfoot may convince me that objects and classes should be right up front now. However, I feel that starting with this book and then moving on to other resources like Greenfoot and Head First Java to develop a better understanding of Java and object oriented programming is a perfectly acceptable way to learn.

Even with its problems, I consider this book to be the best on the market for a non-programmer. It does not go as deeply into Java as Beginning Programming in Java for the Absolute Beginner, but it's an easier read and overall I like the structure better even though it covers less.

Final Grade: 90%, A

Pros:
Easy to read.
Good pacing of material.
Doesn't get boring.
A very good introduction to programming.

Cons:
Uses an IDE, and recommends a Windows-specific IDE (though any multiplatform IDE will work.)
Graphics are left until the very end.
Limited scope, but it's easy to go on from here.

Recommendation:
Get it if you're a non-programmer looking to learn how to program. You may also want to get the "next" Java book you plan on using at the same time, and start referring to it as you work through this one. You should consider downloading Greenfoot then going through its tutorials to get a grounding in classes and objects. You'll also want to get a multi-platform IDE for Java, even if you are on Windows. You may decide to use Greenfoot for this, or BlueJ or Arachnophilia (or perhaps even Eclipse or NetBeans, if you have a mentor to help you get started with them.)

Getting Keyboard Input for Console Apps: Java's Scanner Class

A nice gift that came with Java 1.5 was the Scanner class. It's part of the java.util package. This class simplifies many common programming tasks. One is getting text from the keyboard.

Prior to Scanner, this took a couple of extra steps. With Scanner, it's a snap. Just as we use System.out to print text to the command line, we use System.in to receive input. Like System.out, System.in is a data stream object. In this case, an InputStream object.
import java.util.Scanner;

public class TrollTalk{
  public static void main(String arg[]){
    String nayme="";  // Declare & initialize a String to hold input.
    Scanner input=new Scanner(System.in); // Decl. & init. a Scanner.

    System.out.print("Whut yur nayme? >");  // Troll asks for name.
    nayme=input.next(); // Get what the user types.
    System.out.println();  // Move down to a fresh line.
    // Then say something trollish and use their name.
    System.out.println("Hur, hur! Dat's a phunny nayme, " + nayme + "!");
  }
}

Our Scanner is named input. We could have called it gzorgnplat, if we wanted to--there's nothing magic about the name 'input'. We attach that name to a new Scanner object that accepts vlues from System.in. Then we print a message so that the user knows they're supposed to type something. The message is a question we want them to answer and a greater-than sign to let them know the computer is ready for them to type.

Being able to accept input while the program is running lets us create interactive command line apps.

Scanner can also be used to get particular types of input like numbers of particular primitive types.

It can also be used to get information from files in the same way it gets information from the user's keyboard. But that's another lesson.

Why Start at the Command Line?

Many instructors, including myself, start students out at the command line when we teach programming. With all the great tools out there, why bother? It's not like you start out a basic computer class with an old floppy-disk based system and start teaching the students how to run Windows or OS X by having them boot up CP/M or Integer BASIC.

The main reason I do it, even though I move on to a graphical integrated development environment (IDE) pretty quickly, is that it's important to understand what your tools are doing for you. Also, it's important to be able to work with your program files outside the IDE.

Your program is saved in a file, or a group of files. You should know how to recognize those files, and where to find them. They may be stored in a special directory for that programming project. You should know what it is named, and where to find it. At least well enough that you can recognize it when you do a file search.

You also may end up in a situation where you don't have the IDE but want to get something done. If you've taken a copy of your program to a friend's system, you should know how to run the program without the IDE. You should know which file is the source code and which is the compiled version that you want to actually run. And, since you're doing it with someone looking over your shoulder, you'll want to be able to do it without a lot of hemming and hawing and trying to remember how to start the program. Which means you'll want to be familiar with how it's done. You will also want to know how to check which version of Java is on the system, so if they're running a JVM from the days of the cavemen, you'll know. (And wouldn't it be nice to know how to install a newer one for them without any trouble?)

So don't let the command line put you off. Even if you've started with an IDE, go ahead and use the command line sometime to do the basic tasks of showing your source file's contents, compiling your source file, and running it.