通过库本身强制库的传递 Maven 依赖项的版本

问题描述 投票:0回答:1

我熟悉 Maven 项目(例如

my-app
)如何强制传递依赖项的版本。今天我偶然发现了一个相关问题:库
my-lib
如何强制其与
my-app
相关的传递依赖项的版本而不直接包含传递依赖项?

我有一个库

my-lib
,其唯一目的是让其他项目可以轻松地同时包含多个传递依赖项 - 换句话说,
my-lib
有点像捆绑机制。在
my-lib/pom.xml
我正式声明
com.amazonaws:aws-lambda-java-log4j2:1.5.1
然后使用它:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-log4j2</artifactId>
      <version>1.5.1</version>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-log4j2</artifactId>
  </dependency>
</dependencies>

但是我想覆盖正在使用的 Log4j 版本,因此在

my-lib-parent
中我导入了特定的 Log4j BOM 版本:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-bom</artifactId>
      <version>2.20.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
<dependencyManagement>

果然,如果我在

mvn dependency:tree
上做一个
my-lib
,就表明正在使用Log4j 2.20.0:

[INFO] +- com.amazonaws:aws-lambda-java-log4j2:jar:1.5.1:compile
[INFO] |  +- org.apache.logging.log4j:log4j-core:jar:2.20.0:compile
[INFO] |  \- org.apache.logging.log4j:log4j-api:jar:2.20.0:compile

所以我很高兴地将

my-lib
添加为
my-app
的依赖项。 (请注意,我用
my-lib
指定
<scope>provided</scope>
;我不知道这是否对这个特定问题有影响。我已配置我的 Maven 程序集描述符以创建一个 ZIP 文件,即使使用带有
<scope>provided</scope>
的库也是如此。 )当我的代码尝试记录信息时,我得到了
java.lang.NoClassDefFoundError: org/apache/logging/log4j/BridgeAware
。事实证明,即使
my-lib
项目正在使用
org.apache.logging.log4j:log4j-core:jar:2.20.0
,但这也仅与
my-lib
本身相关——就
my-lib 而言,它不会影响 
my-app
 引入的传递依赖项的版本
,当
my-app
包含
my-lib
作为依赖项时!

因此,如果我在

mvn dependency:tree
上执行
my-app
,则表明正在使用
org.apache.logging.log4j:log4j-api:jar:2.17.1

[INFO] |  +- com.amazonaws:aws-lambda-java-log4j2:jar:1.5.1:provided
[INFO] |  |  +- org.apache.logging.log4j:log4j-core:jar:2.17.1:provided
[INFO] |  |  \- org.apache.logging.log4j:log4j-api:jar:2.17.1:provided

我想这是有道理的,但坦白说我从来没有想过太多。我刚刚假设

my-app
将获得由
my-lib
中的依赖管理设置的传递依赖项的版本。

我注意到

org.apache.logging.log4j:log4j-slf4j2-impl:jar:2.20.0
my-app
中获得了正确的版本,它也通过 Log4j BOM 进入
my-lib
,但这似乎是因为
my-lib
明确包含
org.apache.logging.log4j:log4j-slf4j2-impl:jar:2.20.0
作为其直接依赖项。

这就是唯一的解决方案:如果我希望当

com.amazonaws:aws-lambda-java-log4j2
包含在另一个版本中时将它们设置为另一个版本,我是否被迫去查找并枚举
my-lib
的所有传递依赖项并在
my-lib
中显式声明它们项目?是否有一种更简单的方法,类似于导入 BOM,允许
my-lib
简单地说“当
my-lib
包含在另一个项目中时,强制所有传递 Log4j 版本为 Log4j BOM 的版本”?

java maven log4j dependency-management maven-bom
1个回答
0
投票

我过去也偶然发现了这个问题:DependencyManagement 是不可传递的。

您可以通过使用扁平Maven插件来生成“消费者pom”来避免该问题。

© www.soinside.com 2019 - 2024. All rights reserved.