Java 如何将库与我的 jar 结合起来?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2018257/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:37:46  来源:igfitidea点击:

How to combine library with my jar?

javajar

提问by Dacto

Ok so i wrote a program that makes use of a 3rd party open source library and i want to package it with my program in a single jar. I'm using netbeans 6.8 and everything I've tried java always spit back the error:

好的,所以我编写了一个使用 3rd 方开源库的程序,我想将它与我的程序一起打包在一个 jar 中。我正在使用 netbeans 6.8 并且我尝试过的所有东西 java 总是吐出错误:

java.lang.NoClassDefFoundError: libraryname;

off topic:also i would like to know how to make an executable-jar(exe) through netbeans if it is possible. (ive seen programs that were written in java but were an .exe)

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

EDITdiscovered a plugin for eclipse called FatJar which can do what i want, but i cant find something similar for netbeans, is there such thing?

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

回答by Conrad Meyer

To include another jar in your jar, you might find jarjaruseful.

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

Executable jars just have a class defined as 'Main', if I'm not mistaken. This may be useful.

如果我没记错的话,可执行 jar 只是有一个定义为“Main”的类。这可能很有用

回答by Suraj Chandran

If there are no licencing issuesthen the most preffered way is to unjar the actual jar and rejar it with your class files in it, to a new jar.

如果没有,licencing issues那么最好的方法是解压实际的 jar 并将其与您的类文件一起重新jar 到一个新的 jar 中。

You can simply use the jarcmd itself for this, no big deal!!

为此,您可以简单地使用jarcmd 本身,没什么大不了的!!

回答by erickson

I realize that this doesn't achieve exactly what you want, but I'll describe the customary method of distributing a standalone application. If it does meet your needs, you'll find that it's better supported by tools and more readily understood by users, because it follows established conventions.

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

Put your code in a jar (I'll call it app.jar) along with a META-INF/MANIFEST.MFfile with entries like this:

将您的代码放入一个 jar(我将称之为app.jar)以及一个META-INF/MANIFEST.MF包含如下条目的文件:

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

Then, you can throw all of the jars into a directory and run AppMainlike this:

然后,您可以将所有 jars 放入一个目录并AppMain像这样运行:

java -jar app.jar

If you want, you can put the third-party libraries in a single directory like liband refer to them in the Class-pathattribute using a path relative to the main jar: lib/third-party.jarThat helps keep your distribution tidy.

如果需要,您可以将第三方库放在一个目录中,例如,libClass-path使用相对于主 jar 的路径在属性中引用它们:lib/third-party.jar这有助于保持您的发行版整洁。

回答by bryantsai

If there's not any concern of repackaging 3rd party jars into your final big jar, then thisshould be the easiest method.

如果不担心将第 3 方罐子重新包装到最后的大罐子中,那么应该是最简单的方法。

回答by Dmitry Leskov

My generic answer to your off-topic question is a (rather lengthy) article: Convert Java to EXE - Why, When, When Not and How. It has lots of links to free and commercial tools, but I have never seen a Netbeans plugin with such functionality, sorry.

我对您的题外问题的通用答案是一篇(相当冗长的)文章:将 Java 转换为 EXE - 为什么、何时、何时不以及如何。它有很多免费和商业工具的链接,但我从未见过具有此类功能的 Netbeans 插件,抱歉。

回答by beltorak

I'll start off with the obligatory disclaimer: Java executable JARs do not work this way.An executable JAR has a main class defined in the JAR's MANIFEST.MF file, and the MANIFEST also allows the definition of a class path to include libraries that the code in the executable JAR will need. The class path definition in the MANIFEST must enumerate every JAR or folder to put on the class path, relative paths are relative to the location of the executable JAR - not to paths contained insidethe executable JAR. Executable JARs are launched with the "-jar" argument to the java executable, and both the java "-cp" flag and the CLASSPATH environment variable are ignored. As for why executable JARs were designed this way, you should be aware of the primary disadvantage of loading classes from JARs contained within JARs, even though the rest of this reply will focus on doing just that.

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

NOTE: I lost the original sun forum topic that explained it fully, but essentially it is because entries in the top level JAR can be read in a random access manner, but the entire embedded JAR must be read before any entries can be accessed, because the top level JAR might have compressed its entries.

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

I have used One-Jarsuccessfully in the past, but the structure of the final resulting jar may not be what you expect. Essentially the One-Jar classes are the only non-JARd classes in the final jar; all other code (your code and any dependent library code) is included in the resulting as JAR as JAR files. Your application is JARed as a regular JAR file named "main.jar" in the final JAR's "main" folder. Any libraries your code needs is placed, as JAR files, in the final JAR's "lib" folder. And last but not least the final JAR's MANIFEST.MF file tells One-Jar what your main class is. Execution is a dead simple "java -jar final.jar [args your app uses]". I don't know how to take the next step of converting to an OS-native EXE regarding your off-topic question, but it would probably be best to use a different packaging mechanism than One-Jar anyway. I'm not sure how to go about this with NetBeans, my advice there is to use a build tool to package the final jar. Fortunately One-Jar provides instructions on generating the final jar with Ant, and that should be easily integratable into NetBeans.

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

I believe the Eclipse FatJar plugin creates a One-Jar executable JAR, so if that plugin seems to do what you want, then One-Jar is the way to do it. Personally, I used a Maven assembly.

我相信 Eclipse FatJar 插件会创建一个 One-Jar 可执行 JAR,所以如果该插件似乎可以满足您的需求,那么 One-Jar 就是这样做的方法。就个人而言,我使用了 Maven 程序集。

There is a caveat - any signed libraries that require (or desire) to take advantage of Java's signed JAR verification may not work this way - Java Cryptographic Extension (JCE) implementations like BouncyCastle are a notable example. I think the reason is that the signature verification runs against the final JAR, not the signed library. Fortunately One-Jar allows the end user to add additional libraries to the classpath, something that is explicitly precluded when running an executable JAR; to workaround this you might be better off delivering the problematic JARs with the final JAR and an OS dependent launch script (.bat, .sh, etc).

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

回答by Hiro2k

This was a great guide and really did what I wanted without mucking about in all these 3rd party libs.

这是一个很棒的指南,真的做了我想做的事,而没有在所有这些 3rd 方库中胡思乱想。

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

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

回答by Azat Nugusbayev

if you use MAVEN, use "maven-shade-plugin" plugin. It will compile jar with all dependencies(3rd party and etc.)

如果您使用 MAVEN,请使用“maven-shade-plugin”插件。它将编译具有所有依赖项(第 3 方等)的 jar