2013-04-04 81 views
3

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

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

+0

好问题。我很想知道这件事。 – NilsH 2013-04-04 06:51:18

+1

我也不清楚,但是刚才我搜索这个并获得一个链接为:http://stackoverflow.com/questions/8312909/java-create-jar-executable-with-dependant-jars-embedded。希望,它可以帮助你。 – 2013-04-04 07:10:30

+0

谢谢@TechnoCraft。我遇到这个帖子,正如答案中提到的那样,Classloader找不到嵌入的jar。我想了解其中的原因。 – Macky 2013-04-04 08:30:22

回答

2

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

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

一个jar文件,随机访问是可能的,因为指数给出了文件系统失调,你可以寻求各偏移和只读你想

有了一个嵌套的jar文件,你可以寻求内瓶,但要从文件夹中取出文件,必须先从外层解压内层文件,然后才能寻找。

我想看看解决方案,为通过的OSGi或Maven的阴影插件所提供的,如果你不希望将jar文件解压到一个临时目录,并从所得到的类路径中建立自己的类加载器

+0

谢谢@Stephen。我只是想明白这个不可能的原因。 – Macky 2013-04-04 08:23:05

0

我怀疑这个决定是由于安全性:如果通过嵌套使任何事情变得或多或少安全,那将是令人惊讶的。事实上,能够在我的超级JAR中签署所有JAR作为一个整体可能是相当不错的,并且为了验证我的JAR而对它们进行全面检查。

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

  • 允许嵌套多少?你可以在JAR内部的JAR中使用JAR吗?
  • 在一个类是在两个JAR中的情况下使用?
  • JAR的可以被索引:该索引如何解释嵌套JAR的内容?

看来最简单的认为一个JAR的就像一个共享库:这是一个很好的,包装,索引,签署,平,准备到链路包。值得注意的是,Unix .so和Windows .dll也不允许嵌套,并且出于同样的原因我怀疑。注意:通常不需要创建“uberjar's”:您通常可以在主JAR的清单中使用Class-Path字段来允许它拉入外部库。

0

你可以把所有的罐子您的应用程序需要在您的应用程序文件夹(如LIB),要么使用 java -cp lib/*.jar ...或枚举主罐子的清单Class-Path属性全部罐子。

1

除了其他答案(来自Stephen迄今为止更精确的答案)之外,还要考虑JVM不会抢先探索可用的类路径条目,所以要找到类com.foo。酒吧它看起来像在COM /富/ Bar.class中的条目在classpath中列出的路径。如果此路径可能是一个嵌套的罐子内(本身不是在类路径声明中列出),为了找到所述路径的类加载器首先应该探讨所有嵌套的jar(在这个过程中拆包它们),以做适当的查找。

+0

谢谢@Grim。我是否正确地说Eclipse的Create Runnable Jar选项将jar包中的所有依赖关系与自己的jarinjar加载器一起实现了它自己的ClassLoader? – Macky 2013-04-04 09:29:17

+1

正确,请参阅[这个问题](http://stackoverflow.com/questions/12573302/the-magic-behind-the-eclipse-generated-executable-jar-file)和相关的答案。 – Grim 2013-04-04 09:37:40

+0

谢谢@格里姆 – Macky 2013-04-04 09:57:58