Java Programming on Stanford UNIX

Introduction

To write Java programs in unix, you will need several tools: an editor, a compiler, and a debugger. We'll describe each of these, but you can read the man pages or talk to the TAs for more information.   Also, the Sweet Hall consulting services hold classes covering using the leland workstations.  See their web page http://consult.stanford.edu. for more information.

Java Tools

The Java compiler and tools are already installed on the leland systems (currently version 1.3.1 as of Jan-2002). To use java, you must be on a Sun workstation (elaine, saga, myth), not an HP (amy). Previously, you had to put a special java entry in your path, however this is not longer the case. Your "path", which is defined in the .cshrc file in your home directory, should include the directory /usr/pubsw/bin -- the default site_path includes this directory, so probably you don't need to do anything.

Here's what that part of my .cshrc looks like. Each line must end with a "\".

    set site_path=( \
        /usr/local/bin /usr/pubsw/bin \
        /usr/bin /usr/ucb /usr/bsd /bin /usr/sbin \
         

The directory /usr/class/cs108/bin include some small tools that may be useful for java programming (see below). Here's what my .cshrc looks like with /usr/class/cs108/bin added...

set path=($site_path   /usr/class/cs108/bin   .  ~/bin  )

If you make any change to your .cshrc file, use the command "source .cshrc" to try your changes.

You can check that you account is setup to use java like this..

elaine27> which java
/usr/pubsw/bin/java
elaine27> java -version
java version "1.3.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_01)
Java HotSpot(TM) Client VM (build 1.3.1_01, mixed mode)

CLASSPATH environment variable

With Java 1.2 and later, the CLASSPATH variable can be left undefined (the empty string) for basic programming -- that's the simplest and most reliable strategy. You may want to comment out any old CLASSPATH definitions you may have in your .cshrc.

How the CLASSPATH works: At compile time, java needs to know where classes are stored so it can do the various compile-time checks for classes mentioned in the sources. At run-time, the java VM has a similar need to be able find classes to load them into memory. Both of these needs are addressed by the CLASSPATH variable. The CLASSPATH stores the set of directories and .zip and .jar files where the system will look for java classes.

When you execute a Java program, you give the name of the class to load, but you don't specify exactly where the interpreter will find the appropriate .class file. The interpreter has a standard list of directories that it searches to find .class files as needed. That list of directories is known as your CLASSPATH (not unlike the UNIX shell's PATH variable). CLASSPATH is an environment variable and it lists the directories in order that they will be searched, separated by colons (:). In Java 2, if the CLASSPATH is just not defined (the empty string), then the system uses the current directory which will work fine for our purposes.

If we want to use some Java library, such as jaxp.jar then we will add the full path to jaxp.jar the CLASSPATH while also including ".", so the current directory is still included. A typical setting of the CLASSPATH looks like...

setenv CLASSPATH /usr/class/cs108/jar/jaxp.jar:/usr/class/cs108/jar/crimson.jar:.

It must be one long line, and should include "." as the last directory. As usual, use "source .csrhc" as above to apply the .cshrc update. For basic work, it's fine for the CLASSPATH to not be set to anything. To check your CLASSPATH, use the command "echo $CLASSPATH" on the command line.

Editor

