Using CLASSPATH Effectively

Problem

You need to keep your class files in a common directory or you’re wrestling with CLASSPATH.

Solution

Set CLASSPATH to the list of directories and/or JAR files that contain the classes you want.

Discussion

CLASSPATH is one of the more interesting aspects of using Java. You can store your class files in any of a number of directories, JAR files, or zip files. Just like the PATH your system uses for finding programs, the CLASSPATH is used by the Java runtime to find classes. Even when you type something as simple as java HelloWorld, the Java interpreter looks in each of the places named in your CLASSPATH until it finds a match. Let’s work through an example.

The CLASSPATH can be set as an environment variable on systems that support this (at least Unix and MS-Windows). You set it in the same syntax as your PATH environment variable. PATH is a list of directories to look in for programs; CLASSPATH is a list of directories or JAR files to look in for classes.

Alternatively, you can set your CLASSPATH right on the command line:

java -classpath c:ianclasses MyProg

Suppose your CLASSPATH were set to C:classes;. on MS-Windows, or ~/classes:. on Unix (on the Mac, you can set the CLASSPATH with JBindery). Suppose you had just compiled a file named HelloWorld.java into HelloWorld.class, and went to run it. On Unix, if you run one of the kernel tracing tools (trace, strace, truss, ktrace) you would probably see the Java program open (or stat, or access) the following files:

  • Some file(s) in the JDK directory;

  • Then ~/classes/HelloWorld.class, which it probably wouldn’t find;

  • And ./HelloWorld.class, which it would find, open, and read into memory.

The “some file(s) in the JDK directory” is release-dependent. On JDK 1.2 it can be found in the system properties:

sun.boot.class.path = C:JDK1.2JRElib
t.jar;C:JDK1.2JRElibi18n.jar;C:
JDK1.2JREclasses

The file rt.jar is the RunTime stuff; i18n.jar is the internationalization; and classes is an optional directory where you can install additional classes.

Suppose you had also installed the JAR file containing the supporting classes for programs from this book, com-darwinsys-util.jar. You might then set your CLASSPATH to C:classes;C:classescom-darwinsys-util.jar; on MS-Windows, or ~/classes:~/classes/com-darwinsys-util.jar:. on Unix. Notice that you do need to list the JAR file explicitly. Unlike a single class file, placing a JAR file into a directory listed in your CLASSPATH does not suffice to make it available.

Note that certain specialized programs (such as a web server running servlets; see Chapter 18) may not use either bootpath or CLASSPATH as shown; they provide their own ClassLoader (see Section 25.5 for information on class loaders).

Another useful part of the JDK is javap, which by default prints the external face of a class file: its full name, its public methods and fields, and so on. If you ran a command like javap HelloWorld under kernel tracing, you would find that it opened, seeked around in, and read from a file jdklib ools.jar, and then got around to looking for your HelloWorld class, as previously. Yet there is no entry for this in your CLASSPATH setting. What’s happening here is that the javap command sets its CLASSPATH internally to include the tools.jar file. If it can do this, why can’t you? You can, but not as easily as you might expect. If you try the obvious first attempt at doing a setProperty("java.class.path") to itself plus the delimiter plus jdk/lib/tools.jar, you won’t be able to find the JavaP class (sun.tools.java.JavaP); the CLASSPATH is set in the java.class.path at the beginning of execution, before your program starts. You can try it manually and see that it works if you set it beforehand:

C:javasrc>java -classpath /jdk1.2/lib/tools.jar sun.tools.javap.JavaP
Usage: javap <options> <classes>...

If you need to do this in an application, you can either set it in a startup script, as we did here, or write C code to start Java, which is described in Section 26.6.

How can you easily store class files into a directory in your CLASSPATH? The javac command has a -d dir option, which specifies where the compiler output should go. For example, using -d to put the HelloWorld class file into my /classes directory, I just say:

javac -d /classes HelloWorld.java

Then, as long as this directory remains in my CLASSPATH, I can access the class file regardless of my current directory. That’s one of the key benefits of using CLASSPATH.

Managing CLASSPATH can be tricky, particularly when you alternate among several JVMs, as I do, or if you have multiple directories in which to look for JAR files. You may want to use some sort of batch file or shell script to control this. Here is part of the script that I use. It was written for the Korn shell on Unix, but similar scripts could be written in the C shell or as a DOS batch file.

# These guys must be present in my classpath...
export CLASSPATH=/home/ian/classes/com-darwinsys-util.jar:
 
# Now a for loop, testing for .jar/.zip or [ -d ... ]
OPT_JARS="$HOME/classes $HOME/classes/*.jar
    ${JAVAHOME}/jre/lib/ext/*.jar
    /usr/local/antlr-2.6.0"
 
for thing in $OPT_JARS
do
    if [ -f $thing ]; then       //must be either a file...
        CLASSPATH="$CLASSPATH:$thing"
    else if [ -d $thing ]; then       //or a directory
        CLASSPATH="$CLASSPATH:$thing"
    fi
done
CLASSPATH="$CLASSPATH:."

This builds a minimum CLASSPATH out of com.darwinsys-util.jar, then goes through a list of other files and directories to check that each is present on this system (I use this script on several machines on a network), and ends up adding a dot (.) to the end of the CLASSPATH.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.140.195.225