我正在尝试使用 Ant Build 构建一个项目,并且我已经引用了几个 jar 来使其工作。现在,当我将 Ant 构建创建的 jar 放入其他机器并运行它时。我收到错误消息NoClassDefFoundError org/apache... Not found
。无论如何将所有引用的jar放在项目的类路径或清单文件中?
或者无论如何要重新打包项目中的所有jar?我知道有一种使用jarjar的方法,但我不知道如何使用它。
请给我一些想法,我已经被这个小问题困扰了很长时间。
1 回答
使用 ANT 构建时,您需要的外部 jar 将由 ANT 工具添加到类路径中。查看您的构建脚本,您很可能在javac任务或定义类路径的设置任务中有一个条目。
构建代码后,您的 jar 文件中仅包含您的类,默认情况下,第 3 方 jar 文件(如 Apache)中的类不会添加到您的 jar 文件中。
你需要决定的是你想要一个包含所有需要的类的单个 jar 文件还是你愿意部署多个 jar 文件?如果您愿意将应用程序作为多个 jar 文件交付,您将需要提供批处理文件或 shell 脚本来为构建类路径以包含已部署 jar 的用户启动应用程序。
如果您想要一个 jar 文件,您可以执行以下操作。假设您拥有的所有 3rd 方 jar 都位于由 ANT 属性lib.dir标识的目录中:
<jar destfile='${build.dir}/lib-jars.jar'>
<zipgroupfileset dir="${lib.dir}">
<include name="**/*.jar" />
</zipgroupfileset>
</jar>
<sleep seconds='1'/> <!-- avoid timestamp warnings -->
这将在您的build.dir目录中创建一个名为lib-jars.jar的单个 jar 文件,其中包含来自所有 3rd 方 jar 的所有类。请理解,如果等效文件(如 MANIFEST.MF 文件)存在于多个 jar 中并且仅存在最后一个,则会导致它们被覆盖。
一旦你有了这个新的 all-libs jar,你就可以将你的应用程序类和这个 all-libs jar 的内容打包到一个 jar 中:
<jar destfile='${jar.file}' basedir='${classes.dir}'>
<!-- using zipfileset we can filter on entries in the one file -->
<zipfileset src='${build.dir}/lib-jars.jar'>
<exclude name="META-INF/MANIFEST.MF"/>
</zipfileset>
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-Class" value="${main.class}"/>
<section name="common">
<attribute name="Specification-Title" value="${project.title}"/>
<attribute name="Specification-Version" value="${release.version}"/>
<attribute name="Specification-Vendor" value="${vendor}"/>
<attribute name="Implementation-Title" value="${project.title}"/>
<attribute name="Implementation-Version" value="${release.version}"/>
<attribute name="Implementation-Vendor" value="${vendor}"/>
</section>
</manifest>
</jar>
请注意,我从 all-libs jar 中排除了 MANIFEST.MF 文件并创建了我自己的文件。然后最终结果是一个 jar 文件,其中包含所有库 jar 文件和您的类中的所有类/属性文件/资源。