I am writing an ant file that will compile and run my java files. The ant creates the AntLabRun.jar file. When I try to run the jar file, I get the Exception in thread "main" java.lang.NoClassDefFoundError.
Here is rough look of the directory
-lib/resources.jar
-src/**/pkg1/AntLabMain.java
AntLabMain imports a package found inside resources.jar
<target name="init">
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="apidoc" location="apidoc"/>
<property name="lib" location="lib"/>
<path id="path.base">
<pathelement path="${build}" />
<fileset dir="lib">
<include name="*.jar" />
</fileset>
</path>
<manifestclasspath property="manifest.classpath" jarfile="resources.jar">
<classpath location="${lib}"/>
</manifestclasspath>
</ta开发者_高级运维rget>
<!-- I excluded the unnecessary targets -->
target name="jar" depends="compile">
<jar destfile="AntLabRun.jar" basedir="${build}">
<include name="edu/**/*.class"/>
<manifest>
<attribute name="Main-Class" value="edu.gatech.oad.antlab.pkg1.AntLabMain"/>
<attribute name="Class-Path" value="${manifest.classpath}"/>
</manifest>
</jar>
</target>
<target name="run" depends="jar">
<java jar="AntLabRun.jar" fork="true">
</java>
</target>
I have looked through all of the questions dealing with this and didn't file a solution yet.
You can make use of the pathelement
element. Example:
<!-- Define the CLASSPATH -->
<path id="compile.classpath">
<pathelement location="lib/resources.jar" />
</path>
Then reference the id
when using the javac
element. Example:
<javac srcdir="${src.home}" destdir="${work.home}/bin" debug="on">
<classpath refid="compile.classpath" />
</javac>
It is better to put each of the above under their own targets
, (for me anyway).
You can also use multiple pathelement
elements under the path
element for more than one jar references.
If you want your jar file to reference another jar file, you can put the references in the MANIFEST.MF, below is an example creating a manifest using ant.
<target name="create_manifest">
<manifest file="${work.home}/META-INF/MANIFEST.MF">
<attribute name="Manifest-Version" value="1.0" />
<attribute name="Version" value="${app.version}" />
<attribute name="Company" value="Comp Name here" />
<attribute name="Project" value="${app.name}" />
<attribute name="Java-Version" value="${java.version}" />
<!--Here is the reference to jar files this jar manifest will reference.-->
<attribute name="Class-Path" value="one.jar two.jar three.jar etc.jar" />
</manifest>
</target>
To follow is Example target
s to copy and include the class files and point to the correct manifest when creating the jar
.
<target name="create_jar" depends="create_manifest, copy_all_class_files">
<jar destfile="${guiJar}" manifest="jar_temp/META-INF/MANIFEST.MF" basedir="jar_temp">
</jar>
</target>
<target name="copy_all_class_files">
<copy todir="jar_temp">
<fileset dir="classes">
<include name="*/**" />
</fileset>
</copy>
</target>
You will note that the depends
tag has the create_manifest
and copy_all_class_files
as dependency.
As you know, the dependency targets will run first for a target
, that way you can ensure your order is correct.
I think part of your problem is your ant file complexity.
Try breaking each of your tasks into separate targets and solving the problem for each target before moving on to the next.
That way you can ensure that whatever prior stuff you have is working as expected and won't have to worry about previous tasks not working as expected.
精彩评论