【发布时间】:2010-09-16 01:06:37
【问题描述】:
是否可以指定包含另一个 JAR 文件中的 JAR 文件的 Java classpath?
【问题讨论】:
是否可以指定包含另一个 JAR 文件中的 JAR 文件的 Java classpath?
【问题讨论】:
不写你自己的类加载器。您可以将 jar 添加到 jar 的类路径中,但它们必须位于同一位置,而不是包含在主 jar 中。
【讨论】:
您需要构建自定义类加载器来执行此操作或构建支持此功能的第三方库。最好的办法是从运行时提取 jar 并将它们添加到类路径中(或者已经将它们添加到类路径中)。
【讨论】:
【讨论】:
我正要建议提取同一级别的所有文件,然后从结果中制作一个 jar,因为包系统应该将它们整齐地分开。 那将是手动方式,我想史蒂夫指出的工具会很好地做到这一点。
【讨论】:
我将 maven 用于我的 java 构建,它有一个名为 maven assembly plugin 的插件。
它可以满足您的要求,但就像其他一些建议所描述的那样 - 本质上是分解所有依赖的 jar 并将它们重新组合成一个 jar
【讨论】:
您不想使用那些“爆炸 JAR 内容”解决方案。它们肯定会让东西更难看(因为所有东西都在同一水平上爆炸)。此外,可能存在命名冲突(如果人们使用正确的包,则不会发生,但您不能总是控制这一点)。
您想要的功能是top 25 Sun RFEs:RFE 4648386 之一,Sun 以其无限的智慧将其指定为低优先级。我们只能希望太阳醒来......
与此同时,我遇到的最佳解决方案(我希望 Sun 将其复制到 JDK 中)是使用自定义类加载器 JarClassLoader。
【讨论】:
activation.jar)。
使用 zipgroupfileset 标签(使用与 fileset 标签相同的属性);它将解压缩目录中的所有文件并添加到您的新存档文件中。 更多信息:http://ant.apache.org/manual/Tasks/zip.html
这是解决 jar-in-a-jar 问题的一种非常有用的方法——我知道是因为我在试图弄清楚该怎么做时搜索了这个确切的 StackOverflow 问题。如果您想将一个 jar 或 jar 文件夹打包到您使用 Ant 构建的 jar 中,那么忘记所有这些类路径或第三方插件的东西,您所要做的就是(在 Ant 中):
<jar destfile="your.jar" basedir="java/dir">
...
<zipgroupfileset dir="dir/of/jars" />
</jar>
【讨论】:
温斯顿很不错http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/。但不适用于复杂的网站。这是一种耻辱,因为只需要包含插件。
【讨论】:
如果您使用 ant 构建(我使用的是 eclipse 中的 ant),您可以添加额外的 jar 文件 通过告诉蚂蚁添加它们... 如果您有一个由多人维护的项目,则不一定是最佳方法,但它适用于一个人的项目并且很容易。
例如,我构建 .jar 文件的目标是:
<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
<manifest>
<attribute name="Author" value="ntg"/>
................................
<attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
</manifest>
</jar>
我只是添加了一行来实现它:
<jar ....">
<zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
<manifest>
................................
</manifest>
</jar>
在哪里
<property name="external-lib-dir"
value="C:\...\eclipseWorkspace\Filter\external\...\lib" />
是带有外部罐子的目录。 就是这样……
【讨论】:
经过一些研究,我发现了不需要 maven 或任何 3rd 方扩展/程序的方法。
您可以在清单文件中使用“Class-Path”。
例如:
创建清单文件 MANIFEST.MF
Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass
编译所有类并运行jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar
c 代表创建存档
f 表示要指定文件
v 用于详细输入
m 表示我们将传递自定义清单文件
确保您在 jar 包中包含 lib。你应该可以正常运行jar了。
基于:http://www.ibm.com/developerworks/library/j-5things6/
您需要的有关类路径的所有其他信息都找到here
【讨论】:
custom_lib.jar 移走,jar 就不能再执行了:(
好吧,如果您使用的是 Eclipse,那么有一个非常简单的方法。
将您的项目导出为“可运行”Jar 文件(在 Eclipse 中右键单击项目文件夹,选择“导出...”)。配置导出设置时,请务必选择“将所需库提取到生成的 Jar 中”。请记住,选择“Extract...”和not“Package required libraries...”。
另外:您必须在导出设置中选择运行配置。因此,您总是可以在某个类中创建一个空的 main() 并将其用于您的运行配置。
无论如何,不能保证在 100% 的时间内工作 - 因为您会注意到一条弹出消息,告诉您确保检查您所使用的 Jar 文件的许可证包括关于不复制签名文件的内容。但是,我已经这样做了 年,从未遇到过问题。
【讨论】:
如果您有 eclpise IDE,您只需导出您的 JAR 并选择“将所需的库打包到生成的 JAR 中”。 eclipse 会自动将所需的依赖 JAR 添加到生成的 JAR 中,并生成一些自动加载这些 JAR 的 eclipse 自定义类加载器。
【讨论】:
提取到 Uber-dir 对我有用,因为我们都应该使用 root:\java 并且在带有版本控制的包中包含 outlets 代码。即ca.tecreations-1.0.0。签名没问题,因为 jar 从其下载位置完好无损。 3rd 方签名完整,解压到 c:\java。这是我的项目目录。从启动器运行 java -cp c:\java Launcher
【讨论】:
如果您使用的是 Spring Boot,您可能需要查看以下文档:The Executable Jar Format
Java 不提供任何标准方式来加载嵌套的 jar 文件(即 即,jar 文件本身包含在 jar 中)。这可以是 如果您需要分发自包含应用程序,则会出现问题 无需解压即可从命令行运行。
为了解决这个问题,许多开发人员使用“阴影”罐子。一个有阴影的罐子 将所有 jar 中的所有类打包到一个“uber jar”中。这 带阴影的罐子的问题是很难看出哪个 库实际上在您的应用程序中。也可能有问题 如果在多个文件中使用相同的文件名(但内容不同) 罐子。 Spring Boot 采用了不同的方法,让您实际上 直接嵌套罐子。
Spring 文档还列出了一些替代的单 Jar 解决方案:
【讨论】: