Conceptually, the Java classpath is a list of locations (in a file
system) to be used by the Java tools in order to find the (compiled)
code (.class
and .jar
files) of the
user-defined classes and packages necessary for a given application.
Note: The locations of the code of the core Java classes (the fundamental classes required by the Java language or the libraries provided by the JRE/JDK installation) are not located via the classpath.
In particular, the classpath is used by:
the Java compiler (javac
command):
when compiling a given class A that uses another class
B, the compiler need to check that A correctly uses
B (existing method names, correct list/types of parameters,
etc.)
the Java virtual machine, often abbreviated as
“JVM” (java
command): when executing a Java application,
the JVM needs to find and load the code of all the involved classes.
(Note that usually, the JVM loads classes “lazily”: this means that the
class is only loaded when it is really needed, so not necessarily during
the startup of the application.)
Note: The examples here are focused on Linux/Unix systems. There are some (minor) differences in the case of Windows systems (but the concepts are similar).
The are two ways to configure the classpath via the command line in a shell:
CLASSPATH
environment variablejavac
or java
, depending on the
situation)Below, we will focus on the second way (command line argument), using
javac
as an example.
The classpath is defined as a list of paths separated by colons
(:
).
Let us consider the following example:
We want to compile Toto.java
, which depends on four
other classes:
/home/john/Hello.class
/home/john/stuff/Yes.class
/home/john/stuff/Bye.class
AnotherClass.class
, which is stored inside the
following JAR (archive) file:
/home/john/stuff/MyJar.jar
Then we will use the following command line:
javac -cp /home/john:/home/john/stuff:/home/john/stuff/MyJar.jar Toto.java
Notice that we declare in the classpath:
.class
filesNotes:
When no classpath is explicitly defined, the Java tools will simply consider the current directory.
The precise command line syntax to set up the
CLASSPATH
environment variable depends on the type shell
that you are using (bash, tcsh, etc.). However, the syntax to be used
for the part of the line that describes the list of paths is actually
the same as above with -cp
.
When there is already a CLASSPATH
environment
variable defined, a command line with the -cp
argument will
use the classpath value provided by -cp
rather than the one
from the environment variable.
If a directory contains several JAR files, it is also possible to
use a wildcard. For example:
javac -cp /home/john/jars/* Tata.java
Typically, when compiling one or several classes, it is a good
practice to use the -d
option, in order to produce the
.class
files in a separate directory (distinct from the one
that contains the source files).
Let us consider the following example :
We are currently in the /home/jane
directory. We can
create two subdirectories: src
and build
. And
we can compile our file with the following command:
javac -d bin -cp /home/john:/home/john/stuff:/home/john/stuff/MyJar.jar src/Toto.java
Then, Toto.class
will be found in
/home/jane/build
And you can launch the execution of the application using the
following command (we assume in this scenario that Toto
is
the class providing the main
method):
java -cp /home/john:/home/john/stuff:/home/john/stuff/MyJar.jar:/home/jane/build Toto
The JVM will look for a file named Toto.class
in all the
locations specified in the classpath and will finally find it in
/home/jane/build
.
Important warning: the situation is a bit different
if the class Toto
belongs to a package.
For example, let us assume that the Toto.java
file
contains the following line: package org.mypackage;
.
In that case, we use the same command as above for the compilation:
javac -d bin -cp /home/john:/home/john/stuff:/home/john/stuff/MyJar.jar src/Toto.java
But the produced file will be placed in a slightly different location
(the subdirectories will be automatically created if necessary):
/home/jane/build/org/mypackage
And we must also slightly modify the command to launch the execution of the application:
java -cp /home/john:/home/john/stuff:/home/john/stuff/MyJar.jar:/home/jane/build org.mypackage.Toto
Notice the following points: