Compiling, Running and Debugging Java Programs


Index

NOTE: These instructions are for using Sun's distribution of java (SDK) without an IDE. If you are using some type of Java IDE (like Eclipse) then you should look at its documentation for information on using its editing and debugging features.

Compiling Java Source Code

Before the Java virtual machine (VM) can run a Java program, the program's Java source code must be compiled into byte-code using the javac compiler. Java byte-code is a platform independent version of machine code; the target machine is the Java VM rather than the underlying architecture. To compile a Java source code file Foo.java, you would do the following:
	% javac -g Foo.java
The -g command line option is optional, but we recommend using it as it makes debugging easier.

If there are no errors in your source file, the Java compiler will produce one or more .class files (one .class file for each class defined in the Foo.java source file). For example, the results of a successful compile of Foo.java will produce a byte-code version of the class in a file named Foo.class.

Every public class that you write must be in a separate .java file where the first part of the file name is identical to the class name. The .java file additionally can contain code for protected and private classes.

We suggest that you get in the habit of using makefiles for compiling your Java application code. More information on makefiles is available here.


Running a Java application

Once you have successfully compiled your Java source code, you can invoke the Java VM to run your application's byte-code:
    % java <class with main method to run> [<command line args>, ...] 
For example, to run the main method from the Foo class:
    % java Foo
Any command line arguments (arguments to Foo's main method) follow the class name:
    % java Foo 10 20

The CLASSPATH environment variable and JAR files

When the Java VM runs your program it searches for application .class files using the paths listed in your CLASSPATH environment variable. To run a simple Java application, you do not need to set a CLASSPATH environment variable; the Java VM looks for classes in the current working directory by default. However, if your program uses classes that are not in the current working directory, then you need to explicitly set your CLASSPATH environment variable to list all the directories containing classes used by this application. In addition, if your program uses classes contained in a JAR (Java ARchive) file, then the JAR file must be listed in your CLASSPATH. A JAR file is a single file that contains many .class files.

After the first few weeks of class, we will start using the book's JDSL library, and you will need to add this library's JAR file to your CLASSPATH. To your .cshrc file, add the following:

setenv CLASSPATH ./:/home/newhall/public_html/cs35/book_classes/lib/jdsl_general.jar
Each path is separated by a ':'. In this example, CLASSPATH is set to two directories: the current directory (./) and the dsl_general.jar file. If you have a CLASSPATH environment variable defined, then the VM uses the paths listed in the CLASSPATH environment variable rather than searching using its default paths. As a result, if you set this environment variable you need to add the current path otherwise the VM will not find classes in the current working directory.

Debugging Java Code

If your program terminates with a thread dump, and if you are using a just-in-time compiler Java VM (by default, JDK runs as just-in-time compiler VM), then the thread dump will likely contain lots of useless information. To get thread dump information in terms of your Java source code, compile with -g and run the Java virtual machine in all-interpreted mode using the -Djava.compiler=NONE command line argument:
	java -Djava.compiler=NONE blah


Compile with -g. This will cause the java compiler to put Java source code line information in .class files:

	javac -g blah.java

JDB

Use
jdb to set breakpoints, dump thread stacks, and step through the execution. jdb has a dbx-like interface rather than a gdb-like interface. Running jdb and typing help will provide you with information about jdb's commands. Here are some commonly used commands:

Debugging threaded Java applications

Debugging threaded java applications with jdb is a bit ugly. For threaded applications, try reducing the total number of application threads to one or two if possible. Also, the Thread class has some methods to help you debug threaded Java applications. You can explicitly add debugging code to your Java program to print out information about the threads in your program.

If all else fails, add debugging output statments to your code.