Java class loading
The JVM (Java Virtual Machine) will load classes as and when the classes are required (this is called lazy-loading). Locations of the classes to be used are specified in three places:-
Classes are loaded using classes that are subtypes of
java.lang.ClassLoader. This described in a more detail in this Topic: Classloaders.
The classpath is a parameter used by the JVM or compiler which specifies the locations of user-defined classes and packages.
This can be set in the command line as with most of these examples or through an environmental variable (
There are three ways to set the classpath.
It can be set using the
CLASSPATH environment variable :
set CLASSPATH=... # Windows and csh export CLASSPATH=... # Unix ksh/bash
It can be set on the command line as follows
java -classpath ... javac -classpath ...
Note that the
-cp) option takes precedence over the
CLASSPATH environment variable.
The classpath for an executable JAR file is specified using the
Class-Path element in
Class-Path: jar1-name jar2-name directory-name/jar3-name
Note that this only applies when the JAR file is executed like this:
java -jar some.jar ...
In this mode of execution, the
-classpath option and the CLASSPATH environment variable will be ignored, even if the JAR file has no
If no classpath is specified, then the default classpath is the selected JAR file when using
java -jar, or the current directory otherwise.
If you want to add all the JARs in directory to the classpath, you can do this concisely using classpath wildcard syntax; for example:
This tells the JVM to add all JAR and ZIP files in the
someFolder directory to the classpath. This syntax can be used in a
-cp argument, a
CLASSPATH environment variable, or a
Class-Path attribute in an executable JAR file's manifest file.See Setting the Class Path: Class Path Wild Cards for examples and caveats.
The classpath is a sequence of entries which are directory pathnames, JAR or ZIP file pathnames, or JAR / ZIP wildcard specifications.
For a classpath specified on the command line (e.g.
-classpath) or as an environment variable, the entries must be separated with
; (semicolon) characters on Windows, or
: (colon) characters on other platforms (Linux, UNIX, MacOSX and so on).
Class-Path element in a JAR file's
MANIFEST.MF, use a single space to separate the entries.
Sometimes it is necessary to embed a space in a classpath entry
When the classpath is specified on the command line, it is simply a matter of using the appropriate shell quoting. For example:
export CLASSPATH="/home/user/My JAR Files/foo.jar:second.jar"
(The details may depend on the command shell that you use.)
When the classpath is specified in a JAR file's a "MANIFEST.MF" file, URL encoding must be used.
Class-Path: /home/user/My%20JAR%20Files/foo.jar second.jar
Sometimes, just adding all the JARs from a folder isn't enough, for example when you have native code and need to select a subset of JARs. In this case, you need two
main() methods. The first one builds a classloader and then uses this classloader to call the second
Here is an example which selects the correct SWT native JAR for your platform, adds all your application's JARs and then invokes the real
main() method: Create cross platform Java SWT Application
It can be useful to load a resource (image, text file, properties, KeyStore, ...) that is packaged inside a JAR. For this purpose, we can use the
Suppose we have the following project structure :
program.jar | \-com \-project | |-file.txt \-Test.class
And we want to access the contents of
file.txt from the
Test class. We can do so by asking the classloader :
InputStream is = Test.class.getClassLoader().getResourceAsStream("com/project/file.txt");
By using the classloader, we need to specify the fully qualified path of our resource (each package).
Or alternatively, we can ask the Test class object directly
InputStream is = Test.class.getResourceAsStream("file.txt");
Using the class object, the path is relative to the class itself. Our
Test.class being in the
com.project package, the same as
file.txt, we do not need to specify any path at all.
We can, however, use absolute paths from the class object, like so :
is = Test.class.getResourceAsStream("/com/project/file.txt");
The standard Java toolchain (and 3rd-party tools designed to interoperate with them) have specific rules for mapping the names of classes to the pathnames of files and other resources that represent them.
The mappings are as follows
This is illustrated in the following table:
|Classname||Source pathname||Classfile pathname|
The purpose of the classpath is to tell a JVM where to find classes and other resources. The meaning of the classpath and the search process are intertwined.
The classpath is a form of search path which specifies a sequence of locations to look for resources. In a standard classpath, these places are either, a directory in the host file system, a JAR file or a ZIP file. In each cases, the location is the root of a namespace that will be searched.
The standard procedure for searching for a class on the classpath is as follows:
Map the class name to a relative classfile pathname
RP. The mapping for class names to class filenames is described elsewhere.
For each entry
E in the classpath:
Eto give an absolute pathname
APis a path for an existing file.
RPin the JAR / ZIP file index.
The procedure for searching for a resource on the classpath depends on whether the resource path is absolute or relative. For an absolute resource path, the procedure is as above. For a relative resource path resolved using
Class.getResourceAsStream, the path for the classes package is prepended prior to searching.
(Note these are the procedures implemented by the standard Java classloaders. A custom classloader might perform the search differently.)
The normal Java classloaders look for classes first in the bootstrap classpath, before checking for extensions and the application classpath. By default, the bootstrap classpath consists of the "rt.jar" file and some other important JAR files that are supplied by the JRE installation. These provide all of the classes in the standard Java SE class library, along with various "internal" implementation classes.
Under normal circumstances, you don't need to concern yourself with this. By default, commands like
javac and so on will use the appropriate versions of the runtime libraries.
Very occasionally, it is necessary to override the normal behavior of the Java runtime by using an alternative version of a class in the standard libraries. For example, you might encounter a "show stopper" bug in the runtime libraries that you cannot work around by normal means. In such a situation, it is possible to create a JAR file containing the altered class and then add it to the bootstrap classpath which launching the JVM.
java command provides the following
-X options for modifying the bootstrap classpath:
-Xbootclasspath:<path>replaces the current boot classpath with the path provided.
-Xbootclasspath/a:<path>appends the provided path to the current boot classpath.
-Xbootclasspath/p:<path>prepends the provided path to the current boot classpath.
Note that when use the bootclasspath options to replace or override a Java class (etcetera), you are technically modifying Java. There may be licensing implications if you then distribute your code. (Refer to the terms and conditions of the Java Binary License ... and consult a lawyer.)