在JAR中包含JAR的类路径

问题描述:

是否可以指定包含另一个JAR文件中包含的JAR文件的Java classpath在JAR中包含JAR的类路径

如果您正在尝试创建一个包含您的应用程序并且它是必需的库的jar文件,那么有两种方法(我知道这样做)。第一个是One-Jar,它使用特殊的类加载器来实现罐子的嵌套。第二个是UberJar(或Shade),它会展开包含的库并将所有类放入*jar包中。

我还应该提到,UberJar和Shade分别是Maven1和Maven2的插件。如下所述,您还可以使用程序集插件(实际上它更强大,但要正确配置要困难得多)。

+64

所以我们现在在5年后。看起来这仍然是事实。非常伤心:( – T3rm1 2013-08-06 06:49:19

+1

我知道现在一天的最好方法是使用IntelliJ罐子工件,它从相关罐子中提取所有类并将它们放入一个罐子中。 – enl8enmentnow 2014-01-25 17:50:05

+1

这在某些情况下不可能,例如何时你使用的JCE实现像BouncyCastle那样需要签名 – debuti 2014-08-11 11:44:43

不是没有写你自己的类加载器。您可以将jar添加到jar的类路径中,但它们必须位于同一位置,不包含在主jar中。

您需要构建一个自定义类加载器来执行此操作或支持此功能的第三方库。你最好的选择是从运行时中提取jar并将它们添加到classpath中(或者将它们添加到classpath中)。

我打算建议在同一级别提取所有文件,然后在结果中制作一个jar文件,因为包系统应该保持它们整齐分离。 这将是手动的方式,我想史蒂夫指出的工具会做得很好。

我使用我的java版本的maven,它有一个名为maven assembly plugin的插件。

它做什么你问,但像一些其他的建议形容 - 本质爆炸所有的依赖罐子,并将它们重新组合成一个单一的罐子

你不想使用这些“爆炸JAR内容”的解决方案。他们肯定很难看到东西(因为一切都在同一层次爆炸)。此外,可能会出现命名冲突(如果人们使用适当的软件包,则不会发生这种冲突,但您无法始终控制这种冲突)。

您需要的功能是top 25 Sun RFEsRFE 4648386之一,Sun以其无限的智慧将其指定为低优先级。我们只能希望Sun唤醒...

与此同时,我遇到的最好的解决方案(我希望Sun将在JDK中复制)是使用自定义类加载器JarClassLoader

使用zipgroupfileset标签(使用相同的属性,为文件集标签);它将解压缩目录中的所有文件并添加到新的存档文件中。 更多信息:http://ant.apache.org/manual/Tasks/zip.html

这是要解决的jar-IN-A-JAR问题非常有用的方式 - 我知道,因为我试图找出该怎么做用Google搜索这个确切的*问题。如果要打包一个罐子或瓶子与蚂蚁的一个内置的jar的文件夹,然后忘掉这一切的类路径或第三方插件的东西,你要做的是这样的(以蚂蚁):

<jar destfile="your.jar" basedir="java/dir"> 
    ... 
    <zipgroupfileset dir="dir/of/jars" /> 
</jar> 

Winstone相当不错http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/。但不适用于复杂的网站。这是一个耻辱,因为它只需要包含插件。

如果你正在用ant(我使用eclipse中的ant)构建,你可以通过向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" /> 

是与外部罐子的dir。 就是这样...

经过一番研究,我发现了一种不需要maven或任何第三方扩展/程序的方法。

您可以在清单文件中使用“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意味着我们将pa ss自定义清单文件

确保您在jar包中包含lib。你应该能够以正常的方式运行jar。

基于:http://www.ibm.com/developerworks/library/j-5things6/

您需要了解的类路径中的所有其他信息你觉得here

嗯,是,如果你正在使用Eclipse的一个非常简单的方法。

将项目导出为“Runnable”Jar文件(在Eclipse中右键单击项目文件夹,选择“导出...”)。当您配置导出设置时,请务必选择“将所需库提取到生成的Jar中”。请记住,选择“Extract ...”和而不是“包装所需的库...”。

此外:您必须在导出设置中选择运行配置。因此,您可以在某个类中始终创建一个空的main(),并将其用于您的运行配置。

无论如何,它不是保证 100%的时间工作 - 因为你会注意到一个弹出消息,告诉你确保你检查你包括的Jar文件的许可证和一些关于不复制签名文件。但是,我一直在做这个并从未遇到过问题。

如果你有eclpise IDE,你只需要导出你的JAR并选择“Package Required libraries into generated JAR”。 eclipse会自动将所需的依赖JAR添加到生成的JAR中,并生成一些自动加载这些JAR的eclipse自定义类加载器。