java - 使用 Ant 在新的 jar 文件构建中包含外部 jar 文件

标签 java eclipse ant jar

我刚刚“继承”了一个 Java 项目,而不是来自 Java 背景,有时我有点迷茫。 Eclipse 用于在开发过程中调试和运行应用程序。我通过 Eclipse 成功创建了一个 .jar 文件,该文件“包含”所有必需的外部 jar,如 Log4J、xmlrpc-server 等。然后可以使用以下方法成功运行这个大 .jar:

java -jar myjar.jar

我的下一步是使用 Ant(版本 1.7.1)自动化构建,因此我不必让 Eclipse 来进行构建和部署。由于我缺乏 Java 知识,这已被证明是一个挑战。项目的根目录如下所示:

|-> jars (where external jars have been placed)
|-> java
| |-> bin (where the finished .class / .jars are placed)
| |-> src (Where code lives)
| |-> ++files like build.xml etc
|-> sql (you guessed it; sql! )

我的 build.xml 包含以下内容:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="Seraph">
    <property environment="env"/>
    <property name="debuglevel" value="source,lines,vars"/>
    <property name="target" value="1.6"/>
    <property name="source" value="1.6"/>

    <property name="build.dir"     value="bin"/>
    <property name="src.dir"       value="src"/>
    <property name="lib.dir"       value="../jars"/>
    <property name="classes.dir"   value="${build.dir}/classes"/>
    <property name="jar.dir"       value="${build.dir}/jar"/>
    <property name="jar.file"      value="${jar.dir}/seraph.jar"/>
    <property name="manifest.file" value="${jar.dir}/MANIFEST.MF"/>

    <property name="main.class" value="no.easyconnect.seraph.core.SeraphCore"/>

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

    <path id="project.classpath">
        <pathelement location="${src.dir}"/>
        <path refid="external.jars" />
    </path>

    <target name="init">
        <mkdir dir="${build.dir}"/>
        <mkdir dir="${classes.dir}"/>
        <mkdir dir="${jar.dir}"/>
        <copy includeemptydirs="false" todir="${build.dir}">
            <fileset dir="${src.dir}">
                <exclude name="**/*.launch"/>
                <exclude name="**/*.java"/>
            </fileset>
        </copy>
    </target>

    <target name="clean">
        <delete dir="${build.dir}"/>
    </target>

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

    <target name="build" depends="init">
        <echo message="${ant.project.name}: ${ant.file}"/>
        <javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}" classpathref="project.classpath">
            <src path="${src.dir}"/>
        </javac>
    </target>

    <target name="build-jar" depends="build">
        <delete file="${jar.file}" />
        <delete file="${manifest.file}" />

        <manifest file="${manifest.file}" >
            <attribute name="built-by" value="${user.name}" />
            <attribute name="Main-Class" value="${main.class}" />
        </manifest>

        <jar destfile="${jar.file}" 
            basedir="${build.dir}" 
            manifest="${manifest.file}">
            <fileset dir="${classes.dir}" includes="**/*.class" />
            <fileset dir="${lib.dir}" includes="**/*.jar" />
        </jar>
    </target>
</project>

然后我运行: ant clean build-jar

一个名为 seraph.jar 的文件被放置在 java/bin/jar 目录中。然后我尝试使用以下命令运行这个 jar: java -jar bin/jar/seraph.jar

结果是控制台的输出:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
    at no.easyconnect.seraph.core.SeraphCore.<clinit>(SeraphCore.java:23)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
    ... 1 more
Could not find the main class: no.easyconnect.seraph.core.SeraphCore. Program will exit.

我怀疑我在 build.xml 文件中做了一些非常愚蠢的事情,并且花了两天的大部分时间尝试更改配置,但无济于事。非常感谢您对这项工作的任何帮助。

哦,如果我遗漏了一些重要信息,我很抱歉。这是我第一次在 SO 发帖。

最佳答案

根据您的 ant 构建文件,我假设您想要创建一个 JAR 存档,其中不仅包含您的应用程序类,还包含您的应用程序所需的其他 JAR 的内容。

但是您的 build-jar 文件只是将所需的 JAR 放入您自己的 JAR 中;这将无法正常工作 here (见注)。

尝试修改这个:

<jar destfile="${jar.file}" 
    basedir="${build.dir}" 
    manifest="${manifest.file}">
    <fileset dir="${classes.dir}" includes="**/*.class" />
    <fileset dir="${lib.dir}" includes="**/*.jar" />
</jar>

到这里:

<jar destfile="${jar.file}" 
    basedir="${build.dir}" 
    manifest="${manifest.file}">
    <fileset dir="${classes.dir}" includes="**/*.class" />
    <zipgroupfileset dir="${lib.dir}" includes="**/*.jar" />
</jar>

更灵活、更强大的解决方案是 JarJarOne-Jar项目。如果以上内容不满足您的要求,请查看这些内容。

关于java - 使用 Ant 在新的 jar 文件构建中包含外部 jar 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3770071/

相关文章:

java - Scala-Java 互操作,方法重载问题(数组和可变参数)

java - 我的自定义 Vaadin 6 主题不工作

java - Eclipse Maven 导出丢失

Java applet 不会在浏览器中绘制或接受鼠标输入,但在 Eclipse Appletviewer 中会绘制或接受鼠标输入

ant - 在 Ant 构建任务中包含外部资源

java - 执行 TestRunner 类时出现初始化错误

java - 如何在使用 Java 提交时在 Oracle AQ 表上排队并使用 JMS 客户端使用

java - 将下载的 minecraft mod 更新到 1.8

java - 计算 Ant 执行的 JUnit 测试的总和

android - 组合 Maven/Ant+Ivy 构建管理对于双平台桌面/Android 部署的敏感性?