When programming in Java, you make other classes available to the class you are writing by putting something like this at the top of your source file:

import org.javaguy.coolframework.MyClass;

Or sometimes you 'bulk import' stuff by saying:

import org.javaguy.coolframework.*;

So later in your program when you say:

MyClass mine = new MyClass();

The Java Virtual Machine will know where to find your compiled class.

It would be impractical to have the VM look through every folder on your machine, so you have to provide the VM a list of places to look. This is done by putting folder and jar files on your classpath.

Before we talk about how the classpath is set, let's talk about .class files, packages, and .jar files.

First, let's suppose that MyClass is something you built as part of your project, and it is in a directory in your project called output. The .class file would be at output/org/javaguy/coolframework/MyClass.class (along with every other file in that package). In order to get to that file, your path would simply need to contain the folder 'output', not the whole package structure, since your import statement provides all that information to the VM.

Now let's suppose that you bundle CoolFramework up into a .jar file, and put that CoolFramework.jar into a lib directory in your project. You would now need to put lib/CoolFramework.jar into your classpath. The VM will look inside the jar file for the org/javaguy/coolframework part, and find your class.

So, classpaths contain:

  • JAR files, and
  • Paths to the top of package hierarchies.

How do you set your classpath?

The first way everyone seems to learn is with environment variables. On a unix machine, you can say something like:

export CLASSPATH=/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/

On a Windows machine you have to go to your environment settings and either add or modify the value that is already there.

The second way is to use the -cp parameter when starting Java, like this:

java -cp "/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/"  MyMainClass

A variant of this is the third way which is often done with a .sh or .bat file that calculates the classpath and passes it to Java via the -cp parameter.

There is a "gotcha" with all of the above. On most systems (Linux, Mac OS, UNIX, etc) the colon character (:) is the classpath separator. On Windows the separator is the semicolon (;)

So what's the best way to do it?

Setting stuff globally via environment variables is bad, generally for the same kinds of reasons that global variables are bad. You change the CLASSPATH environment variable so one program works, and you end up breaking another program.

