当两个Java框架需要第三个框架,但两个框架中的每一个都需要第三个框架的不同版本时,会发生什么?

2022-09-04 20:31:44

在我的Java项目中,我使用了两个不同的框架(假设A.jar和B.jar),它们都需要一个通用框架(假设Log4j.jar),但有两个不同的版本。如果框架A需要Log4J v1.1,B需要Log4j v1.2,Java如何处理它?它是否会导致某种冲突/错误,或者会以某种方式(如何?)解决?

如果它不会导致冲突/错误(我的项目可以编译和运行) - 我可以在这个项目中使用任何版本的Log4j吗?还是我被迫选择Log4j的较低/较高版本号?

更新:更具体...如果Log4j API的某些部分在v1.2中发生了变化(假设一个方法doIt()签名发生了变化),并且A和B都调用doIt,该怎么办?将会发生什么?我的项目会运行吗?它会在首次使用doIt时崩溃吗?我必须将哪个版本的Log4j放在类路径上 - v1.2或两者兼而有之?


答案 1

在平面类装入方案中,没有库版本控制支持。您需要使用最新版本的库,并从类路径中删除其他版本。

一些框架,如OSGi,提供了处理这些情况的机制,但目前还不清楚你是否依赖于插件框架。


编辑:

如果Log4j API的某些部分在v1.2中发生了变化(假设一个方法签名发生了变化),并且A和B都调用了,该怎么办?将会发生什么?我的项目会运行吗?它会在首次使用时崩溃吗?doIt()doItdoIt

依赖于不存在的签名的调用可能会导致 .在调用该方法之前,这可能不会发生。如果其他机制依赖于签名(例如.class继承),则可能会发生其他错误。NoSuchMethodError

我必须将哪个版本的Log4j放在类路径上 - v1.2或两者兼而有之?

在类路径上创建两个版本的库只会导致随机加载一组类。该行为将未定义,但可能导致各种令人不快的错误和异常。


答案 2

Java 本身不支持管理同一段代码的多个版本,也就是说,在同一 JVM 中最多只能使用一个版本(使用缺省类装入器)。但是,结帐问题1705720,其中有几个答案指出了实现这一目标的可能方法(OSGi或自定义类装入器)。

但我怀疑这是否值得麻烦,因为您的代码不需要多个log4j版本。在这种情况下,我建议首先使用较新的log4j版本(v1.2),并验证它是否会导致框架A出现任何问题。如果确实导致冲突,请回退到 log4j v1.1 并再次验证。如果你真的不走运,那么你需要把你的手弄脏......

更新:对于您的特定描述,无法使用log4j v1.1或v1.2,因为框架A和B都需要不同的签名。你必须滚动你自己的任何版本的log4j或框架A,或B。


推荐