修改:在审核了游戏后,我在下面使用的示例是 tad 误导。我正在寻找我有两个第三方罐子(不是我可以访问源代码的本土罐子)的情况,它们都依赖于同一个罐子的不同版本。
原始 所以我最近熟悉了OSGi是什么,以及它解决的核心问题(“JAR Hell”)。而且,和我一样感兴趣(并计划在某个地方迁移),我只是没有让我开始学习如何将我的项目带到它上面。
所以,我现在感叹:如果JAR发生在我身上,我怎么解决这个没有OSGi?
显然,该解决方案几乎 涉及编写我自己的ClassLoader
,但我很难想象这将如何表现自己,更重要的是,这将如何表现解决这个问题。我做了一些研究,并且一致认为你必须为你生产的每一个JAR编写自己的ClassLoader,但是因为我已经很难看到树林中的那片林,所以这句话并没有和我一起沉没。 / p>
有人能提供一个具体的例子,说明我自己的ClassLoader如何在这个伤口上放一个创可贴(我知道,唯一真正的解决方案是OSGi)?
假设我写了一个名为SuperJar-1.0.jar
的新JAR,可以完成各种令人惊奇的工作。假设我的SuperJar-1.0.jar
有两个其他依赖项,Fizz-1.0.jar
和Buzz-1.0.jar
。 Fizz
和Buzz
个罐子都依赖于log4j
,除了Fizz-1.0.jar
取决于log4j-1.2.15.jar
,而Buzz-1.0.jar
取决于log4j-1.2.16.jar
。同一个罐子的两个不同版本。
基于ClassLoader的解决方案如何解决这个问题(简而言之)?
答案 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框架,因此您不必转换整个应用程序?