Friday, June 1, 2012

Setting multiple jars in java classpath


Is there a way to include all the jar files within a directory in the classpath?



I'm trying java -classpath lib/*.jar:. my.package.Program and it is not able to find class files that are certainly in those jars. Do I need to add each jar file to the classpath separately?


Source: Tips4all

9 comments:

  1. If using Java 6, or more recent (which you should be), classpath wildcards were added to the JVM, but the syntax must be precisely correct. Read the Classpath document section entitled, Understanding class path wildcards.

    If you cannot use wildcards, bash allows the following syntax (where lib is the directory containing all the Java archive files):

    java -cp $(echo lib/*.jar | tr ' ' ':')

    ReplyDelete
  2. 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.

    ReplyDelete
  3. 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 -classpath 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.0
    Implementation-Title: myapp
    Implementation-Version: 1.0.1
    Class-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.

    ReplyDelete
  4. My solution on Ubuntu 10.04 using java-sun 1.6.0_24 having all jars in "lib" directory:

    java -cp .:lib/* my.main.Class

    If this fails, the following command should work (prints out all *.jars in lib directory to the classpath param)

    java -cp $(for i in lib/*.jar ; do echo -n $i: ; done). my.main.Class

    ReplyDelete
  5. If you really need to specify all the .jar files dynamically you could use shell scripts, or Apache Ant. There's a commons project called Commons Launcher which basically lets you specify your startup script as an ant build file (if you see what I mean).

    Then, you can specify something like:

    <path id="base.class.path">
    <pathelement path="${resources.dir}"/>
    <fileset dir="${extensions.dir}" includes="*.jar" />
    <fileset dir="${lib.dir}" includes="*.jar"/>
    </path>


    In your launch build file, which will launch your application with the correct classpath.

    ReplyDelete
  6. Short answer: java -classpath lib/*:. my.package.Program

    Oracle provides documentation on using wildcards in classpaths here for Java 6 and here for Java 7, under the section heading Understanding class path wildcards. (As I write this, the two pages contain the same information.) Here's a summary of the highlights:


    In general, to include all of the JARs in a given directory, you can use the wildcard * (not *.jar).
    The wildcard only matches JARs, not class files; to get all classes in a directory, just end the classpath entry at the directory name.
    The above two options can be combined to include all JAR and class files in a directory, and the usual classpath precedence rules apply. E.g. -cp /classes;/jars/*
    The wildcard will not search for JARs in subdirectories.
    The above bullet points are true if you use the CLASSPATH system property or the -cp or -classpath command line flags. However, if you use the Class-Path JAR manifest header (as you might do with an ant build file), wildcards will not be honored.


    Yes, my first link is the same one provided in the top-scoring answer (which I have no hope of overtaking), but that answer doesn't provide much explanation beyond the link. Since that sort of behavior is discouraged on Stack Overflow these days, I thought I'd expand on it.

    ReplyDelete
  7. If you are using Java 6, then you can use wildcards in the classpath.

    Now it is possible to use wildcards in classpath definition:
    javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java -d build/classes

    Ref: http://www.rekk.de/bloggy/2008/add-all-jars-in-a-directory-to-classpath-with-java-se-6-using-wildcards/

    ReplyDelete
  8. You can try java -Djava.ext.dirs=jarDirectory
    http://java.sun.com/j2se/1.4.2/docs/guide/extensions/spec.html

    Directory for external jars when running java

    ReplyDelete
  9. Correct:

    java -classpath "lib/*:." my.package.Program


    Incorrect:

    java -classpath "lib/a*.jar:." my.package.Program
    java -classpath "lib/a*:." my.package.Program
    java -classpath "lib/*.jar:." my.package.Program
    java -classpath lib/*:. my.package.Program

    ReplyDelete