The -cp is the way to go. I generally make sure my CLASSPATH environment variable is an empty string where I develop, whenever possible, so that I avoid global classpath issues (some tools aren't happy when the global classpath is empty though - I know of two common, mega-thousand dollar licensed J2EE and Java servers that have this kind of issue with their command-line tools).

Answer from bokmann on Stack Overflow
🌐
Oracle
docs.oracle.com › javase › 8 › docs › technotes › tools › windows › classpath.html
2 Setting the Class Path
April 21, 2026 - The class path is the path that the Java Runtime Environment (JRE) searches for classes and other resource files. ... The class search path (class path) can be set using either the -classpath option when calling a JDK tool (the preferred method) or by setting the CLASSPATH environment variable.
🌐
GeeksforGeeks
geeksforgeeks.org › java › different-ways-to-set-a-classpath-in-java
Different Ways to Set a Classpath in Java - GeeksforGeeks
July 23, 2025 - Click "Advanced System Settings". Click "Environment Variables". In the "User Variable Section", click the "New" button. Enter Variable name :classpath [Don't give space between class path] Variable value:<directory_location>(for example in ...
🌐
Oracle
docs.oracle.com › javase › › 7 › docs › technotes › tools › windows › classpath.html
Setting the class path
The -classpath option is preferred because you can set it individually for each application without affecting other applications and without other applications modifying its value. C:> sdkTool -classpath classpath1;classpath2... ... A command-line tool, such as java, javac, javadoc, or apt.
Top answer
1 of 12
910

When programming in Java, you make other classes available to the class you are writing by putting something like this at the top of your source file:

import org.javaguy.coolframework.MyClass;

Or sometimes you 'bulk import' stuff by saying:

import org.javaguy.coolframework.*;

So later in your program when you say:

MyClass mine = new MyClass();

The Java Virtual Machine will know where to find your compiled class.

It would be impractical to have the VM look through every folder on your machine, so you have to provide the VM a list of places to look. This is done by putting folder and jar files on your classpath.

Before we talk about how the classpath is set, let's talk about .class files, packages, and .jar files.

First, let's suppose that MyClass is something you built as part of your project, and it is in a directory in your project called output. The .class file would be at output/org/javaguy/coolframework/MyClass.class (along with every other file in that package). In order to get to that file, your path would simply need to contain the folder 'output', not the whole package structure, since your import statement provides all that information to the VM.

Now let's suppose that you bundle CoolFramework up into a .jar file, and put that CoolFramework.jar into a lib directory in your project. You would now need to put lib/CoolFramework.jar into your classpath. The VM will look inside the jar file for the org/javaguy/coolframework part, and find your class.

So, classpaths contain:

  • JAR files, and
  • Paths to the top of package hierarchies.

How do you set your classpath?

The first way everyone seems to learn is with environment variables. On a unix machine, you can say something like:

export CLASSPATH=/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/

On a Windows machine you have to go to your environment settings and either add or modify the value that is already there.

The second way is to use the -cp parameter when starting Java, like this:

java -cp "/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/"  MyMainClass

A variant of this is the third way which is often done with a .sh or .bat file that calculates the classpath and passes it to Java via the -cp parameter.

There is a "gotcha" with all of the above. On most systems (Linux, Mac OS, UNIX, etc) the colon character (:) is the classpath separator. On Windows the separator is the semicolon (;)

So what's the best way to do it?

Setting stuff globally via environment variables is bad, generally for the same kinds of reasons that global variables are bad. You change the CLASSPATH environment variable so one program works, and you end up breaking another program.

The -cp is the way to go. I generally make sure my CLASSPATH environment variable is an empty string where I develop, whenever possible, so that I avoid global classpath issues (some tools aren't happy when the global classpath is empty though - I know of two common, mega-thousand dollar licensed J2EE and Java servers that have this kind of issue with their command-line tools).

2 of 12
127

Think of it as Java's answer to the PATH environment variable - OSes search for EXEs on the PATH, Java searches for classes and packages on the classpath.

🌐
Blogger
javarevisited.blogspot.com › 2011 › 01 › how-classpath-work-in-java.html
How to Set Classpath for Java on Windows and Linux? Steps and Example
Classpath can be specified using CLASSPATH environment variable which is case insensitive, -cp or -classpath command-line option or Class-Path attribute in manifest.mf file inside the JAR file in Java.
🌐
How to do in Java
howtodoinjava.com › home › java basics › java classpath
How to set CLASSPATH in Java - HowToDoInJava
February 23, 2023 - Learn how to set classpath in Java either as an environment variable and pass as the command-line argument.
🌐
Coderanch
coderanch.com › t › 377098 › java › Add-classpath-programmatically
Add classpath programmatically (Java in General forum at Coderanch)
I tried something like this: String jarFile = "c:\\tmp.jar"; Properties sysProp = System.getProperties(); sysProp.list(System.out); String sep = sysProp.getProperty("path.separator"); String javaClassPath = System.getProperty("java.class.path"); if (javaClassPath == null || javaClassPath.trim().length() == 0) { javaClassPath = jarFile; }else { System.out.println(javaClassPath); javaClassPath = javaClassPath + sep + jarFile; } System.setProperty("java.class.path", javaClassPath); sysProp = System.getProperties(); System.out.println(sysProp.getProperty("java.class.path")); ... If you want to dynamically load classes you should write your own classloader. You will not be able to change the classpath.
🌐
UCSB
sites.cs.ucsb.edu › ~cappello › 50-2005-Winter › lectures › classpath.html
Setting the class path
If the path to that directory is /java/MyClasses/utility/myapp, you set the class path so that it contains /java/MyClasses. To run that app, you could use the following JVM command: % java -classpath /java/MyClasses utility.myapp.Cool
Find elsewhere
🌐
Javatpoint
javatpoint.com › how-to-set-classpath-in-java
How to Set CLASSPATH in Java - Javatpoint
August 6, 2014 - CLASSPATH is an environment variable which is used by Application ClassLoader to locate and load the .class files. The CLASSPATH defines the path, to find third-party and user-defined classes that are not extensions or part of Java platform. Include all the directories which contain .class files and JAR files when setting the CLASSPATH.
🌐
Stack Overflow
stackoverflow.com › questions › 22174028 › set-classpath-file-programmatically-java
eclipse plugin - Set classpath file programmatically Java - Stack Overflow
March 4, 2014 - <classpathentry kind="lib" path="C:/ProgramsFiles/foo.jar"> <attributes> <attribute name="javadoc_location" value="file:C:\ProgramsFiles\Javadoc\"/> </attributes> </classpathentry>
🌐
Princeton CS
introcs.cs.princeton.edu › java › 15inout › classpath.html
Setting the Classpath in Java
Go to that directory and compile them. ... From DrJava, choose the menu option Edit -> Preferences -> Resource Locations -> Extra Classpath -> Add and select C:\introcs. Click the Apply button, then the OK button. To set the classpath for the Windows XP Command Prompt:
🌐
HowToDoInJava
howtodoinjava.com › home › java examples › java – set classpath from command line
Java - Set Classpath from Command Line
January 25, 2022 - Learn to use the -classpath or -cp option in command prompt to set classpath from command prompt in Windows and Linux OS.
Top answer
1 of 6
86

Update 2023: as commented below by Holger

The only way to add jar files to the class path working in Java 9 and newer, is through the Instrumentation API, but it requires a Java Agent.

If you are in control of the launcher/main jar, you can use the Launcher-Agent-Class attribute in the jar file’s manifest to start an embedded Agent.


Update Q4 2017: as commented below by vda8888, in Java 9, the System java.lang.ClassLoader is no longer a java.net.URLClassLoader.

See "Java 9 Migration Guide: The Seven Most Common Challenges"

The class loading strategy that I just described is implemented in a new type and in Java 9 the application class loader is of that type.
That means it is not a URLClassLoader anymore, so the occasional (URLClassLoader) getClass().getClassLoader() or (URLClassLoader) ClassLoader.getSystemClassLoader() sequences will no longer execute.

java.lang.ModuleLayer would be an alternative approach used in order to influence the modulepath (instead of the classpath). See for instance "Java 9 modules - JPMS basics".


For Java 8 or below:

Some general comments:

you cannot (in a portable way that's guaranteed to work, see below) change the system classpath. Instead, you need to define a new ClassLoader.

ClassLoaders work in a hierarchical manner... so any class that makes a static reference to class X needs to be loaded in the same ClassLoader as X, or in a child ClassLoader. You can NOT use any custom ClassLoader to make code loaded by the system ClassLoader link properly, if it wouldn't have done so before. So you need to arrange for your main application code to be run in the custom ClassLoader in addition to the extra code that you locate.
(That being said, cracked-all mentions in the comments this example of extending the URLClassLoader)

And you might consider not writing your own ClassLoader, but just use URLClassLoader instead. Create a URLClassLoader with a url that are not in the parent classloaders url's.

URL[] url={new URL("file://foo")};
URLClassLoader loader = new URLClassLoader(url);

A more complete solution would be:

ClassLoader currentThreadClassLoader
 = Thread.currentThread().getContextClassLoader();

// Add the conf dir to the classpath
// Chain the current thread classloader
URLClassLoader urlClassLoader
 = new URLClassLoader(new URL[]{new File("mtFile").toURL()},
                      currentThreadClassLoader);

// Replace the thread classloader - assumes
// you have permissions to do so
Thread.currentThread().setContextClassLoader(urlClassLoader);

If you assume the JVMs system classloader is a URLClassLoader (which may not be true for all JVMs), you can use reflection as well to actually modify the system classpath... (but that's a hack;)):

public void addURL(URL url) throws Exception {
  URLClassLoader classLoader
         = (URLClassLoader) ClassLoader.getSystemClassLoader();
  Class clazz= URLClassLoader.class;

  // Use reflection
  Method method= clazz.getDeclaredMethod("addURL", new Class[] { URL.class });
  method.setAccessible(true);
  method.invoke(classLoader, new Object[] { url });
}

addURL(new File("conf").toURL());

// This should work now!
Thread.currentThread().getContextClassLoader().getResourceAsStream("context.xml");
2 of 6
3

I don't believe you can - the right thing to do (I believe) is create a new classloader with the new path. Alternatively, you could write your own classloader which allows you to change the classpath (for that loader) dynamically.

Top answer
1 of 2
1

A complete (coded) solution would be a bit beyond a single Stack Overflow answer, so I'll outline the points you need to be aware of instead if you decide to write your own ClassLoader:

  1. The classloader represents (part of) a namespace, and two otherwise identical classes loaded by different classloaders are not "equal". Which means there are a few dangers lurking in classloading, notably singletons suddenly not being so single anymore as well as casts failing unexpectedly.
  2. Classloaders (should) work on a pattern of delegating to the "parent" loader before attempting anything themselves (see above).
  3. Class loading and linking are two distinct steps (even though example implementations of a classloader such as may be found in blog posts/online Java articles, will combine the two into one for simplicity) Therefore you should not assume that if a parent loader has loaded a class it has also loaded all dependencies ...
  4. All this means there is a problem if class A loaded by loader A references a class B which neither loader A nor any of its parents can load: class A may load just fine in loader A but at the point of use it fails because loader A cannot fully resolve (link) it.
  5. And you should make sure that your classloader loads classes in a synchronized manner otherwise the issues hinted at in step #1 can leap from duplicates due to classloaders to duplicates from multiple threads using the same classloader as well...

Note: it is far easier to just use the -cp switch in some wrapper script/batch file for your program.

2 of 2
0

From the ClassLoader#getSystemClassLoader() doc:

This method is first invoked early in the runtime's startup sequence, at which point it creates the system class loader and sets it as the context class loader of the invoking Thread.

When you do Thread.currentThread().setContextClassLoader(urlClassLoader), you're changing the reference in the current thread, not the one in ClassLoader (and you can't change this one), so from then on you should rely on the new class loader of the current thread to load your classes with something like:

Thread.currentThread().getContextClassLoader().loadClass(...) 
🌐
GeeksforGeeks
geeksforgeeks.org › java › how-to-set-classpath-in-java
How to Set Classpath in Java? - GeeksforGeeks
July 23, 2025 - Find out where you have installed Java, basically, it's in /usr/lib/jvm path. Set the CLASSPATH in /etc/environment using
🌐
Blogger
javahowto.blogspot.com › 2006 › 06 › 6-ways-of-setting-java-classpath.html
Java How To ...: 6 Ways of Setting Java Classpath
Java howto JBoss WildFly Git IntelliJ GlassFish EJB Servlet JEE JavaEE JNDI IDE JDK JPA MySQL NetBeans Tomcat WebLogic Eclipse Concurrency Mac Linux
🌐
Michigan State University
web.pa.msu.edu › reference › jdk-1.2.2-docs › tooldocs › solaris › classpath-linux.html
Setting the class path
The class path can be set using either the -classpath option when calling a JDK tool (the preferred method) or by setting the CLASSPATH environment variable. The -classpath option is preferred because you can set it individually for each application without affecting other applications and ...
🌐
GitHub
gist.github.com › 0338424508496b6e171e
add new class path at runtime in java · GitHub
public static void addPath(String s) throws Exception { File f = new File(s); URL u = f.toURL(); URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); Class urlClass = URLClassLoader.class; Method method = urlClass.getDeclaredMethod("addURL", new Class[]{URL.class}); method.setAccessible(true); method.invoke(urlClassLoader, new Object[]{u}); } ... class jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to class java.net.URLClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader and java.net.URLClassLoader are in module java.base of loader 'bootstrap')
🌐
Dkessner
dkessner.github.io › ProcessingLibraryExamples › classpath.html
Setting the Java CLASSPATH | ProcessingLibraryExamples
You want to edit the Environment Variables in the Control Panel. You can create a new variable named CLASSPATH with a value of something like: .;%UserProfile%\Desktop\processing_????\core\library · Note: %UserProfile% is an environment variable set to your home directory (C:\Users\YourName).