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

Wil*_*zyr 13 java dependencies frameworks jar

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

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

更新: 更具体...... 如果在v1.2中更改了Log4j API的某些部分(假设一个方法doIt()签名已更改),并且A和B都调用了doIt.会发生什么?我的项目会运行吗?首次使用doIt会崩溃吗?我必须在classpath-v1.2或两者上放置什么版本的Log4j?

McD*_*ell 11

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

某些框架(如OSGi)提供了处理这些情况的机制,但您不清楚是否依赖于插件框架.


编辑:

如果Log4j的API的某些部分在V1.2改变(比方说一个单一的方法doIt()签名改变),A和B的呼叫doIt.会发生什么?我的项目会运行吗?它会在第一次使用时崩溃doIt吗?

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

我必须在classpath-v1.2或两者上放置什么版本的Log4j?

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


bry*_*sai 3

Java本身并不支持管理同一段代码的多个版本,也就是说,在同一个 JVM 中(使用默认的类加载器)最多只能使用一个版本。然而,请查看问题1705720,其中有几个答案,指出了实现这一目标的可能方法(OSGi 或自定义类加载器)。

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

更新:对于您的具体描述,无法使用 log4j v1.1 或 v1.2,因为框架 A 和 B 各自需要不同的签名。您必须推出自己的 log4j 或框架 A 或 B 版本。

  • 假设您按顺序将 log4j-1.1.jar;log4j-1.2.jar 放入类路径中,则将使用 log4j-1.1.jar 中的类(版本)。只要找到一个类,搜索就会停止。因此,由于使用了 v1.1,任何期望 log4j v1.2 签名的代码都会有问题(找不到方法)。 (2认同)