【问题标题】:Maven: Using inherited property in dependency classifier causes build failureMaven:在依赖分类器中使用继承属性会导致构建失败
【发布时间】:2010-11-13 06:03:58
【问题描述】:

给定三个 POM 文件:

  • C 依赖于 B。
  • B 继承自 A。
  • 我可以构建 A 和 B
  • C 因依赖 B 而无法构建。

下面包含完整的源代码和构建输出供您查看。

这是 A 的 POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.foo</groupId>
    <artifactId>A</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>A</name>
    <repositories>
        <repository>
            <id>foo releases</id>
            <name>libs-releases-local</name>
            <layout>default</layout>
            <url>http://foo.net/artifactory/libs-releases-local</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>org.eclipse.swt</groupId>
            <artifactId>swt</artifactId>
            <classifier>${swt.classifier}</classifier>
            <version>3.6.1</version>
        </dependency>
    </dependencies>
    <profiles>
        <profile>
            <id>windows-x86</id>
            <properties>
                <swt.classifier>win32-x86</swt.classifier>
            </properties>
        </profile>
    </profiles>
</project>

这是 B 的 POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.foo</groupId>
        <artifactId>A</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../A</relativePath>
    </parent>
    <artifactId>B</artifactId>
    <packaging>jar</packaging>
    <name>B</name>
    <profiles>
        <profile>
            <id>windows-x86</id>
            <properties>
                <swt.classifier>win32-x86</swt.classifier>
            </properties>
        </profile>
    </profiles>
</project>

这是 C 的 POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.foo</groupId>
    <artifactId>C</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>C</name>
    <dependencies>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>B</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
</project>

这是来自 C 的构建输出:

------------------------------------------------------------------------
Building C
   task-segment: [install]
