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.
Explained
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
(Unix, including Mac OS X, and Windows). You set it the same way you set other
environment variables, such as your PATH environment variable.
Alternatively, you can specify the CLASSPATH for a given command on its command
line:
java -classpath \c:\ian\classes MyProg
Suppose your CLASSPATH were set to C:\classes;. on 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 tried 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 vague “some file(s) in the JDK directory” is release-dependent. On Sun’s JDK it
can be found in the system properties:
sun.boot.class.path = C:\JDK1.4\JRE\lib\rt.jar;C:\JDK1.4\JRE\lib\i18n.jar;C:\JDK1.4\ JRE\classes
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, darwinsys.jar. You might then set your CLASSPATH to C:\
classes;C:\classes\darwinsys.jar;. on Windows or ~/classes:~/classes/darwinsys.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 Java Servlets)
may not use either bootpath or CLASSPATH as shown; these application servers typically
provide their own ClassLoader.
Another useful tool in 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,
looked around in, and read from a file \jdk\lib\tools.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.4/lib/tools.jar sun.tools.javap.JavaP Usage: javap...
javac -d /classes HelloWorld.java
# These guys must be present in my classpath... export CLASSPATH=/home/ian/classes/darwinsys.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 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:." do
This builds a minimum CLASSPATH out of darwinsys.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.
No comments:
Post a Comment