Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 针对非OSGi开发人员的JAR地狱黑客_Java_Jar_Osgi_Dll - Fatal编程技术网

Java 针对非OSGi开发人员的JAR地狱黑客

Java 针对非OSGi开发人员的JAR地狱黑客,java,jar,osgi,dll,Java,Jar,Osgi,Dll,编辑:在回顾了剧本之后,我下面使用的例子有点误导。我正在寻找这样一种情况:我有两个第三方jar(不是我可以访问源代码的国产jar),它们都依赖于同一jar的不同版本 原件: 因此,我最近熟悉了OSGi是什么,以及它在核心解决了什么(“JAR地狱”)问题。而且,尽管我对它很感兴趣(并计划在今后的某个地方迁移),我只是没有能力开始学习如何将我的项目带到它身边 所以,我现在悲叹:如果JAR地狱发生在我身上,我该如何解决这个问题呢 显然,解决方案几乎需要编写我自己的类加载器,但我很难想象这将如何表现出

编辑:在回顾了剧本之后,我下面使用的例子有点误导。我正在寻找这样一种情况:我有两个第三方jar(不是我可以访问源代码的国产jar),它们都依赖于同一jar的不同版本


原件: 因此,我最近熟悉了OSGi是什么,以及它在核心解决了什么(“JAR地狱”)问题。而且,尽管我对它很感兴趣(并计划在今后的某个地方迁移),我只是没有能力开始学习如何将我的项目带到它身边

所以,我现在悲叹:如果JAR地狱发生在我身上,我该如何解决这个问题呢

显然,解决方案几乎需要编写我自己的
类加载器
,但我很难想象这将如何表现出来,更重要的是,这将如何解决问题。我做了一些研究,大家的共识是,你必须为你生产的每一个罐子编写自己的类加载器,但由于我已经很难从树上看到森林,所以我并不认同这种说法

可以有人提供一个具体的例子,说明我自己的类加载器如何将创可贴放在伤口上(我知道,我知道,唯一的真正解决方案是OSGi)? 假设我写了一个名为
SuperJar-1.0.JAR
的新JAR,它可以做各种各样的惊人的事情。假设我的
SuperJar-1.0.jar
还有另外两个依赖项,
Fizz-1.0.jar
Buzz-1.0.jar
Fizz
Buzz
jar都依赖于
log4j
,除了
Fizz-1.0。jar
依赖于
log4j-1.2.15.jar
,而
Buzz-1.0.jar
依赖于
log4j-1.2.16.jar
。同一个jar的两个不同版本


一个基于类加载器的解决方案如何解决这个问题(简而言之)?

如果你是从“我正在构建一个应用程序,我如何避免这个”的角度而不是从“我需要这个特定的解决方案”的角度来问这个问题,我更喜欢Maven方法——即,只解析任何给定依赖项的单个版本。在log4j1.2.15->1.2.16的情况下,这将很好地工作-您只能包括1.2.16。由于旧版本是API兼容的(它只是一个补丁版本),所以很可能Fizz 1.0甚至不会注意到它使用的是比预期的更新版本


你会发现这样做可能会更容易调试问题(没有什么比让多个版本的偶数类或静态字段四处浮动更让我困惑的了!谁知道你在处理哪一个!),并且不需要任何聪明的类装入器黑客。

但是,这正是所有AppServer必须处理的问题。假设您的Fizz和Buzz是web应用程序(WAR),Super Jar是您的appserver。Super Jar将为每个“打破”正常委托模型的web应用程序安排一个类加载器,即,在查找层次结构之前,它将在本地(向下)查找。请在appservers的任何文档中阅读。例如。

使用log4j-1.2.16。它只包含wrt 1.2.15中的错误修复

如果Fizz与1.2.16冲突,分叉并修补它,然后将这些修补程序提交回Fizz的作者


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

请注意,如果您有真正不兼容的版本升级(例如Baz 1.0.0->2.0.0和向后不兼容的更改),这对您没有帮助。您必须采用类似OSGI的方式,或者将旧的jar重新打包到新的包中。是的,这是一个假设,我对非OSGi解决方案感兴趣@Steven-你能详细说明一下重新打包旧jar如何/为什么可以修复一个真正不兼容的场景吗?顺便说一句,如果你想使用OSGi的唯一原因是同时获得一个库的多个版本,我就不麻烦了。多个版本令人困惑,即使在OSGi中,对它的支持也是有限的。更好的做法是尽一切努力让每个人都能兼容一个版本。(顺便说一句,我不是说“不要使用OSGi”…正如你所知,我是OSGi的忠实拥护者。使用它的理由是正确的。)如果我使用的是两个第三方JAR,它们取决于不同的版本,比如log4j,该怎么办?在这种情况下,我无法重构代码以与相同的log4j版本兼容。@Mara:repackage意味着操作Java语言包。也就是说,将log4j类从Fizz使用的版本从org.log4j包移动到Fizz.org.log4j包中,将log4j类从Buzz使用的版本移动到Buzz.org.log4j中。然后在Fizz和Buzz的(字节)代码中相应地更改对org.log4j的引用。在您自己的代码中,您可以使用自动化。对于第三方库,可能更好。那么@四十二,我是否正确地理解了(在GlassFish上)我只需要编写自己的类加载器,如果GlassFish看到一个打破委托模型的JAR/WAR,它会查看是否有任何子类加载器可以处理该解决方案?如果是这样,我假设这些“子”类加载器必须包含在战争中,是吗?不是,我的意思是,你的问题是由打破正常委托模型的类加载器解决的。作为这个问题的解决方案的一个例子,我选择了应用服务器已经做的事情。这一点一直有效,直到你需要一个对不兼容JAR具有可传递依赖关系的webapp。特别是,现在我正在考虑一个问题,它要求我在同一个webapp中包含netty-3.2.2和netty-3.6.1,并且它们是API不兼容的