关于类加载器的行为,我有一个有趣的问题。
问题一:类加载器加载jar的顺序是什么?
给出了以下jar和包含类:
a.jar
+-com/scheffield/foo/A.class
b.jar
+-com/scheffield/foo/B.class
将加载哪个类?
问题二:类路径中文件的路径和名称是唯一的吗?
给出了以下jar和包含类(真实示例):
spring-beans-3.0.3.RELEASE.jar
+-META-INF/spring.schemas
spring-aop-3.0.3.RELEASE.jar
+-META-INF/spring.schemas
我可以告诉您的是,这两个文件都是由Spring加载的,否则会发生异常(请参阅this article)。
我为什么要问:
我做了一个所谓的大 jar (cookbook entry for gradle)。多数民众赞成在一个jar与应用程序类和所有其他依赖项解压缩并打包在大jar中。而且我不确定如何处理重复的文件。
最佳答案
如果将 jar 组合成一个大 jar ,则肯定有发生冲突的可能性。如果您小心地将它们从有效类路径中的最后一个源合并到第一个(因此将后面的jar和早期的jar覆盖),您将获得大致相同的结果。
我之所以这么说,是因为jars中的 list 包含其他需要合并的处理指令。例如, list 可以包含Class-Path attribute,它在类路径中包含其他jar。可以合并jar,但丢失 list 属性,这些 list 属性指定了实际必要的类路径的一部分。如果 list 中包含sealed或signed jar ,那么在不违反 jar 签名部分的情况下,您可能根本无法进行合并。
总而言之, jar 并不是真正设计为以这种方式合并的。它可以工作,但是有很多错误的可能性,其中一些是不可能解决的。常见的错误原因是合并两个jar文件,并最终导致多个文件具有相同的路径,而zip文件中允许使用相同的路径。 ant jar和zip任务使您可以合并多个源,并且可能产生此类问题。
实际上,最好将包含许多jar和源的Web应用程序 bundle 到一个WAR或EAR归档文件中。这就是它们存在的全部意义。
关于spring - 类加载器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4437028/