Greetings,
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:
====================================================
ant_test
'- build
'- lib
'- log4j.jar
'- build.xml
'- dist
'- src
'- HelloWorld.java
====================================================
====================================================
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 -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init">
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<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}">
<manifest>
<attribute name="Class-Path" value=". ./lib/log4j.jar"/>
<attribute name="Main-Class" value="HelloWorld"/>
</manifest>
</jar>
</target>
<target name="clean">
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>
====================================================
====================================================
HelloWorld.java:
====================================================
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[] )
{
BasicConfigurator.configure();
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:
org/apache/log4j/Category
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 http://jakarta.apache.org/log4j/, 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.
Regards,
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: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>