Real'sHowTo AddThis Feed Button
Custom Search

Include all jars in the classpath definitionTag(s): Environment


Specifying all the required jar in the classpath can be a pain. Here some techniques to set the classpath definition automatically.

Windows batch file

For Windows 2000 (or better), we need a set of 3 CMD files to scan a given directory and build the classpath defintion with all the jars found.

main.cmd
@echo off
call buildclasspath.cmd .\lib
Echo The Classpath definition is %CLASSPATH%
...
java MyClass
buildclasspath.cmd
set _CLASSPATH=%CLASSPATH%
 
set CLASSPATH=%1
for %%i in ( %1\*.jar ) do call buildclasspath_append.cmd %%~fsi
 
if "%_CLASSPATH%" == "" goto END
set CLASSPATH=%_CLASSPATH%;%CLASSPATH%
 
:END
buildclasspath_append.cmd
set CLASSPATH=%CLASSPATH%;%1

With XP (or better), it's simpler ... a single batch file can do the job.

@echo off
setlocal ENABLEDELAYEDEXPANSION
if defined CLASSPATH (set CLASSPATH=%CLASSPATH%;.) else (set CLASSPATH=.)
FOR /R .\lib %%G IN (*.jar) DO set CLASSPATH=!CLASSPATH!;%%G
Echo The Classpath definition is %CLASSPATH%
...
java MyClass

JDK6

According to http://java.sun.com/javase/6/docs/technotes/tools/windows/java.html, there is a new way to include jars in a given directory without explicitly to specify each one of them.
As a special convenience, a class path element containing a 
basename of * is considered equivalent to specifying a list 
of all the files in the directory with the extension .jar 
or .JAR (a java program cannot tell the difference between
the two invocations).

For example, if directory foo contains a.jar and b.JAR, then 
the class path element foo/* is expanded to a A.jar:b.JAR, 
except that the order of jar files is unspecified. All jar files 
in the specified directory, even hidden ones, are included in 
the list. A classpath entry consisting simply of * expands to a 
list of all the jar files in the current directory. The CLASSPATH 
environment variable, where defined, will be similarly expanded.

Note : There is a bug when using this feature with JAVAW, see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6510337

Note : Use quote to avoid problem during the wildcard expansion, ex. javac -cp "C:\mylib\*" HelloWorld.java

JAR (and ANT)

The best solution when you have a jar is to try to include the required jars into the manifest declaration.
Manifest-Version: 1.0 
Class-Path:  
 customer_client.jar  
 mailer_client.jar  
 signon_client.jar 
 
The manifest file format restrictions mandated by the JDK requires the use of a space ' ' character as the line continuation character, so ensure that your editor is not set up to trim trailing spaces on saves and exits.

The line with the Class-Path: header must end with a space character and each of the lines referencing the client jar's should start and end with a space ' ' character and the manifest file as a whole must end with a blank line.


Remember that when you launch an application with

java -jar myjar.jar
the CLASSPATH definition (as defined by the environment variable) is overriden by the "class-path" defined the jar's manifest.

See http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html

Ant can be used to build your Jar and built the manifest class-path definition.

<target name="MyJar" depends="dist, compile" description="generate jar" >
     <jar destfile="${dist}/${jar}">
          <manifest>
            <attribute name="Main-Class" value="${Main_Class}"/>
            <attribute name="Class-Path" value=". lib/utils.jar  lib/client.jar" />
        </manifest>      
    </jar>
</target>

It's possible (but not so simple) to do it automatically without specifying each jar one by one :

<path id="build.classpath">
  <fileset dir="${basedir}"/>
     <include name="lib/*.jar"/>
  </fileset>
</path>

<pathconvert property="manifest.classpath" pathsep=" ">
  <path refid="build.classpath"/>
  <mapper>
    <chainedmapper>
       <flattenmapper/>
       <globmapper from="*.jar" to="lib/*.jar"/>
    </chainedmapper>
  </mapper>
</pathconvert>

<target depends="compile" name="buildjar">
  <jar jarfile="${basedir}/${test.jar}">
     <fileset dir="${build}" />
     <manifest>
       <attribute name="Main-Class" value="com.mycompany.TestMain"/>
       <attribute name="Class-Path" value="${manifest.classpath}"/>
     </manifest>
 </jar>
</target>

Latest Ant version (1.7) includes a task called ManifestClassPath which converts a classpath into a space-separated list of items used to set the Manifest Class-Path attribute. See http://ant.apache.org/manual/CoreTasks/manifestclasspath.html


<path id="build-classpath">
   <fileset dir="${build.dir}">
      <include name="*.jar"/>
   </fileset>
</path>

<manifestclasspath property="lib.list" jarfile="${build.dir}/${jar.file}">
   <classpath refid="build-classpath" />
</manifestclasspath>

<jar>
  ...
   <manifest>
      <attribute name="Main-Class" value="com.mycompany.TestMain"/>
      <attribute name="Class-Path" value=". ${lib.list}"/>
   </manifest>
 ...
</jar>

blog comments powered by Disqus


If you find this article useful, consider making a small donation
to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998-2014
[ home ]