【问题标题】:java build ant file with external jar filesjava用外部jar文件构建ant文件
【发布时间】:2013-09-23 09:22:32
【问题描述】:

我创建了一个 ant 构建文件来将我的 java src 编译成一个 .jar 文件。它使用外部 jar 文件。

我的文件目录:

+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

外部库位于 lib 文件夹中。 主类在 HelloServer.java 中

这是我的 ant 构建文件:

<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>

我执行run,所有目录都创建成功,.jar文件创建成功,可以执行了。

我打开终端并转到 jar 目录。我试图通过这样的命令行执行,它给了我以下错误:

$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

为什么说找不到类文件?我想通过创建 helloworld jar 文件,我实际上包含了外部库。

【问题讨论】:

    标签: java ant build


    【解决方案1】:

    您需要使用 zipgroupfileset 将所有 jar 组合在一起:

    <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>
    

    见:Creating a bundle jar with ant

    【讨论】:

    • 嗨,凯文,感谢您的回复。我读到用外部 jar 编译不是一个好主意?那是对的吗?这样做的标准方法是什么?
    • 这完全取决于您希望如何打包您的应用程序。您可以使用您的 lib 目录打包,并提供一个启动脚本,将 3rd 方 jar 放在类路径上。或者,您可以将所有内容组合成一个“fatjar”。我不知道一种方法一定更好——它们只是不同的方法。
    【解决方案2】:

    我找到了解决方案。基本上我编译我的 jar 文件并使用清单文件将其指向外部 jar 文件。

    这是我的构建文件:

    <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>
    

    主要区别是我在目标“jar”中添加了以下内容:

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

    【讨论】:

      猜你喜欢
      • 2011-04-15
      • 1970-01-01
      • 2012-07-09
      • 2020-04-08
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      相关资源
      最近更新 更多