如何将库与我的jar组合?

时间:2010-01-07 04:46:51

标签: java jar

好的,所以我编写了一个程序,它使用了第三方开源库,我希望将它与我的程序打包在一个jar中。我正在使用netbeans 6.8和我尝试过的所有java总是吐出错误:

java.lang.NoClassDefFoundError: libraryname;

off topic :我也想知道如果可能的话,如何通过netbeans制作可执行jar(exe)。 (我见过用java编写但是是.exe的程序)

编辑发现了一个名为FatJar的eclipse插件可以做我想要的,但是我找不到类似netbeans的东西,有这样的东西吗?

8 个答案:

答案 0 :(得分:16)

我将从强制性免责声明开始: Java可执行JAR不能以这种方式工作。可执行JAR在JAR的MANIFEST.MF文件中定义了一个主类,并且MANIFEST也允许包含可执行JAR中的代码所需库的类路径的定义。 MANIFEST中的类路径定义必须枚举要放在类路径上的每个JAR或文件夹,相对路径相对于可执行JAR的位置 - 而不是包含内部可执行JAR的路径。使用java可执行文件的“-jar”参数启动可执行JAR,java“-cp”标志和CLASSPATH环境变量都忽略。至于为什么可执行JAR是以这种方式设计的,你应该知道从JAR中包含的JAR加载类的主要缺点,即使这个回复的其余部分将集中于这样做。

注意:我丢失了完全解释它的原始sun论坛主题,但实质上是因为顶层JAR中的条目可以以随机访问方式读取,但是整个嵌入式JAR必须在任何之前读取可以访问条目,因为顶级JAR可能已压缩其条目。

我过去成功使用过One-Jar,但最终产生的jar的结构可能不是你所期望的。基本上,One-Jar类是最终jar中唯一的非JARd类;所有其他代码(您的代码和任何依赖库代码)作为JAR文件包含在结果中。您的应用程序在最终JAR的“main”文件夹中作为名为“main.jar”的常规JAR文件进行JAR。您的代码所需的任何库都作为JAR文件放在最终的JAR的“lib”文件夹中。最后但并非最不重要的是,最终的JAR的MANIFEST.MF文件告诉One-Jar你的主要类是什么。执行是一个简单的“java -jar final.jar [args your app uses]”。我不知道如何转换到关于你的非主题问题的OS原生EXE的下一步,但最好使用与One-Jar不同的打包机制。我不确定如何使用NetBeans,我的建议是使用构建工具来打包最终的jar。幸运的是,One-Jar提供了有关使用Ant生成最终jar的说明,并且应该可以轻松地集成到NetBeans中。

我相信Eclipse FatJar插件会创建一个One-Jar可执行JAR,所以如果该插件看起来像你想要的那样,那么One-Jar就是这样做的方法。就个人而言,我使用了Maven程序集。

有一点需要注意 - 任何需要(或希望)利用Java签名JAR验证的已签名库可能无法正常工作 - 像BouncyCastle这样的Java加密扩展(JCE)实现是一个值得注意的例子。我认为原因是签名验证针对最终的JAR运行,而不是签名库。幸运的是,One-Jar允许最终用户向类路径添加额外的库,这在运行可执行JAR时明确排除;为了解决这个问题,你可能最好用最终的JAR和依赖操作系统的启动脚本(.bat,.sh等)交付有问题的JAR。

答案 1 :(得分:4)

我意识到这并不能达到您想要的效果,但我将描述分发独立应用程序的常规方法。如果它确实满足了您的需求,您会发现它更好地受到工具的支持,并且更容易被用户理解,因为它遵循既定的惯例。

将您的代码放在一个jar中(我将其称为app.jar)以及一个META-INF/MANIFEST.MF文件,其中的条目如下:

Main-Class: com.y.app.AppMain
Class-path: third-party.jar blort.jar foo.jar

然后,您可以将所有jar放入目录并运行AppMain,如下所示:

java -jar app.jar

如果需要,可以将第三方库放在lib这样的单个目录中,并使用相对于主jar的路径在Class-path属性中引用它们:{{1}这有助于保持您的发行整洁。

答案 2 :(得分:4)

我对您的偏离主题问题的一般性回答是(相当冗长的)文章: Convert Java to EXE - Why, When, When Not and How 。它有许多免费和商业工具的链接,但我从未见过具有此类功能的Netbeans插件,抱歉。

答案 3 :(得分:3)

要在jar中包含另一个jar,您可能会发现jarjar有用。

如果我没有弄错的话,可执行的jar只有一个定义为'Main'的类。 This may be useful

答案 4 :(得分:2)

这是一个很好的指南,并且真正做了我想要的,而不是在所有这些第三方库中捣乱。

http://java.sun.com/developer/technicalArticles/java_warehouse/single_jar/

答案 5 :(得分:1)

如果没有关心将第三方罐子重新包装到你的最后一个大罐子里,那么this应该是最简单的方法。

答案 6 :(得分:0)

如果没有licencing issues,那么最常用的方法是解开实际的jar并将其与你的类文件一起重新加入一个新jar。

你可以简单地使用 jar cmd本身,没什么大不了的!

答案 7 :(得分:0)

如果您使用MAVEN,请使用" maven-shade-plugin"插入。它将编译包含所有依赖项的jar(第三方等)