ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Todd Wilson <>
Subject Using Main-Class and Class-Path in a manifest file
Date Tue, 12 Mar 2002 21:20:16 GMT

We're attempting to use Ant in generating a JAR file that creates a 
manifest file which uses both the Class-Path and Main-Class properties, 
but can't seem to be able to get it to work.

Here is some information that would be useful to any wanting to respond--

Our directory structure:
'- build
   '- lib
     '- log4j.jar
'- build.xml
'- dist
'- src

Our build.xml file:
<project name="HelloWorld" default="dist" basedir=".">

   <target name="init">
     <!-- set global properties for this build -->
     <property name="src" value="src"/>
     <property name="build" value="build"/>
     <property name="dist"  value="dist"/>

     <!-- Create the time stamp -->
     <!-- Create the build directory structure used by compile -->
     <mkdir dir="${build}"/>

   <target name="compile" depends="init">
     <!-- Compile the java code from ${src} into ${build} -->
     <javac srcdir="${src}" destdir="${build}"/>

   <target name="dist" depends="compile">
     <!-- Create the distribution directory -->
     <mkdir dir="${dist}"/>

     <!-- Put everything in ${build} into the HelloWorld.jar file -->
     <jar jarfile="${dist}/HelloWorld.jar" basedir="${build}">
         <attribute name="Class-Path" value=". ./lib/log4j.jar"/>
         <attribute name="Main-Class" value="HelloWorld"/>

   <target name="clean">
     <!-- Delete the ${build} and ${dist} directory trees -->
     <delete dir="${build}"/>
     <delete dir="${dist}"/>

import org.apache.log4j.*;

public class HelloWorld
   public static Category log = Category.getInstance( 
HelloWorld.class.getName() );

   public HelloWorld()
     System.out.println( "Hello world!" );

     log.debug( "Log4J is working." );

   public static void main( String args[] )

     HelloWorld hw = new HelloWorld();

When we run ant in the "ant_test" directory it produces the 
HelloWorld.jar file in the "dist" directory as it's supposed to, but 
running the jar with

java -jar HellowWorld.jar

produces the following error message:

Exception in thread "main" java.lang.NoClassDefFoundError: 
         at HelloWorld.<clinit>(Unknown Source)

So it's apparently finding our "Main-Class" just fine, but seems to be 
ignoring the "Class-Path" property.

If we unjar the HelloWorld.jar file it reveals that the following 
manifest file was generated by Ant:

Manifest-Version: 1.0
Main-Class: HelloWorld
Created-By: Ant 1.4.1
Class-Path: . ./lib/log4j.jar

In an attempt to diagnose the problem, we then copy the contents of the 
build directory (which contains the HelloWorld.class file generated when 
Ant ran as well as the lib directory containing log4j.jar) into a 
separate tmp directory.  We then attempt to jar up the contents of tmp 
using the manifest file created by Ant, with the following command:

jar -cfm HelloWorld.jar ../dist/META-INF/MANIFEST.MF ./*

Again, notice that we're designating the manifest file that was 
generated by Ant as the manifest file that should be used for the newly 
created HelloWorld.jar file.  After running this jar command we attempt 
to run the second HelloWorld.jar file with

java -jar HelloWorld.jar

and it runs just fine.  If we unjar this second HelloWorld.jar file we 
find that the contents of it are identical to that of the first 
HelloWorld.jar file (as near as we can tell) aside from the manifest 
file which now looks like this:

Manifest-Version: 1.0
Created-By: Ant 1.4.1
Class-Path: . ./lib/log4j.jar
Main-Class: HelloWorld

Running diff on the two files reveals that, aside from white space, the 
only difference between the two is that the "Main-Class" line in the 
first manifest file is on the second line where the "Main-Class" line in 
the second manifest file is on the last line.  It seems odd that the 
order in which the properties appear in the manifest file would make any 
difference, but, as I mentioned, that's the only discrepancy we could 
find between the two jars.

It's as though the java runtime parses through the manifest file and, 
upon reaching the "Main-Class" line, immediately invokes the class 
designated rather than parsing the rest of the file in order to set the 
classpath first.  If this is the case, is there any way to make Ant put 
the "Main-Class" property at the end of the manifest file?  Rearranging 
the XML tags doesn't seem to have any affect on this.

We've also tried creating a manifest file before running Ant that 
positions the "Main-Class" property at the end, then using the 
"manifest" attribute of the "jar" tag, but when Ant runs it moves the 
"Main-Class" property up to the second position, as before.

We've tried this process on Linux running JDK 1.4 as well as Win2K 
running JDK 1.3.1_01, and have gotten the same results.  The log4j.jar 
file can be obtained from, but I'm sure 
you all already knew that :)

Sorry this message is so long-winded, but I figure it's better to be 
verbose in situations like this rather than terse.  Many thanks in 
advance to anyone willing to lend a hand.


Todd Wilson

P.S.  Lest we be accused otherwise, we've already spent a fair amount of 
time searching the archives of the list for a solution to this problem, 
but, unfortunately, haven't been successful.

To unsubscribe, e-mail:   <>
For additional commands, e-mail: <>

View raw message