在JAR中包含JAR的类path
是否可以指定包含另一个JAR文件中包含的JAR文件的Java classpath
?
如果你正在试图创build一个包含你的应用程序的jar,并且它是必需的库,那么有两种方法(我知道的)来做到这一点。 第一个是One-Jar ,它使用一个特殊的类加载器来实现jar子的嵌套。 第二个是UberJar (或者Shade ),它将包含的库展开,并将所有的类放在顶层jar中。
我还要提到UberJar和Shade分别是Maven1和Maven2的插件。 如下所述,你也可以使用程序集插件(实际上它更强大,但要正确configuration要困难得多)。
你不想使用那些“爆炸JAR内容”的解决scheme。 他们肯定很难看到东西(因为一切都在同一水平爆炸)。 此外,可能存在命名冲突(如果人们使用适当的软件包,则不会发生这种情况,但是您无法控制这一点)。
你想要的function是前25个Sun RFE中的一个 : RFE 4648386 ,Sun以其无限智慧将其指定为低优先级。 我们只能希望太阳醒来…
与此同时,我遇到的最好的解决scheme(我希望Sun将在JDK中复制)是使用自定义类加载器JarClassLoader 。
经过一番研究,我发现了一些不需要maven或任何第三方扩展/程序的方法。
您可以在清单文件中使用“Class-Path”。
例如:
创build清单文件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
表示创build归档文件f
表示要指定文件v
表示详细inputm
意味着我们将传递自定义清单文件
确保你在jar包中包含lib。 你应该能够以正常的方式运行jar。
基于: http : //www.ibm.com/developerworks/library/j-5things6/
你需要的关于class级path的所有其他信息都在这里find
使用zipgroupfileset标记(使用与fileset标记相同的属性); 它将解压目录中的所有文件并添加到新的存档文件中。 更多信息: http : //ant.apache.org/manual/Tasks/zip.html
这是解决jar-in-a-jar问题的一个非常有用的方法 – 我知道,因为我在search这个确切的StackOverflow问题的同时试图找出该做什么。 如果你想把一个jar子或者一个jar子文件夹打包到你的一个用Ant创build的jar子里,那么忘掉所有这些类path或者第三方插件,你所要做的就是这个(在Ant中):
<jar destfile="your.jar" basedir="java/dir"> ... <zipgroupfileset dir="dir/of/jars" /> </jar>
如果你正在用ant(我使用eclipse中的ant)构build,你可以通过向ant添加额外的jar文件来添加它们…如果你有一个由多个人维护的项目,不一定是最好的方法,但它的工作原理为一个人的项目,很容易。
例如我的目标是build立.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" />
是与外部jar子的目录。 就是这样
不是没有写你自己的类加载器。 您可以将jar添加到jar的类path中,但是它们必须位于同一位置,不包含在主jar中。
您需要构build一个自定义的类加载器来执行此操作或支持此function的第三方库。 最好的办法是从运行时中提取jar并将它们添加到classpath(或者已经将它们添加到classpath中)。
我使用maven为我的java版本,它有一个名为maven程序集插件的插件 。
它按照你的要求做,但是像其他一些build议所描述的那样 – 基本上爆炸了所有依赖的jar子,并将它们重组成一个jar子
如果你有eclpise IDE,你只需要导出你的JAR并select“Package Required libraries into generated JAR”。 eclipse会自动将所需的依赖JAR添加到生成的JAR中,并生成一些自动加载这些JAR的eclipse自定义类加载器。
我正要build议提取同级别的所有文件,然后把结果做成一个jar子,因为包装系统应该把它们整齐地分开。 这将是手动的方式,我想史蒂夫指出的工具将做得很好。
温斯顿是相当不错的http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/ 。 但不适用于复杂的网站。 这是一个耻辱,因为它只需要包含插件。
那么,如果你使用Eclipse,那么有一个非常简单的方法。
将项目导出为“Runnable”Jar文件(在Eclipse中右键单击项目文件夹,select“导出…”)。 在configuration导出设置时,请确保select“将所需的库提取到生成的Jar中”。 请记住,select“Extract …”,而不是 “Package required libraries …”。
另外 :您必须在导出设置中select运行configuration。 所以,你总是可以在某个类中创build一个空的main(),并将其用于运行configuration。
无论如何,不能保证 100%的工作时间 – 因为你会注意到一个popup消息,告诉你确保你检查你正在包含的Jar文件的许可证,以及有关不复制签名文件的东西。 但是,我一直这样做了多年 ,从来没有遇到过问题。