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

2024-03-20

我刚刚“继承”了一个 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 构建 jar

并且名为 seraph.jar 的文件放置在 java/bin/jar-directory 中。然后我尝试使用以下命令运行这个 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-jarfile 只是将所需的 JAR 放入您自己的 JAR 中;这不会像解释的那样工作here http://download.oracle.com/javase/tutorial/deployment/jar/downman.html(看注释)。

尝试修改这个:

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

to this:

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

更灵活、更强大的解决方案是JarJar http://code.google.com/p/jarjar/ or One-Jar http://one-jar.sourceforge.net/项目。如果上述内容不能满足您的要求,请查看这些内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Ant 将外部 jar 文件包含在新的 jar 文件构建中 的相关文章

随机推荐

  • 修改后的 ClaimsPrincipal 无效

    我正在使用 ASP NET MVC Identity2 我添加了 名字 自定义ClaimPrincipal public async Task
  • 任意泛型的 Typescript 映射

    我试图定义两种类型 它们应该类似于 export type IQuery
  • 如何在 SVG 中嵌入 schema.org 标记?

    我希望向 SVG 文件添加语义 并希望使用 schema org 术语 SVG 有执行此操作的语法吗 我的第一次尝试是
  • LaTeX 中的脚注间距

    我正在写论文 研究生院说我需要在多个脚注之间留一个空格 而且文本和脚注开头之间的空格太小 有没有办法做到这一点 任何帮助是极大的赞赏 footnotesep是脚注之间的空格 setlength footnotesep 0 5cm footi
  • 将一堆扩展名为“.jpg”的 PNG 图像重命名为“.png”

    所以我有一个包含数千个图像文件的文件夹 所有这些文件都保存为 jpg 问题是其中一些文件实际上是 PNG 图像文件 因此它们无法在很多程序中打开 除非我手动将其扩展名更改为 png 例如 Ubuntu 图像查看器会抛出此错误 解释 JPEG
  • 销毁并重新初始化引导滑块

    我正在使用这里找到的 Bootstrap slider https github com seiyria bootstrap slider https github com seiyria bootstrap slider目前正在使用 v1
  • .NET 通过反射获取私有属性

    我有以下场景 装配A public abstract class MyBaseEntity Uncompleted method public void addChild
  • Jquery中的Ajax代码完成后执行下一行

    需要帮忙 我正在函数内执行 ajax 调用 Ajax 调用的结果是函数的返回值 代码如下 function tabstrip ajax type POST url WebService MessageUnratedCount asmx Ge
  • 仅将分支的最后一次提交合并到 master 中

    我使用以下命令创建了一个测试存储库 mkdir test repo cd test repo git init 我在目录中创建了一个文件并提交了更改 echo 0 gt file txt git add file txt git commi
  • git log 每个文件的提交计数

    我正在尝试从中获取以下内容git log 1 存储库中每个文件的提交次数 两个日期之间 2 编辑每个文件的贡献者数量 两个日期之间 3 编辑每个文件的不同贡献者的数量 两个日期之间 我试过玩git log但我并没有那么成功 我也尝试过寻找脚
  • 带有 OR 条件的 COUNTIFS 给出#SPILL!因此

    我有以下公式 COUNTIFS MachineData N N Arlington RenewNorfolk MachineData X X Y MachineData E E lt gt rinse MachineData C C gt
  • 如何在 Objective C 中找到 HH:MM:SS 格式的两个日期之间的差异?

    我认为标题本身说明了我想做什么 不过 让我澄清一下 我现在正在开发一个应用程序 其中有两个日期 格式如下 年 月 日 时 分 SS 我需要使用它来计算格式中两个日期之间的差异 HH MM SS 我在维基上搜索并尝试了运气但没有成功 有人可以
  • 我应该使用 int 还是 Int32

    In C int and Int32是同一件事 但我读过很多次int优先于Int32没有给出任何理由 有什么原因吗 我应该关心吗 两者确实是同义词 int看起来会更熟悉一些 Int32使 32 位对于阅读代码的人来说更加明确 我会倾向于使用
  • REST 确保 JSON 模式验证不起作用

    我正在使用 Spring Boot 和 REST Assured 来测试 REST API 我正在尝试使用 JSON 模式验证的示例 但它引发了此错误 java lang IllegalArgumentException Schema to
  • 查找会计年度特定日期所属的季度

    我正在使用 java 1 7 如何查找会计年度的特定日期所属的季度 该季度可以从任何月份的 1 日 JAN DEC 开始 并且还需要该季度的开始日期和结束日期 即假设FY 2017年4月1日 2018年3月31日 那么日期2017年6月26
  • Android - 如何在新 API 中请求位置更新?

    我正在研究 google 的新位置 API 以获取纬度和经度值 private void getLastLocation FusedLocationProviderClient mFusedLocationClient LocationSe
  • 如果用户不在角色中,则忽略@Html.Action()

    In my View我渲染菜单 Html Action RenderMenu Admin and Html Action RenderMenu Manager 行动地点 Authorize Roles Admin public Action
  • 如何在自定义 .NET Web 控件中指定必需的属性?

    private string itemId Browsable true Description Required identifier for the Item public string ItemId get return itemId
  • 按位左移函数

    我正在尝试实现一个左旋转函数 将整数 x 左旋转 n 位 例如 rotateLeft 0x87654321 4 0x76543218 法律行动 gt 到目前为止我有这个 int rotateLeft int x int n return x
  • 使用 Ant 将外部 jar 文件包含在新的 jar 文件构建中

    我刚刚 继承 了一个 Java 项目 而不是来自 Java 背景 有时我会有点迷失 Eclipse 用于在开发过程中调试和运行应用程序 我通过 Eclipse 成功创建了一个 jar 文件 其中 包含 所有必需的外部 jar 如 Log4J