What is the classpath in Java?
- tool
- Java
- versions
- Java 8+
- os
- any
The classpath is the ordered list of directories and JAR files in which the Java launcher and the compiler look for compiled classes that are not part of the JDK itself. You set it with -cp (or -classpath, --class-path) on java and javac, or with the CLASSPATH environment variable. If you set neither, it is the current directory.
How a class is found
When code names a class, such as com.example.App, the class loader turns the package into a folder path and checks each classpath entry from left to right. For a directory entry it looks for com/example/App.class below it; for a JAR entry it looks for the same path inside the archive. The first match wins, and later entries with the same class are ignored. Order therefore decides which version of a library is used when two JARs contain the same class.
The JDK classes in java.base and the other platform modules are not searched through the classpath; they come from the runtime image.
Setting it
| Form | Example | Notes |
|---|---|---|
| Command-line option | java -cp out:lib/a.jar com.example.App | Highest priority. Overrides CLASSPATH for this run. |
| Wildcard | java -cp "lib/*" com.example.App | Every .jar in lib/. Quote it so the shell does not expand it. Subfolders are not searched. |
| Environment variable | CLASSPATH=out java com.example.App | Used only when no -cp is given. Affects every Java tool run in that shell. |
| Default | java com.example.App | The current directory (a dot). |
| JAR manifest | Class-Path: lib/a.jar in META-INF/MANIFEST.MF | Used by java -jar. The -cp option is ignored with -jar. |
The separator between entries is : on Linux and macOS and ; on Windows.
Seeing it work
The block compiles a class into an out folder and then runs it with and without the folder on the classpath. JAVA_TOOL_OPTIONS is unset first so the JVM does not print its "Picked up" line.
unset JAVA_TOOL_OPTIONS
mkdir out
cat > Hello.java <<'JAVA'
public class Hello {
public static void main(String[] args) {
System.out.println("hello from Hello");
}
}
JAVA
javac -d out Hello.java
echo "--- -cp out"
java -cp out Hello
echo "--- default classpath (current directory), no Hello.class there"
java Hello 2>&1 || echo "exit code: $?"
echo "--- CLASSPATH variable"
CLASSPATH=out java Hello
echo "--- -cp out/* (wildcard matches only .jar files)"
java -cp 'out/*' Hello 2>&1 || echo "exit code: $?"Output
--- -cp out hello from Hello --- default classpath (current directory), no Hello.class there Error: Could not find or load main class Hello Caused by: java.lang.ClassNotFoundException: Hello exit code: 1 --- CLASSPATH variable hello from Hello --- -cp out/* (wildcard matches only .jar files) Error: Could not find or load main class Hello Caused by: java.lang.ClassNotFoundException: Hello exit code: 1
With -cp out and with CLASSPATH=out the class is found. With the default classpath the launcher searches only the current directory, where no Hello.class exists (the compiler put it in out/), so it stops with Could not find or load main class. The wildcard out/* fails for the same reason: out/ holds a .class file, not a JAR.
Common problems
Could not find or load main classorClassNotFoundException: the entry holding the class is missing from the classpath, or the class name does not match its package. See Could not find or load main class.cannot find symbolfromjavac: the compiler also uses the classpath to resolve the classes you import. Pass-cptojavacas well. See cannot find symbol.- The current directory disappeared: setting
-cpreplaces the default dot. Add.explicitly when you need it. - Two versions of one library: the first JAR on the list wins. Put the version you want first, or remove the other.
For several JARs at once, see classpath with multiple JARs.
FAQ
What is the default classpath in Java?
When neither -cp nor CLASSPATH is set, the classpath is the current directory, written as a dot. As soon as you pass -cp or set CLASSPATH, the dot is no longer included, so add it yourself (for example -cp lib/app.jar:.) if you still want classes from the current folder.
What separator does the classpath use?
A colon on Linux and macOS and a semicolon on Windows. A wildcard such as lib/* adds every JAR in that folder, but it does not search subfolders and it matches only .jar files, not loose .class files.
Is the classpath the same as the module path?
No. The classpath is the older mechanism that treats every JAR as part of one unnamed module. The module path, set with --module-path or -p, loads named modules with explicit dependencies. Both can be used in the same run.