------------------------------------------------------------------------
[compiler:compile]
Nothing to compile - all classes are up to date
Downloading: http://foo.net/artifactory/libs-releases-local/org/eclipse/swt/swt/3.6.1/swt-3.6.1-${swt.classifier}.jar
[WARNING] Unable to get resource 'org.eclipse.swt:swt:jar:${swt.classifier}:3.6.1' from repository foo releases (http://foo.net/artifactory/libs-releases-local): Error transferring file: foo.net
Downloading: http://repo1.maven.org/maven2/org/eclipse/swt/swt/3.6.1/swt-3.6.1-${swt.classifier}.jar
Unable to find resource 'org.eclipse.swt:swt:jar:${swt.classifier}:3.6.1' in repository central (http://repo1.maven.org/maven2)
------------------------------------------------------------------------
[ERROR]BUILD ERROR
------------------------------------------------------------------------
Failed to resolve artifact.

Missing:
----------
1) org.eclipse.swt:swt:jar:${swt.classifier}:3.6.1

我知道这个问题与https://issues.apache.org/jira/browse/MNG-3228 有关,但我不确定如何解决它。请帮忙!

更新

向 B 添加分类器有帮助。现在只要存储库只包含 B 的 jar 文件,C 就会构建。如果我将 B 的 POM 文件与存储库中的 JAR 一起上传,C 将失败并出现上述错误(${swt.classifier} 未定义)。有什么想法吗?

【问题讨论】:

    标签: maven-2 inheritance profiles


    【解决方案1】:

    在您写的评论中,“我期望 SWT 的分类器在 B 的构建时得到解决,而不是 C 的构建时”,但这是错误的 - 您需要在 C 的构建时使用分类器,因为 C 依赖于swt(通过 A 传递)。该依赖项仅由属性完全确定,因此您必须有一种方法来评估 C 的 pom 中的属性。

    • A 依赖于 swt-${classifier}
    • C 依赖于 A
    • 因此 C 依赖于 swt-${classifier}
    • 因此 C 的 pom 必须定义属性。它可以由配置文件定义(如在 A 中),或在运行时手动定义(不利于重现性),但没有它就无法构建 C。

    就这么简单(而且令人费解)。

    如果您期望该属性在此过程中以某种方式得到完全“解析”,并且在您构建 C 时已经明确定义,那么您并不了解 Maven 如何处理这些属性。它让他们独自一人。曾尝试在 Maven 2.1 中做一些不同的事情(当您安装 A 时,分类器属性表达式将转换为它的值),但它没有成功,导致许多令人惊讶的行为,它在 2.2 中恢复,实际上导致2.1 将被迅速弃用。有关更多详细信息以及有关问题的复杂程度的一些提示,请参阅下面的链接。

    https://cwiki.apache.org/confluence/display/MAVENOLD/Artifact-Coordinate+Expression+Transformation

    在 Maven 开发人员另有决定之前,我认为我们将继续保持自 2.0 以来一直存在的行为:“工件坐标中的表达式被忽略。用户有很多绳子可以用来吊死自己”

    不过,一旦你习惯了它,它就不再令人困惑了。只有当你试图猜测 Maven 时,你才会感到惊讶。

    【讨论】:

    • 我了解需要覆盖依赖版本/分类器,但完全删除默认/父值会使子 POM 更难维护并导致重复。
    • 我尝试在 C 中定义 ${swt.classifier} 但 Maven 仍然抱怨它无法解析该属性。有什么想法吗?
    • 我不明白为什么如果您定义了属性,Maven 将无法解析它。你得到同样的错误?你确定你已经定义了吗? help:effective-pom 向您展示了什么?
    • 此处提供的链接不再有效:这是一个有效的cwiki.apache.org/confluence/display/MAVENOLD/…
    【解决方案2】:

    Maven 正在尝试查找工件 org.eclipse.swt:swt:3.6.1,但无法正确解析坐标。错误是说 ${swt.classifier} 没有被 POM.xml 中的 &lt;properties/&gt; 块识别。由于该值显示在 &lt;profile/&gt; 块中,您能否验证您正在运行的 Maven 命令?

    试试这个:mvn dependency:resolve -P windows-x86

    另外,验证 SWT 的版本和分类器实际上是正确的。我在Maven Central上看到的最新版本不是3.6.0,而是3.3.0-v3346

    【讨论】:

    • 帕斯卡是对的。 C 没有个人资料。关于 SWT,有问题的工件存在于我的私有存储库中,所以这不是问题(否则 B 将无法正确构建)。
    【解决方案3】:

    这在 Maven 3.1.0 中是不可能的。以下是相关功能请求:https://issues.apache.org/jira/browse/MNG-1388

    【讨论】:

      【解决方案4】:

      我知道这个问题与https://issues.apache.org/jira/browse/MNG-3228 有关,但我不确定如何解决。

      我不确定是否存在与此问题相关的链接,我在上面显示的 pom.xml 中没有看到与配置文件激活相关的任何内容。

      实际上,我什至不确定是否理解预期的结果。分类器应该从哪里来?也许我遗漏了一些部分,但我认为您应该安装/部署 B 的合格版本(具有完全解析的 POM)并让 C 依赖于这个合格的版本。

      我需要如何修改 B 的 POM 才能部署合格的版本?我希望 SWT 的分类器在 B 的构建时得到解决,而不是 C 的构建时。

      是的,但是在 C 的构建时,C 需要 B B 的依赖项,因此必须完全解决 B 的已安装/部署的 .pom。至少,我认为事情是这样运作的。

      但我必须承认,我不确定如何准确处理这种情况,在阅读了诸如 MNG-4140Artifact-Coordinate Expression Transformation 页面之类的问题后,我完全糊涂了。

      我建议以 正确 方式将其发布到 maven 用户列表上(我将密切关注该线程,因为我认为我现在使用配置文件、属性和依赖项修复了一些损坏的 POM ,谢谢:)

      【讨论】:

      • 我需要如何修改 B 的 POM 才能部署合格的版本?我期待 SWT 的分类器在 B 的构建时得到解决,而不是 C 的构建时。
      • 我已经为 B 添加了一个分类器。如果存储库只包含 B 的 jar 文件,那么 C 将构建。如果存储库还包含 B 的 POM 文件,则 C 的构建将失败,并且 ${swt.classifier} 未定义。有什么想法吗?
      • @Gili: If the repository only contains B's jar file then C will build 是的,但它不会得到传递依赖。不好。 If the repository also contains B's POM file, C's build will fail with ${swt.classifier} undefined 这是问题的核心。 Any ideas? 不,对不起,这就是我建议发布到 maven 用户列表的原因。
      猜你喜欢
      • 2018-09-18
      • 2019-10-10
      • 2013-04-01
      • 1970-01-01
      • 2021-02-12
      • 2011-05-29
      • 2013-04-01
      • 2015-06-23
      • 2017-08-14
      相关资源
      最近更新 更多