这是一个常见问题。我正在使用 2 个库 罐子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 个依赖项(最新版本)意味着如果库不向后兼容(有向后兼容的库吗?),我的代码可能会抛出运行时异常。

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

多谢

有帮助吗?

解决方案

“老样子”你提到(和一个OSGI引擎盖下肯定使用)是安装自己的ClassLoader为你的依赖的两个分支。这是怎么了,例如,应用程序服务器能够运行在同一个JVM内部新旧版本的同一应用程序。

阅读关于类加载器的层次结构。

在您的设置中,棘手的部分是接头的点,其中来自两个支路的类满足。无论是分支机构可以采用加载到另外一个班。使它工作的方法是确保只有通过引导类加载器(JRE类)或MY.jar的类装载器装载的类传下来的两个分支。

其他提示

的OSGi可以解决这个问题。 OSGi包无非就是一个罐子更多额外的元数据,详细的版本。甲束具有版本号,并且将详细的版本号(或范围)相关的罐子。

看看 获得更多信息。

要解决这个不OSGi的装置具有手动确保编译和兼容罐子运行。正如你已经发现,不一定是简单的任务。由于罐子不必识别他们的版本中,唯一可靠的方式做到这一点,以记录/比较校验或签名。

许多库都是向后兼容的。但不是所有的..


旧的方法是尝试仅依赖一个版本。

使用相同版本(最新)编译两者可能更安全。
至少你会得到编译时错误,而不是运行时错误。

如果需要,您可以稍微修改一下与旧依赖项一起使用的库......
这需要访问源...


请注意,编译时兼容性也不能保证正确的运行时行为。这是一步,然后您可以:

  • 阅读 WhatsNew 文件以获取新版本的 jar
  • 在 Internet 上查找报告兼容性问题的用户
  • 编写 JUnit
  • 比较两个jar中的代码

正如KLE所提到的,默认的方法是依赖于较新版本。谁也不能保证,但大多数的这个作品的时候。可能是最好的方式(而被臃肿一个)是利用OSGI克服它。

要参照基本的 “oldway” 实施结帐 https://github.com/atulsm/ElasticsearchClassLoader

此提供了一种方法来处理elasticsearch客户端使用的非后向兼容的版本。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top