We recommend using emacs or xemacs to edit your source (.java) files, but feel free to use your favorite editor. (See http://consult.stanford.edu/pub/editors/emacs for emacs information). (Beginner tip) don't start/end your emacs session for every edit -- keep one session running for editing, and another session for compiling/running.
The name of each .java file you write must match the name of the public class defined in that file. So if you have a class called 108Student, the filename must be 108Student.java.

Compiler

The command line compiler is called "javac". It takes a list of .java files on the command line and compiles them to produce .class files. To compile a single file called myFile.java, type:

javac myFile.java

To compile your entire program, go to the directory where your program lives and type the following:

javac -g *.java

This will generate a class file for every class in your source files. If you had myFile1.java and myFile2.java in your directory, you would now also find myFile1.class and myFile2.class. The -g option tells the compiler to include debugging information.  This will allow you to examine variables in the debugger. Another way to compile your whole program is to run javac on the .java file containing your main() method.  This will compile all the files of classes used in your program for which .class files do not already exist.  To recompile everything from scratch, remove all of your .class files and then run javac on your main file. The rmclass script removes the class files for you. If you type "rm *.class" by hand, you risk accidentally typing "rm * .class" which deletes all your files. Using rmclass protects you from that little slipup. (Adding 108/bin is described above.)

Running

To run your code, type java name, where name is the name of the class containing the main() method you would like to run. For example:

java Tetris

You don't append .class to the name, it knows to look for a file called Tetris.class to load and then finds and executes the main() method of that class. The runtime system uses the same CLASSPATH as the compile time system to try to find a class by that name. The current directory is in the CLASSPATH, so that's usually how it finds your classes.

The Debugger (jdb)

Before talking about the debugger, we need to mention that much debugging can be accomplished with good old System.out.println() -- don't be shy about using it. However, using a "real" debugger  can be more powerful.

jdb is a command-line java debugger with an interface similar to gdb.   Itís not as sophisticated as gdb but it has the basics.  This section does describe all of the features of jdb, but will hit on the high points. You can access the on-line help by typing help at the jdb prompt.
To start the debugger from the shell just type jdb <TargetName> where <TargetName> is the name of the class with the main() method that you want to debug, like this :
jdb Tetris

(note you do not include the ".class" part of the name at the end). If you do not specify a target then jdb will start without a target and you will need to specify one later before you can do anything useful. The debugger is an interactive program. Once started, it will prompt you for commands. The most common commands in the debugger are: setting breakpoints, single stepping, continuing after a breakpoint, and examining the values of variables.

To start running your program within the debugger, type run at the prompt.
 

Breakpoints

You can set a breakpoint in jdb with either of the following two commands:
stop in <class id>.<method> -- set a breakpoint in a method
Ex: to put a breakpoint in RA.confide() method, type: stop in RA.confide

2. stop at <class id>:<line>   -- set a breakpoint at a line
Ex: to put a breakpoint at line 42 of the RA class, type: stop at RA:42

Here are more breakpont-related commands:
classes                     -- list currently known classes
methods <class id>          -- list a class's methods
clear <class id>:<line>     -- clear a breakpoint
clear <class id>.<method>   -- clear a breakpoint
 

When you stop at breakpoint, you can examine the stack and variables (see below) and when you want to continue execution you use the step and continue commands:
step                        -- execute current line
cont                        -- continue execution from breakpoint

Examining the stack

To answer the question of "where are we in the program?", we use the where, locals, up, and down commands to examine the run-time stack. The run-time stack is like a "trail of breadcrumbs" in a program; each time a method call is made, a "crumb is dropped" (a RT stack frame is pushed). When a return from a method occurs, the corresponding RT stack frame is popped and discarded. These stack frames contain valuable information about where the method was called in the source code (line # and file name), what the parameters for the call were, etc.
jdb assigns numbers to stack frames counting from one for the innermost (currently executing) frame. At any time jdb identifies one frame as the "selected" frame. Variable lookups are done with respect to the selected frame.  When the program being debugged stops (at a breakpoint), jdb selects the innermost frame. The where command prints a complete list of all stack frames, starting from the inner and listing outward to the main. The commands below can be used to select other frames by number or address.
up [n frames]             -- move up a thread's stack
down [n frames]           -- move down a thread's stack
locals                    -- print all local variables in current stack frame
 

Examining source files

Another way to find our current location in the program and other useful information is to examine the relevant source files. jdb provides the following command:

list [line number|method] -- print source code

For example, after hitting a breakpoint, you can view the current code by typing: list.   To look at random pieces of code in the current class, such as the confide method in the RA class, type:
list confide.
 

Examining data

It is also useful to answer the question, "what are the values of the variables around us?" In order
to do so, we use the following commands to examine variables:
print <id> [id(s)]        -- print object or field
dump <id> [id(s)]         -- print all object information
Ex: To print out the contents of an RA object called a, type: dump a
Type dump this to print out the entire state of current object.
 
 

Java library source

Of course your best resource for documentation is the class specifications available on Sun's documentation site, http://www.javasoft.com/products/jdk/1.3/docs/api/. Naturally, there are links for the various docs on the cs108 home page. However, sometimes digging through the java sources is more handy...

The source for all the JDK 1.3.1 classes is available in /usr/class/cs108/jdk1.3.1-src/. The java sources contain the text that is used to generage the javadoc comments for all the library classes, so digging through the sources can be a quick way to see the docs. Note that the source is copyrighted by Sun, and looking at it may inhibit your ability to write a "clean room" re-implementation of Java in the future.

The easy way to pull up a source file is using the tools "showjavasource" and "emacsjavasource" in the cs108/bin directory -- they take the name of a java source file (not case sensitive), and either dump it to the console or open it in emacs.

elaine27> showjavasource string.java
/*
 * @(#)String.java      1.130 01/02/09
 *
 * Copyright 1994-2001 Sun Microsystems, Inc. All Rights Reserved.
 *
...

To do it manually, cd to /usr/class/cs108/jdk1.3.1-src/ and type the following:

elaine:> find directory -name file.java -print
For instance, to find the source for ArrayList.java, you would type:
elaine:> find . -name ArrayList.java -print
and you will get:
./java/util/ArrayList.java
Then, you can cd into /usr/class/cs108/jdk1.3.1-src/java/util/ to look at the source.
 

Miscellaneous

Changing Window Managers

To change the window manager on your workstation you can: The window manager can be one of your choice. If you are used to working in Microsoft Windows you can try "x -w fvwm95".