Java JAR 中包含 JAR 的类路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/183292/
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-11 11:00:33  来源:igfitidea点击:

Classpath including JAR within a JAR

javaclasspath

提问by Paul Reiners

Is it possible to specify a Java classpaththat includes a JAR file contained within another JAR file?

是否可以指定classpath包含另一个 JAR 文件中包含的 JAR 文件的 Java ?

采纳答案by Steve Moyer

If you're trying to create a single jar that contains your application and its required libraries, there are two ways (that I know of) to do that. The first is One-Jar, which uses a special classloader to allow the nesting of jars. The second is UberJar, (or Shade), which explodes the included libraries and puts all the classes in the top-level jar.

如果您正在尝试创建一个包含应用程序及其所需库的 jar,有两种方法(我知道)可以做到这一点。第一个是One-Jar,它使用一个特殊的类加载器来允许 jar 的嵌套。第二个是UberJar,(或Shade),它分解包含的库并将所有类放在顶级 jar 中。

I should also mention that UberJar and Shade are plugins for Maven1 and Maven2 respectively. As mentioned below, you can also use the assembly plugin (which in reality is much more powerful, but much harder to properly configure).

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

回答by Joe Skora

Not without writing your own class loader. You can add jars to the jar's classpath, but they must be co-located, not contained in the main jar.

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

回答by James Schek

You need to build a custom class-loader to do this or a third-party library that supports this. Your best bet is to extract the jar from the runtime and add them to the classpath (or have them already added to the classpath).

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

回答by PhiLho

I was about to advise to extract all the files at the same level, then to make a jar out of the result, since the package system should keep them neatly separated. That would be the manual way, I suppose the tools indicated by Steve will do that nicely.

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

回答by Vinnie

I use maven for my java builds which has a plugin called the maven assembly plugin.

我将 maven 用于我的 java 构建,它有一个名为maven assembly plugin 的插件

It does what your asking, but like some of the other suggestions describe - essentially exploding all the dependent jars and recombining them into a single jar

它可以满足您的要求,但就像其他一些建议所描述的那样 - 本质上是爆炸所有依赖的罐子并将它们重新组合成一个罐子

回答by Bruce Willis

You do NOT want to use those "explode JAR contents" solutions. They definitely make it harder to see stuff (since everything is exploded at the same level). Furthermore, there could be naming conflicts (should not happen if people use proper packages, but you cannot always control this).

您不想使用那些“分解 JAR 内容”的解决方案。它们肯定会让看东西变得更难(因为所有东西都在同一级别爆炸)。此外,可能存在命名冲突(如果人们使用正确的包,就不应该发生,但你不能总是控制这一点)。

The feature that you want is one of the top 25 Sun RFEs: RFE 4648386, which Sun, in their infinite wisdom, has designated as being of low priority. We can only hope that Sun wakes up...

您想要的功能是Sun RFE 前 25 名之一:RFE 4648386,Sun 以其无限智慧将其指定为低优先级。我们只能希望太阳醒来......

In the meanwhile, the best solution that I have come across (which I wish that Sun would copy in the JDK) is to use the custom class loader JarClassLoader.

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

回答by ecbrodie

Use the zipgroupfilesettag (uses same attributes as a filesettag); it will unzip all files in the directory and add to your new archive file. More information: http://ant.apache.org/manual/Tasks/zip.html

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

This is a very useful way to get around the jar-in-a-jar problem -- I know because I have googled this exact StackOverflow question while trying to figure out what to do. If you want to package a jar or a folder of jars into your one built jar with Ant, then forget about all this classpath or third-party plugin stuff, all you gotta do is this (in Ant):

这是解决 jar-in-a-jar 问题的一种非常有用的方法——我知道是因为我在试图弄清楚该怎么做时已经搜索了这个确切的 StackOverflow 问题。如果你想用 Ant 将一个 jar 或一个 jar 文件夹打包到你的一个构建的 jar 中,然后忘记所有这些类路径或第三方插件的东西,你所要做的就是(在 Ant 中):

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

回答by Jan Goyvaerts

Winstone is pretty good http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/. But not for complex sites. And that's a shame because all it takes is to include the plugin.

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

回答by ntg

If you are building with ant (I am using ant from eclipse), you can just add the extra jar files by saying to ant to add them... Not necessarily the best method if you have a project maintained by multiple people but it works for one person project and is easy.

如果您使用 ant 构建(我正在使用 eclipse 中的 ant),您可以通过告诉 ant 添加它们来添加额外的 jar 文件...如果您的项目由多人维护,则不一定是最佳方法,但它有效对于一个人的项目,很容易。

for example my target that was building the .jar file was:

例如,我正在构建 .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>

I just added one line to make it:

我只是添加了一行来实现它:

<jar ....">
    <zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
    <manifest>
        ................................
    </manifest>
</jar>

where

在哪里

<property name="external-lib-dir" 
          value="C:\...\eclipseWorkspace\Filter\external\...\lib" />

was the dir with the external jars. And that's it...

是带有外部罐子的目录。就是这样......

回答by Tezar

After some research I have found method that doesn't require maven or any 3rd party extension/program.

经过一些研究,我发现了不需要 maven 或任何 3rd 方扩展/程序的方法。

You can use "Class-Path" in your manifest file.

您可以在清单文件中使用“类路径”。

For example:

例如:

Create manifest file MANIFEST.MF

创建清单文件 MANIFEST.MF

Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass

Compile all your classes and run jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar

编译所有类并运行 jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar

cstands for create archive findicates that you want to specify file vis for verbose input mmeans that we will pass custom manifest file

c代表 create archive f表示您要指定 file vis for verbose input m表示我们将传递自定义清单文件

Be sure that you included lib in jar package. You should be able to run jar in the normal way.

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

based on: http://www.ibm.com/developerworks/library/j-5things6/

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

all other information you need about the class-path do you find here

你需要的关于类路径的所有其他信息你能在这里找到吗