【问题标题】:why is "test-jar" dependency required for "mvn compile"为什么“mvn compile”需要“test-jar”依赖
【发布时间】:2023-03-18 04:22:01
【问题描述】:

我在多模块项目中使用 test-jar 依赖项时遇到问题。例如,当我这样声明cleartk-syntax 模块依赖于cleartk-token 模块的test-jar 时(完整代码为here):

<modelVersion>4.0.0</modelVersion>
<groupId>org.cleartk</groupId>
<artifactId>cleartk-syntax</artifactId>
<version>0.5.0-SNAPSHOT</version>
<name>cleartk-syntax</name>
...
<dependencies>
    ...
    <dependency>
        <groupId>org.cleartk</groupId>
        <artifactId>cleartk-token</artifactId>
        <version>0.7.0-SNAPSHOT</version>
        <type>test-jar</type>
        <scope>test</scope>
    </dependency>

如果我使用 maven 2 运行 mvn compile,我会收到以下错误:

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) org.cleartk:cleartk-token:test-jar:tests:0.7.0-SNAPSHOT

如果我使用 maven 3,我会收到错误:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.654s
[INFO] Finished at: Mon Jan 24 21:19:17 CET 2011
[INFO] Final Memory: 16M/81M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project cleartk-syntax: Could not resolve
dependencies for project org.cleartk:cleartk-syntax:jar:0.5.0-SNAPSHOT: Could
not find artifact org.cleartk:cleartk-token:jar:tests:0.7.0-SNAPSHOT

在后一种情况下,我特别困惑,因为我认为它应该寻找 test-jar 类型的工件,而不是 jar 类型的工件。

使用 maven 2 或 maven 3,我可以通过运行 mvn compile package -DskipTests 来编译它。使用 maven 3,我还可以通过运行 mvn compile test-compile 来编译它。

但是为什么 maven 2 或 maven 3 在 compile 阶段寻找 test-jar 依赖?难道不应该等到test-compile阶段才去寻找这样的依赖吗?

更新:答案是在我的编译阶段使用的 maven-exec-plugin,requires dependency resolution of artifacts in scope:test。我创建了a feature request to remove the scope:test dependency

【问题讨论】:

    标签: java maven-2 maven-3


    【解决方案1】:

    在我的情况下,根本原因是应该在test 范围内用作test-jar 类型的依赖项的模块不包括所需的maven-jar-plugin 配置。如果没有下面的 sn-p,当您在相应模块上调用 mvn deploy 时,将不会部署任何测试 jar。

    <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>test-jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
    

    更多详情请见https://maven.apache.org/guides/mini/guide-attached-tests.html

    【讨论】:

    • 这也是我的根本原因。
    【解决方案2】:

    在我看来,这确实是一个错误。

    我有同样的问题并测试了 Maven 3.0.1 和 3.0.2。验证不会失败,只有编译步骤失败。使用 Maven 3 mvn compile 中断,但 mvn test-compile 有效。

    似乎编译阶段在反应堆中寻找测试罐工件,然后在 repo 中寻找,但它不应该因为依赖项在测试范围内。测试范围工件应该在测试编译期间解决,而不是编译。

    因此,我认为这可以通过将 maven-compiler-plugin 的 testCompile 目标映射到编译阶段而不是默认的测试编译阶段来解决。

    我将此添加到我的 pom 中,就在上游 pom 中添加 test-jar 创建的部分旁边:

      <!-- there is a bug in maven causing it to resolve test-jar types
           at compile time rather than test-compile. Move the compilation 
           of the test classes earlier in the build cycle -->
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <executions>
          <execution>
            <id>default-testCompile</id>
            <phase>compile</phase>
            <goals>
              <goal>testCompile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    

    但这也行不通,因为 compile 和 test-compile 之间的五个阶段还没有运行并设置诸如测试类路径之类的东西。

    我想在修复此错误之前,真正的解决方法是使用 test-compile 代替 compile

    【讨论】:

    • 我已经确认第一个工作的 maven 阶段是测试编译。流程测试资源失败。
    • 很高兴听到我不是唯一一个遇到这个错误的人。在您的情况下,您是否也在使用 exec:java 插件 - 这对我来说似乎是问题的一部分。如果没有,您是否将任何其他插件绑定到执行阶段?
    • 我最近发现但尚未解开的是,我可以通过非常减少的 3 个 pom 文件集引起问题。如果这三个(我的项目)从无继承,它就可以工作。如果他们从 org.apache:apache 继承,它就会中断。因此,其中定义的插件之一可能会破坏它。那里没有 exec:java 插件——但这些插件之一和 exec 可能依赖于上游其他损坏的东西。如果可以缩小范围,我会在这里发表评论。
    • 就我而言,问题出在 maven-remote-resources 中。我提交了jira.codehaus.org/browse/MRRESOURCES-53。如果其他人有这个问题并且不是由于 exec:java,可能是它。
    • 我也遇到了这个问题。这为我解决了:*.com/questions/14722873/…
    【解决方案3】:

    所以我做了一些认真的调试,发现问题似乎是exec:java插件、test-jar依赖项和mvn compile之间的交互。

    简而言之,如果将exec:java 附加到执行阶段,mvn compile 会在编译时开始寻找test-jar 依赖项。如果您从 exec:java 插件声明中删除 &lt;executions&gt; 元素,mvn compile 将再次正常工作。

    我在这里为exec:java 插件提交了一个错误报告,虽然我无法确定该错误是在exec:javatest-jar 还是mvn compile,所以如果/当有人发现时:

    http://jira.codehaus.org/browse/MEXEC-91

    更新:这不是一个真正的错误,maven-exec-plugin 被记录为需要测试依赖项:

    http://mojo.codehaus.org/exec-maven-plugin/java-mojo.html

    这并不意味着它不会成为一个很棒的功能。 ;-)

    【讨论】:

      【解决方案4】:

      我正在使用 maven2。我想答案在 Maven 生命周期管理中。 默认生命周期的第一步是验证,它确实“验证项目是否正确并且所有必要的信息都可用”。 (见http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)。

      所以 maven 只是尽力获取所有需要的依赖项以供以后执行。

      【讨论】:

      • 但如果是这样,那mvn compile package为什么会起作用?
      • 你提到它只有在你提供 -DskipTests=true 变量时才有效。这可能是maven的内部优化吗?
      • 它也可以在没有 -DskipTests 的情况下工作。我只是补充说,因为我只是想编译,而不是测试。