Unix Lab



Compiling Java Programs on a Unix system



Using the Java compiler

In this module we will learn how to use a Java compiler in a command-line Unix environment. The java compiler is invoked with the javac command.

You can determine if the compiler is available on the Unix system you are using by just typing the command with no parameters. It should complain that there are no parameters by telling you how to use it. This tells you it's there and waiting for your compilation requests.

Compiling a java source file

In the PC or Macintosh world, you are probably accustomed to an IDE or Integrated Development Environment for creating, compiling, and loading Java programs. In such an environment, you edit, compile, and even run programs while you are creating and debugging them.

You should already know how to create and edit your source files using a text editor. Any text editor will work. Once you have a source file, you can then compile it and produce a class file. The class file contains the bytecodes generated by the Java compiler and represent an intermediate set of instructions that can be easily executed by a Java Virtual Machine (JVM).

Create a subdirectory named project in your home directory for the exercises in this module. Copy the files named Patterns.java and PatternMaker.java into the project directory from the directory /handouts/cs46blab.

You can view these files by using cat or more.

In the project directory, type:

javac PatternMaker.java

If you check you will see that there is now another file in your directory named Patternmaker.class. This file contains the compiled form of the Java source file.

The javac command executes the Java compiler. The named file must be a java source code file and must have a .java extension. Moreover, the name of the class defined within the .java file must be the same as the name of the .java file (excluding the extension).

Now delete the .class file generated in the previous exercise and type:

javac Patterns.java

View the contents of the project directory. You should notice that there are two .class files, the one you probably expected: Patterns.class, but also the file PatternMaker.class. Why the second one?

The java compiler needs to know about any class that you use in a file that it is compiling. If that class isn't part of the Java API (the classes that are supplied automatically with Java), then it must be available somewhere locally.

The java compiler noticed that there was a reference to the PatternMaker class in the Patterns.java file. It found that this is not part of the Java API so it looked around and found the file PatternMaker.java file in the current directory. So it compiled that file, too, and generated the PatternMaker.class file.

The java compiler will compile as many .java files as it needs (provided it can find them) to satisfy the need to resolve any classes that it doesn't know about.


Executing a java program

Java programs are executed by calling on the Java Virtual Machine to execute them. This is done by using the java command.

Type the following:

java Patterns 18 21

The command requires that you give it the name of a class (notice that there is no .class extension). The stuff following the class name are parameters that are (in this case) read by the program to do whatever it's doing. In this case, the 18 is a number between 1 ane 255 that will result in a different pattern being generated for each value and 21 is the number of lines that you want to see generated. You should play with other choices to see the results of other patterns (instead of 18 try 126, for example).

The class named in the java command must have a static main method (which you can verify by viewing the source file: Patterns.java). Here, we're just concerned with compiling and executing Java programs, not with some of these issues you will learn (or have learned) in your computer science classes.


The CLASSPATH environment variable

When the Java compiler compiles your .java files, it must be able to find the .class file for any class that you reference in your .java file. We saw above that even if the necessary .class file doesn't exist but the .java file does, the Java compiler will go ahead and create the .class file that it needs from the .java file.

The compiler can only find files if it knows where to look. And the only place it looks is in each of the directories named in a string variable that the shell makes available called CLASSPATH.

Type the following:

echo $CLASSPATH

The use of uppercase letters is important since Unix distinguishes lower case from uppercase. What you should see is a list of directories separated by the : character. Are any of these directories in your home directory area? Is the current working directory one of the directories listed (the "current working directory" is indicated by a single . character)?

If you get a message such as
CLASSPATH: Undefined variable.
then you will have to assign a value to CLASSPATH. This is done as follows.

Go to your home directory and use a text editor to open the file .cshrc which is stored in your home directory. This file is used by the C shell to set various parameters that it needs to work with (such as the CLASSPATH variable).

Just before the line that begins with if ( ..., insert the following line making sure the spacing is just as it shows here:
setenv CLASSPATH "/usr/java/bin:."
then save the file and exit the editor.

Finally, you need to tell the C shell to read your .cshrc file so that it can incorporate the information you have supplied. To do this issue the command:

source .cshrc

In your home directory create a new directory called graph. Into that directory, copy the files

   Connection.java
   GraphUSAReader.java
   FindNeighbors.java
   graph.usa
from the directory named /handouts/cs46blab.

Now type the following:
javac FindNeighbors.java

You should probably see a message that tells you that the compiler cannot locate one of the classes required to carry out the compilation. This might be notification of a missing class or a message about a missing package.

What's happening is that the Java compiler is looking for a package (named archipelago in this example) but it can't find it. It's telling you that the problem is in the GraphUSAReader.java file

In your home directory, if you have not already created one, create a directory named lib. Into this directory copy the file archipelago.jar from the /handouts/cs46blab directory.

The archipelago.jar file contains the necessary class files that the Java compiler was looking for in the previous exercise. These classes are in a special file type that we will look at later when we cover jar files. We're placing it in a directory that we can place such utilities that we need in many projects. Now we need to tell the Java compiler where to find this jar file.

Go to your home directory and edit the .cshrc file using your favorite editor. Look for the line in there that starts with:
setenv CLASSPATH ...
At the end of that line we want to add the characters:
:/home/yourLoginName/lib/archipelago.jar
Where yourLoginName is whatever is appropriate for you.

What we're doing is changing the CLASSPATH string variable so that it contains, in addition to the other directory names, the name of the jar file in the lib directory in your home directory.

If you are a careful person, you will have noticed that in a list of directories, we have placed the name of a file. The Java compiler understands that jar files are like directories (containers of files) and it "does the right thing" to extract the needed .class file.

Making a change to the .cshrc file won't take effect until the next time you open a terminal window or the next time you login. You can get around this by typing in your home directory:
source .cshrc

This causes the C shell to (re-)execute the commands in the .cshrc file. One of these (the one you changed) will set the CLASSPATH variable.

Now go back and re-compile the Java program that we tried above:
javac FindNeighbors.java

This time the Java compiler should be able to find the archipelago.jar file which contains the missing class that it couldn't find before.


Options for the javac command

The javac command can take several options. These options tell the compiler to do extra things or give it information that it may need.

Java is still changing and some classes that belong to the API have been replaced by better, more recent versions. In fact, these classes may soon no longer be a part of the Java API. This would mean that your program would no longer execute at some point in the future. In order to find out which (if any) of these "deprecated" classes you may be using, you can use the -deprecation option.

You may want the .class files that the compiler generates to be placed in some directory other than the current working directory. If so you can use the -d directoryname to do this.

Re-compile the Java program (FindNeighbors) that we tried above and place the .class files that get generated in your home directory. What is the command?

Re-compile the FindNeighbors program that we tried above and see if there are any depcrecated APIs referenced in that program. What is the command?

Finally, use the -verbose option and recompile the FindNeighbors program after you have deleted all the .class files that you created previously. What does this option do?


Click on to go back to the main directory.

Click on to take the quiz for this module.

These pages were developed by John Avila SJSU CS Dept.