java - Maven 依赖管理在测试时被忽略(在运行时工作)

标签 java maven dependency-management transitive-dependency

我有两个依赖项,它们指向 javax.validation:validation-api 的冲突版本。为了解决这个问题,我添加了一个 dependencyManagement 部分,其中包含最新版本的 validation-api

虽然这会导致应用程序正确构建,并且应用程序在运行时工作,但在测试期间,构建会在引用验证 api 的行处中断(通过 @Valid 注释)。

冲突的依赖关系是:

<dependency>
  <groupId>io.dropwizard</groupId>
  <artifactId>dropwizard-core</artifactId>
  <version>0.9.2</version>
</dependency>

<dependency>
  <groupId>com.google.gwt</groupId>
  <artifactId>gwt-user</artifactId>
  <version>2.8.0-beta1</version>
  <scope>provided</scope>
</dependency>

我添加了以下dependencyManagement:

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>

这在运行时和编译时有效,但在我引用 @Valid 的测试中失败。

非常感谢任何帮助,因为这让我发疯。

最佳答案

可能的故障排除路径位于为 provided 定义的范围 ( gwt-user ) 上,这是唯一引入 validation-api 的库应用上面的依赖关系管理。

运行以下命令,首先省略 dropwizard-core

mvn dependency:tree -Dincludes=javax.validation

输出将是:

[INFO] +- com.google.gwt:gwt-user:jar:2.8.0-beta1:provided  
[INFO] |  +- javax.validation:validation-api:jar:1.1.0.Final:compile  
[INFO] |  \- javax.validation:validation-api:jar:sources:1.0.0.GA:provided  

因此采用所需的 1.1.0.Final 版本,而不是可传递的 1.0.0.GA 版本。
(请注意上面的范围,每个依赖项的最后一个标记,它们都应该位于 provided 上,因为它的根 gwt-user 位于 provided 范围内。但是,由于依赖项管理,validation-api 位于 compile 上条目)。

同时省略gwt-user输出将是:

[INFO] com.sample:sample2:jar:0.0.1-SNAPSHOT
[INFO] \- io.dropwizard:dropwizard-core:jar:0.9.2:compile
[INFO]    \- io.dropwizard:dropwizard-validation:jar:0.9.2:compile
[INFO]       \- org.hibernate:hibernate-validator:jar:5.2.2.Final:compile
[INFO]          \- javax.validation:validation-api:jar:1.1.0.Final:compile

因此,确实,两者都会将其引入,但第一个被定义为 provided范围,而第二个范围为默认范围 ( compile )。

此外,validation-api的依赖管理已为默认( compile )范围定义,影响 Maven 如何通过 gwt-user 引入它(上面列出,如 compile ,即使 gwt-userprovided 并且其所有传递依赖项也将在 provided 上,除非依赖项管理以不同的方式定义,就像在本例中一样)。

根据official Maven documentation提供的依赖项是

available on the compilation and test classpath

因此,您在编译和测试过程中同时拥有两个库,validation-apigwt-user ,然后在运行时会有不同的耦合( gwt-user 预计由运行时容器提供)。

如果gwt-user必须位于 provided范围,我建议采取更精细的治理并排除 validation-api直接来自gwt-user 。因此,validation-api将从 dropwizard-core 引入具有依赖管理所需的版本。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>io.dropwizard</groupId>
        <artifactId>dropwizard-core</artifactId>
        <version>0.9.2</version>
    </dependency>
    <dependency>
        <groupId>com.google.gwt</groupId>
        <artifactId>gwt-user</artifactId>
        <version>2.8.0-beta1</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

更新
从下面的评论中可以看出,您还使用以下内容作为依赖项管理的一部分:

<dependency>
    <groupId>com.google.gwt</groupId>
    <artifactId>gwt</artifactId>
    <version>2.8.0-beta1</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

然后还在其依赖项管理中指定以下内容:

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.0.0.GA</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.0.0.GA</version>
    <!-- Note: use classifier=sources rather than type=java-sources so they're added to the classpath -->
    <classifier>sources</classifier>
</dependency>

虽然您设法覆盖第一个,但您没有覆盖第二个,实际上它仍然添加到类路径中(检查上面的依赖关系树输出,1.0.0.GA源仍然是在提供的范围内引入。这是编译器/测试和运行时之间的进一步区别。在运行时,您不会将其作为类路径的一部分。

因此,我建议将其1.1.0.Final版本添加到您的依赖项管理中作为覆盖,以便它与第一个版本保持一致。

关于java - Maven 依赖管理在测试时被忽略(在运行时工作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36568756/

相关文章:

java - java中的URLClassLoader

java - 打开其中一个解决项目时,Eclipse中的“解决工作空间 Artifact ”选项会生成错误

java - 如何从命令行运行这个 Maven 插件任务?

java - 无法使用 URL 协议(protocol)处理程序从 HDFS 获取数据

C++运算符的多重定义>>

git - CocoaPods 是如何工作的

java - Java 中的 TensorFlow 服务 - 在一个 session 运行中进行多个预测

java - 为什么接口(interface)中不包含同步方法

java - 如果我们有多个 session 对象,一级缓存如何工作?

Pig UDF 中的 Java 依赖项