Java Jar将几个jar组合成一个可执行的Jar

时间:2013-04-04 06:49:31

标签: java executable-jar

我知道要组合几个jar并创建一个可执行jar,如果我不想解压缩依赖的jar,我需要使用像OneJar这样的工具。 OneJar有自己的自定义类加载器,可以在相关的jar中找到所需的类并加载它们。

我的问题是:为什么默认的类加载器无法从附加的jar中加载类。是因为安全吗? 我很感激清楚地解释了在创建一个包含其他依赖jar的单个可执行jar时需要自定义类加载器的原因(不解包它们)。 谢谢,

4 个答案:

答案 0 :(得分:2)

技术原因是jar:的uri规范不支持嵌套。

您可以编写一个满足此需求的URI处理程序,但是当您在每个jar文件中嵌套时性能将开始下降。

使用单个jar文件,随机访问是可能的,因为索引提供了文件系统偏移量,您可以查找每个偏移量并只读取您想要的文件

使用嵌套的jar,您可以寻找内部jar,但是要从该jar中取出一个文件,您必须先从内部解压缩内部jar,然后再进行搜索。

如果您不想将jar文件解压缩到临时目录并从生成的类路径构建自己的类加载器,我会查看OSGi或Maven Shade插件提供的解决方案

答案 1 :(得分:1)

除了其他答案(Stephen迄今为止更准确的答案)之外,还要考虑JVM没有抢先探索可用的类路径条目,因此为了找到类 com.foo.Bar < / em>它将在类路径中的列出条目中查看类似 com / foo / Bar.class 的路径。如果此路径可能位于嵌套jar中(它本身不在类路径声明中列出),为了找到所述路径,类加载器应首先探索所有嵌套jar(在进程中解压缩)以便进行相应的查找

答案 2 :(得分:0)

我怀疑这个决定是出于安全性的考虑:如果通过嵌套使得任何东西变得更安全或更不安全,那将是令人惊讶的。实际上,能够在我的超级JAR中签署所有JAR作为一个整体并且在验证我的JAR时检查它们的完整性可能是非常好的。

我认为主要原因是性能和简洁性。如果JAR可以嵌套,那么这些问题的答案应该是什么:

  • 允许嵌套多少?你能否在JAR内的JAR中拥有JAR?
  • 如果一个类在两个JAR中使用?
  • JAR可以编入索引:该索引如何解释嵌套JAR的内容?

将JAR看作是一个共享库似乎是最直接的:它是一个很好的,打包的,索引的,签名的,扁平的,随时可用的链接包。值得注意的是Unix .so和Windows .dll也不允许嵌套,并且出于同样的原因我怀疑。

旁注:通常不需要创建“uberjar”:通常可以使用主JAR清单中的Class-Path字段来允许它引入外部库。

答案 3 :(得分:0)

您可以将应用程序所需的所有jar放在app文件夹(例如lib)中并使用 java -cp lib/*.jar ...或枚举主jar的清单Class-Path属性中的所有jar。