JAR Hell Hacks for Non-OSGi Developers

时间:2011-09-22 20:31:05

标签: java jar osgi dll

修改:在审核了游戏后,我在下面使用的示例是 tad 误导。我正在寻找我有两个第三方罐子(不是我可以访问源代码的本土罐子)的情况,它们都依赖于同一个罐子的不同版本。


原始 所以我最近熟悉了OSGi是什么,以及它解决的核心问题(“JAR Hell”)。而且,和我一样感兴趣(并计划在某个地方迁移),我只是没有让我开始学习如何将我的项目带到它上面。

所以,我现在感叹:如果JAR发生在我身上,我怎么解决这个没有OSGi?

显然,该解决方案几乎 涉及编写我自己的ClassLoader,但我很难想象这将如何表现自己,更重要的是,这将如何表现解决这个问题。我做了一些研究,并且一致认为你必须为你生产的每一个JAR编写自己的ClassLoader,但是因为我已经很难看到树林中的那片林,所以这句话并没有和我一起沉没。 / p>

有人能提供一个具体的例子,说明我自己的ClassLoader如何在这个伤口上放一个创可贴(我知道,唯一真正的解决方案是OSGi)?

假设我写了一个名为SuperJar-1.0.jar的新JAR,可以完成各种令人惊奇的工作。假设我的SuperJar-1.0.jar有两个其他依赖项,Fizz-1.0.jarBuzz-1.0.jarFizzBuzz个罐子都依赖于log4j,除了Fizz-1.0.jar取决于log4j-1.2.15.jar,而Buzz-1.0.jar取决于log4j-1.2.16.jar。同一个罐子的两个不同版本。

基于ClassLoader的解决方案如何解决这个问题(简而言之)?

3 个答案:

答案 0 :(得分:4)

如果您从“我正在构建应用程序中提出这个问题,我该如何避免这个问题”而不是“我需要这个特定的解决方案”的角度,我强烈希望使用Maven方法 - 即,仅解析任何给定依赖项的单个版本。在log4j 1.2.15的情况下 - > 1.2.16,这将工作正常 - 你只能包括1.2.16。由于旧版本与API兼容(它只是一个补丁版本),因此Fizz 1.0很可能甚至不会注意到它使用的是比预期更新的版本。

你会发现这样做可能方式更容易调试问题(没有什么让我感到困惑,就像有多个版本的偶数类或静态字段浮动!谁知道你是哪一个?处理!)并且不需要任何聪明的类加载器黑客。

答案 1 :(得分:3)

但是,这正是所有应用程序中必须处理的内容。假装您的Fizz和Buzz是Web应用程序(WAR),Super-Jar就是您的appserver。 Super-Jar将为每个Web应用程序安排一个“打破”正常委托模型的类加载器,即在查找层次结构之前它将在本地(向下)查找。请阅读任何应用程序的文档中的相关内容。例如http://download.oracle.com/docs/cd/E19798-01/821-1752/beade/index.html

答案 2 :(得分:0)

使用log4j-1.2.16 。它只包含1.2.15的错误修正。

如果Fizz打破1.2.16,分叉并修补,则将这些补丁提交给Fizz的作者。

使用特殊委派逻辑创建自定义类加载器的替代方法非常复杂,可能会导致许多问题。我不明白你为什么要这样做而不只是使用OSGi。您是否考虑过创建嵌入式OSGi框架,因此您不必转换整个应用程序?