Java类加载器-如何引用jar的不同版本
这是一个常见的问题。我使用了两个库A.jar和B.jar,它们取决于同一jar的不同版本。Java类加载器-如何引用jar的不同版本,java,jar,dependencies,classloader,versions,Java,Jar,Dependencies,Classloader,Versions,这是一个常见的问题。我使用了两个库A.jar和B.jar,它们取决于同一jar的不同版本。 假设在运行时我需要这个.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个依赖项(最新版本)意味着如果库不向后兼容,我的代码可能
假设在运行时我需要这个.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这样的东西可以解决这个问题。
我想知道解决这类问题的老办法是什么
非常感谢许多库都是向后兼容的。但并非所有
旧方法是尝试只依赖一个版本 使用相同的版本(最新版本)编译两者可能更安全。
至少会出现编译时错误,而不是运行时错误 如果需要,您可以稍微修改一点与旧依赖项一起工作的库…
这将需要访问源
请注意,编译时兼容性也不能保证正确的运行时行为。这是一个步骤,然后您可以:
- 读取新版本jar的WhatsNew文件
- 在Internet上查找报告兼容性问题的用户
- 写JUnits
- 比较两个JAR中的代码
- OSGi可以解决此问题。OSGi捆绑包只不过是一个包含额外元数据详细版本的jar。捆绑包有一个版本号,并将详细说明依赖JAR的版本号(或范围)
有关更多信息,请参阅
在没有OSGi的情况下解决这个问题意味着必须手动确保使用兼容的JAR编译和运行。正如您所发现的,这不一定是一项琐碎的任务。由于JAR不一定能识别其版本,因此唯一可靠的方法是记录/比较校验和或签名。正如KLE所提到的,默认方法是依赖于较新的版本。没有保证,但大多数情况下,这是可行的。也许最好的方法(虽然过于臃肿)是使用OSGI来克服它。您提到的“旧方法”(OSGI当然在幕后使用的方法)是为依赖项的两个分支安装您自己的类加载器。例如,应用服务器就是这样在同一JVM中运行同一应用程序的旧版本和新版本的 了解类加载器层次结构 在您的设置中,棘手的部分是连接点,来自两个分支的类在此交汇。两个分支都不能使用加载到另一个分支中的类。使其工作的方法是确保只将引导类加载器(JRE类)或MY.jar的类加载器加载的类传递给这两个分支。参考基本的“oldway”实现签出
这提供了一种处理elasticsearch客户端使用的非向后兼容版本的方法。有可能实现吗?OSGi如何帮助?我们再次引入对OSGi的依赖,这是典型产品软件开发(尤其是嵌入式)中的一项开销