Java Classloader - 如何引用 jar 的不同版本

2022-09-02 13:49:39

这是一个常见问题。我使用的是2个库A.jarB.jar这些库取决于同一jar的不同版本。
假设在运行时我需要 THIS.X.x.x.jar

MY.jar   
     -> A.jar -> THIS.1.0.0.jar
     -> B.jar -> C.jar -> THIS.5.0.0.jar

我可以根据它的依赖关系编译特定的jar(A.jar / B.jar),但在运行时,我只需要加载1个版本。哪一个?
仅加载 1 个依赖项(最新版本)意味着,如果库不是向后兼容的(是否有向后兼容的库?),我的代码可能会引发运行时异常。

无论如何,我知道像OSGi这样的东西可以解决这个问题。
我想知道解决这类问题的旧方法是什么......

多谢


答案 1

你提到的“旧方法”(OSGI肯定在引擎盖下使用的方法)是为依赖项的两个分支安装自己的ClassLoader。例如,这就是应用程序服务器能够在同一JVM中运行同一应用程序的较旧版本和较新版本的原因。

阅读有关类装入器层次结构的信息。

在您的设置中,棘手的部分是连接点,其中来自两个分支的类相遇。这两个分支都不能使用加载到另一个分支中的类。使它起作用的方法是确保只有由引导类装入器(JRE类)或MY.jar的类装入器装入的类被传递到两个分支。


答案 2

OSGi可以解决这个问题。OSGi 捆绑包只不过是一个包含其他元数据详细描述版本的 jar。捆绑包具有版本号,并将详细说明依赖 jar 的版本号(或范围)。

请查看这篇 Javaworld 入门文章,了解更多信息。

要在没有OSGi的情况下解决这个问题,意味着必须手动确保使用兼容的jar进行编译和运行。正如你所发现的,这不一定是一件微不足道的任务。由于jar不一定识别其版本,因此唯一可靠的方法是记录/比较校验和或签名。


推荐