【问题标题】:Maven 2 - define dependency version from transitive dependency versionMaven 2 - 从传递依赖版本定义依赖版本
【发布时间】:2013-02-13 19:16:48
【问题描述】:

我会用我的实际情况来解释这个问题。

我使用 logback 1.0.1 进行日志记录,它包含 SLF4J 1.6.4 作为依赖项。我还将 SLF4J API 桥用于遗留日志 API(java.util.logging、log4j 和 commons-logging),它们不是显式依赖项。这些也必须(最好)是 1.6.4 版本。

为了使我的 pom.xml 尽可能整洁和无错误,我想强制这些 API 桥与 SLF4J 的版本相同。我知道的唯一方法是使用 1.6.4 版在我的 pom.xml 中手动将它们定义为依赖项。如果我更新了 logback 并提高了所需的 SLF4J 版本,我需要记住将桥 API 更改为正确的版本。

我能否以某种方式将遗留 API 的版本与传递依赖项 SLF4J 的版本挂钩?

当前 pom.xml:

    <properties>
    <org.slf4j.version>1.6.4</org.slf4j.version>
</properties>

<dependencies>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.0.1</version>
        <!-- requires SLF4J 1.6.4 -->
    </dependency>
    <!-- ... -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>log4j-over-slf4j</artifactId>
        <version>${org.slf4j.version}</version>
        <!-- here, how to bind this version value to SLF4J's version? -->
        <scope>runtime</scope>
    </dependency>
    <!-- the other two bridge API's go here -->
</dependencies>

【问题讨论】:

标签: java maven maven-2 dependency-management


【解决方案1】:

不是很漂亮:/

有 maven enforcer 插件:http://maven.apache.org/enforcer/enforcer-rules/

所以你可以禁止传递依赖并包含你想要的版本:http://maven.apache.org/enforcer/enforcer-rules/bannedDependencies.html

如果您使用好版本的属性,则不需要在强制插件版本中乱来。

【讨论】:

  • 我查看了执行器,但这并不是我真正需要的。如果我只是在我的 pom 中定义 SLF4J,我会得到相同的结果。它可以工作,但不能通过 logback 升级“自动”,我也需要更改 SLF4J 版本。实用,但不是一种漂亮的方式... ;-)
  • 杰普!问题是这不会阻止人们通过直接添加传递依赖项来更改它们的版本。如果你禁止那些你肯定没有人能够做到这一点。但这可能不是问题:)
【解决方案2】:

Dependency Convergence 可以帮助你。谢谢@wemu!

我有一个same? problem

你可以克隆https://gist.github.com/f35db1ac6dc8b6f45393.git

<dependencies>
  <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.1.3</version>
    <scope>runtime</scope> <!-- depends on slf4j-api:1.7.7 -->
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
    <version>${unified.slf4j-api.version}</version>
    <scope>runtime</scope>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${unified.slf4j-api.version}</version>
  </dependency>
</dependencies>
<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <unified.slf4j-api.version>1.7.7</unified.slf4j-api.version>
</properties>
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-enforcer-plugin</artifactId>
       <version>1.4.1</version>
       <executions>
         <execution>
           <id>enforce</id>
           <configuration>
             <rules>
               <dependencyConvergence/>
             </rules>
           </configuration>
           <goals>
             <goal>enforce</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
  </plugins>
</build>

此时,一切正常。

$ mvn -Dverbose=true dependency:tree verify
...
[INFO] test:enforcer-dependency-convergence-test:jar:0.1-SNAPSHOT
[INFO] +- ch.qos.logback:logback-classic:jar:1.1.3:runtime
[INFO] |  +- ch.qos.logback:logback-core:jar:1.1.3:runtime
[INFO] |  \- (org.slf4j:slf4j-api:jar:1.7.7:runtime - omitted for duplicate)
[INFO] +- org.slf4j:log4j-over-slf4j:jar:1.7.7:runtime
[INFO] |  \- (org.slf4j:slf4j-api:jar:1.7.7:runtime - omitted for duplicate)
[INFO] \- org.slf4j:slf4j-api:jar:1.7.7:compile
[INFO]
[INFO] --- maven-enforcer-plugin:1.4.1:enforce (default) @ enforcer-dependency-convergence-test ---
[INFO]
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
...

$

现在让我们更改slf4j-api 的版本。

$ mvn -Dunified.slf4j-api.version=1.7.13 -Dverbose=true dependency:tree verify
...
[INFO] test:enforcer-dependency-convergence-test:jar:0.1-SNAPSHOT
[INFO] test:enforcer-dependency-convergence-test:jar:0.1-SNAPSHOT
[INFO] +- ch.qos.logback:logback-classic:jar:1.1.3:runtime
[INFO] |  +- ch.qos.logback:logback-core:jar:1.1.3:runtime
[INFO] |  \- (org.slf4j:slf4j-api:jar:1.7.7:runtime - omitted for conflict with 1.7.13)
[INFO] +- org.slf4j:log4j-over-slf4j:jar:1.7.13:runtime
[INFO] |  \- (org.slf4j:slf4j-api:jar:1.7.13:runtime - omitted for conflict with 1.7.7)
[INFO] \- org.slf4j:slf4j-api:jar:1.7.13:compile
[INFO]
[INFO] --- maven-enforcer-plugin:1.4.1:enforce (default) @ enforcer-dependency-convergence-test ---
[WARNING]
Dependency convergence error for org.slf4j:slf4j-api:1.7.7 paths to dependency are:
+-test:enforcer-dependency-convergence-test:0.1-SNAPSHOT
  +-ch.qos.logback:logback-classic:1.1.3
    +-org.slf4j:slf4j-api:1.7.7
and
+-test:enforcer-dependency-convergence-test:0.1-SNAPSHOT
  +-org.slf4j:log4j-over-slf4j:1.7.13
    +-org.slf4j:slf4j-api:1.7.13
and
+-test:enforcer-dependency-convergence-test:0.1-SNAPSHOT
  +-org.slf4j:slf4j-api:1.7.13

[WARNING] Rule 0: org.apache.maven.plugins.enforcer.DependencyConvergence failed with message:
Failed while enforcing releasability the error(s) are [
Dependency convergence error for org.slf4j:slf4j-api:1.7.7 paths to dependency are:
+-test:enforcer-dependency-convergence-test:0.1-SNAPSHOT
  +-ch.qos.logback:logback-classic:1.1.3
    +-org.slf4j:slf4j-api:1.7.7
and
+-test:enforcer-dependency-convergence-test:0.1-SNAPSHOT
  +-org.slf4j:log4j-over-slf4j:1.7.13
    +-org.slf4j:slf4j-api:1.7.13
and
+-test:enforcer-dependency-convergence-test:0.1-SNAPSHOT
  +-org.slf4j:slf4j-api:1.7.13
]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
...

$

【讨论】:

    【解决方案3】:

    只是不要直接依赖顶级 pom 中的 slf4j。

    【讨论】:

    • 我需要桥接 API,我可以直接或不依赖 SLF4J,但版本不匹配的可能性仍然存在,因为我需要手动定义两个版本。如果捆绑两个版本/库根本无法完成,因为到目前为止没有人编写过这样的代码,所以我将不得不处理它。
    猜你喜欢
    • 2016-09-18
    • 2020-07-26
    • 2019-01-24
    • 2011-12-22
    • 2020-06-24
    • 2015-04-03
    • 2019-12-25
    • 1970-01-01
    相关资源
    最近更新 更多