Including all the jars in a directory within the Java classpath Including all the jars in a directory within the Java classpath java java

Including all the jars in a directory within the Java classpath


Using Java 6 or later, the classpath option supports wildcards. Note the following:

  • Use straight quotes (")
  • Use *, not *.jar

Windows

java -cp "Test.jar;lib/*" my.package.MainClass

Unix

java -cp "Test.jar:lib/*" my.package.MainClass

This is similar to Windows, but uses : instead of ;. If you cannot use wildcards, bash allows the following syntax (where lib is the directory containing all the Java archive files):

java -cp "$(printf %s: lib/*.jar)"

(Note that using a classpath is incompatible with the -jar option. See also: Execute jar file with multiple classpath libraries from command prompt)

Understanding Wildcards

From the Classpath document:

Class path entries can contain the basename wildcard character *, which is considered equivalent to specifying a list of all the filesin the directory with the extension .jar or .JAR. For example, theclass path entry foo/* specifies all JAR files in the directory namedfoo. A classpath entry consisting simply of * expands to a list of allthe jar files in the current directory.

A class path entry that contains * will not match class files. Tomatch both classes and JAR files in a single directory foo, use eitherfoo;foo/* or foo/*;foo. The order chosen determines whether theclasses and resources in foo are loaded before JAR files in foo, orvice versa.

Subdirectories are not searched recursively. For example, foo/* looksfor JAR files only in foo, not in foo/bar, foo/baz, etc.

The order in which the JAR files in a directory are enumerated in theexpanded class path is not specified and may vary from platform toplatform and even from moment to moment on the same machine. Awell-constructed application should not depend upon any particularorder. If a specific order is required then the JAR files can beenumerated explicitly in the class path.

Expansion of wildcards is done early, prior to the invocation of aprogram's main method, rather than late, during the class-loadingprocess itself. Each element of the input class path containing awildcard is replaced by the (possibly empty) sequence of elementsgenerated by enumerating the JAR files in the named directory. Forexample, if the directory foo contains a.jar, b.jar, and c.jar, thenthe class path foo/* is expanded into foo/a.jar;foo/b.jar;foo/c.jar,and that string would be the value of the system propertyjava.class.path.

The CLASSPATH environment variable is not treated any differently fromthe -classpath (or -cp) command-line option. That is, wildcards arehonored in all these cases. However, class path wildcards are nothonored in the Class-Path jar-manifest header.

Note: due to a known bug in java 8, the windows examples must use a backslash preceding entries with a trailing asterisk: https://bugs.openjdk.java.net/browse/JDK-8131329


Under Windows this works:

java -cp "Test.jar;lib/*" my.package.MainClass

and this does not work:

java -cp "Test.jar;lib/*.jar" my.package.MainClass

Notice the *.jar, so the * wildcard should be used alone.


On Linux, the following works:

java -cp "Test.jar:lib/*" my.package.MainClass

The separators are colons instead of semicolons.


We get around this problem by deploying a main jar file myapp.jar which contains a manifest (Manifest.mf) file specifying a classpath with the other required jars, which are then deployed alongside it. In this case, you only need to declare java -jar myapp.jar when running the code.

So if you deploy the main jar into some directory, and then put the dependent jars into a lib folder beneath that, the manifest looks like:

Manifest-Version: 1.0Implementation-Title: myappImplementation-Version: 1.0.1Class-Path: lib/dep1.jar lib/dep2.jar

NB: this is platform-independent - we can use the same jars to launch on a UNIX server or on a Windows PC.