简体   繁体   中英

java build ant file with external jar files

I created an ant build file to compile my java src into a .jar file. It uses external jar files.

My files dir:

+src
----android
------------Address.java
------------HelloServer.java
------------HelloServerResource.java
+lib
------------org.codehaus.jackson.core.jar
------------org.codehaus.jackson.mapper.jar
------------org.json.jar
------------org.restlet.ext.jackson.jar
------------org.restlet.jar
build.xml

The external libraries are in lib folder. The main class is in HelloServer.java

Here is my ant build file:

<project name="helloworld">
    <property name="src-dir" location="src"/>
    <property name="build-dir" location="build"/>
    <property name="classes-dir" value="${build-dir}/classes"/>
    <property name="dist-dir" location="dist"/>
    <property name="lib-dir" value="lib"/>
    <property name="jar-dir"     value="${build-dir}/jar"/>
    <property name="main-class"  value="android.HelloServer"/>

    <path id="classpath">
        <fileset dir="${lib-dir}" includes="**/*.jar"/>
    </path>

    <target name="clean" description="compile the source">
        <delete dir="${build-dir}" />
        <delete dir="${dist-dir}" />
    </target>

    <target name="cleanall" depends="clean"/>

    <target name="init">
        <!-- Create the build directory structure used by compile -->
        <mkdir dir="${build-dir}"/>
        <mkdir dir="${classes-dir}"/>
        <mkdir dir="${jar-dir}"/>
        <!--<mkdir dir="${dist-dir}"/>-->
    </target>

    <target name="compile" depends="init" description="compile the source " >
        <javac srcdir="${src-dir}" destdir="${classes-dir}" classpathref="classpath" includeantruntime="false" />
        <!--<javac srcdir="${src-dir}" destdir="${build-dir}"/>-->
    </target>

    <target name="jar" depends="compile">
        <jar destfile="${jar-dir}/${ant.project.name}.jar" basedir="${classes-dir}">
            <manifest>
                <attribute name="Main-Class" value="${main-class}"/>
            </manifest>
        </jar>
    </target>

    <target name="run" depends="jar">
        <java fork="true" classname="${main-class}">
            <classpath>
                <path refid="classpath"/>
                <path location="${jar-dir}/${ant.project.name}.jar"/>
            </classpath>
        </java>
    </target>

</project>

I execute run and all the dirs were created successfully, the .jar file was created and it was able to be executed.

I open terminal and go to the jar dir. I tried to execute through command line like this and it gave me the following error:

$java -jar helloworld.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/restlet/Server
    at android.HelloServer.main(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.restlet.Server
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    ... 1 more

Why does it say class file not found? I thought by creating the helloworld jar file, i actually included the external libraries.

You'll need to combine all the jars together using zipgroupfileset :

<target name="jar" depends="compile">
    <jar destfile="${jar-dir}/${ant.project.name}.jar" basedir="${classes-dir}">
        <manifest>
            <attribute name="Main-Class" value="${main-class}"/>
        </manifest>
        <zipgroupfileset dir="${lib-dir}" includes="*.jar"/>
    </jar>
</target>

See: Creating a bundle jar with ant

i found a solution. basically i compile my jar file and point it to the external jar files using manifest file.

here is my build file:

<project name="helloworld">
    <property name="src-dir" location="src"/>
    <property name="build-dir" location="build"/>
    <property name="classes-dir" value="${build-dir}/classes"/>
    <property name="dist-dir" location="dist"/>
    <property name="lib-dir" value="lib"/>
    <property name="jar-dir"     value="${build-dir}/jar"/>
    <property name="main-class"  value="android.HelloServer"/>

    <path id="classpath">
        <fileset dir="${lib-dir}" includes="**/*.jar"/>
    </path>

    <target name="clean" description="compile the source">
        <delete dir="${build-dir}" />
        <delete dir="${dist-dir}" />
    </target>

    <target name="cleanall" depends="clean"/>

    <target name="init">
        <!-- Create the build directory structure used by compile -->
        <mkdir dir="${build-dir}"/>
        <mkdir dir="${classes-dir}"/>
        <mkdir dir="${jar-dir}"/>
        <!--<mkdir dir="${dist-dir}"/>-->
    </target>

    <target name="compile" depends="init" description="compile the source " >
        <javac srcdir="${src-dir}" destdir="${classes-dir}" 
            classpathref="classpath" includeantruntime="false" />
        <!--<javac srcdir="${src-dir}" destdir="${build-dir}"/>-->
    </target>

    <target name="jar" depends="compile">
        <manifestclasspath property="jar.classpath" jarfile="${jar-dir}/${ant.project.name}.jar">
          <classpath refid="classpath"/>
        </manifestclasspath>    
        <jar destfile="${jar-dir}/${ant.project.name}.jar" basedir="${classes-dir}">
            <manifest>
                <attribute name="Main-Class" value="${main-class}"/>
                <attribute name="Class-Path" value="${jar.classpath}"/>
            </manifest>
        </jar>
    </target>

    <target name="run" depends="jar">
        <java fork="true" classname="${main-class}">
            <classpath>
                <path refid="classpath"/>
                <path location="${jar-dir}/${ant.project.name}.jar"/>
            </classpath>
        </java>
    </target>

</project>

The main difference is that i added the following into targer "jar":

<manifestclasspath property="jar.classpath" jarfile="${jar-dir}/${ant.project.name}.jar">
          <classpath refid="classpath"/>
        </manifestclasspath>   

<attribute name="Class-Path" value="${jar.classpath}"/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM