The concept of a path should be familiar to anyone who
has worked on a DOS or Unix platform. It’s an environment variable that
provides an application with a list of places to look for some resource.
The most common example is a path for executable programs. In a Unix
shell, the PATH
environment variable
is a colon-separated list of directories that are searched, in order, when
the user types the name of a command. The Java CLASSPATH
environment
variable, similarly, is a list of locations that are searched for Java
class files. Both the Java interpreter and the Java compiler use the
CLASSPATH
when searching for packages
and Java classes.
An element of the classpath can be a directory or a JAR file. Java also supports archives in the conventional ZIP format, but JAR and ZIP are really the same format. JARs are simple archives that include extra files (metadata) that describe each archive’s contents. JAR files are created with the JDK’s jar utility; many tools for creating ZIP archives are publicly available and can be used to inspect or create JAR files as well. The archive format enables large groups of classes and their resources to be distributed in a single file; the Java runtime automatically extracts individual class files from the archive as needed.
The precise means and format for setting the classpath vary from
system to system. On a Unix system (including Mac OS X), you set the
CLASSPATH
environment variable with a
colon-separated list of directories and class archive files:
%
export
CLASSPATH
=/
home
/
vicky
/
Java
/
classes:
/
home
/
josh
/
lib
/
foo
.
jar
:.
This example specifies a classpath with three locations: a directory
in the user’s home, a JAR file in another user’s directory, and the
current directory, which is always specified with a dot (.
). The last component of the classpath, the
current directory, is useful when you are tinkering with classes.
On a Windows system, the CLASSPATH
environment variable is set with a
semicolon-separated list of directories and class archive files:
C:
\
>
set
CLASSPATH
=
C:
\
home
\
vicky
\
Java
\
classes
;
C:
\
home
\
josh
\
lib
\
foo
.
jar
;.
The Java launcher and the other command-line tools know how to find
the core classes, which are the classes included in every Java
installation. The classes in the java.lang
, java.io
, java.net
, and javax.swing
packages, for example, are all core
classes so you do not need to include these classes in your
classpath.
The classpath may also include “*” wildcards that match all JAR files within a directory. For example:
export
CLASSPATH
=/
home
/
pat
/
libs
/*
To find other classes, the Java interpreter searches the elements of
the classpath in order. The search combines the path location and the
components of the fully qualified class name. For example, consider a
search for the class animals.birds.BigBird
. Searching the classpath
directory /usr/lib/java means the interpreter looks
for an individual class file at
/usr/lib/java/animals/birds/BigBird.class. Searching
a ZIP or JAR archive on the classpath, say
/home/vicky/myutils.jar, means that the interpreter
looks for component file animals/birds/BigBird.class
within that archive.
For the Java runtime, java, and the Java
compiler, javac, the classpath can also be
specified with the -classpath
option:
%
javac
-
classpath
/
home
/
pat
/
classes:
/
utils
/
utils
.
jar
:.
Foo
.
java
If you don’t specify the CLASSPATH
environment
variable or command-line option, the classpath defaults to the current
directory (.
); this means that the
files in your current directory are normally available. If you change the
classpath and don’t include the current directory, these files will no
longer be accessible.
We suspect that about 80 percent of the problems that newcomers have when first learning Java are classpath-related. You may wish to pay particular attention to setting and checking the classpath when getting started. If you’re working inside an IDE, it may remove some or all of the burden of managing the classpath. Ultimately, however, understanding the classpath and knowing exactly what is in it when your application runs is very important to your long-term sanity. The javap command, discussed next, can be useful in debugging classpath issues.
A useful tool to know about is the javap command. With javap, you can print a description of a compiled class. You don’t need the source code, and you don’t even need to know exactly where it is, only that it is in your classpath. For example:
%
javap
java
.
util
.
Stack
prints the information about the java.util.Stack
class:
Compiled
from
"Stack.java"
public
class
java
.
util
.
Stack
<
E
>
extends
java
.
util
.
Vector
<
E
>
{
public
java
.
util
.
Stack
();
public
E
push
(
E
);
public
synchronized
E
pop
();
public
synchronized
E
peek
();
public
boolean
empty
();
public
synchronized
int
search
(
java
.
lang
.
Object
);
}
This is very useful if you don’t have other documentation
handy and can also be helpful in debugging classpath problems. Using
javap, you can determine whether a class is in the
classpath and possibly even which version you are looking at (many
classpath issues involve duplicate classes in the classpath). If you are
really curious, you can try javap with the
-c
option, which causes it to also print the
JVM instructions for each method in the class!
Get Learning Java, 4th Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.