Maven:在依赖项分类器中使用继承的属性会导致构建失败

发布于 2024-10-01 17:28:46 字数 4818 浏览 2 评论 0原文

给定三个 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} 未定义)。有什么想法吗?

Given three POM files:

  • C depends on B.
  • B inherits from A.
  • I can build A and B
  • C fails to build because of its dependency on B.

The full source-code and build output is included below for your review.

Here is A's 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>

Here is B's 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>

Here is C's 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>

Here is the build output from 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

I know this issue is related to https://issues.apache.org/jira/browse/MNG-3228 but I'm not sure how to fix it. Please help!

UPDATE:

Adding a classifier to B helped. Now C builds so long as the repository only contains B's jar file. If I upload B's POM file alongside the JAR in the repository, C fails with the aforementioned error (${swt.classifier} not defined). Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

焚却相思 2024-10-08 17:28:46

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

  • 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-Cooperative+Expression+Transformation

在 Maven 开发人员做出其他决定之前,我认为我们将继续拥有自 2.0 以来一直存在的行为:“工件坐标中的表达式被忽略。用户有足够的绳索 然而,一旦你习惯了它

,它就不再令人困惑了。只有当您试图对 Maven 进行事后猜测时,您才会感到惊讶。

In a comment you write, "I am expecting SWT's classifier to get resolved at B's build-time, not C's build-time", but that is wrong - you need the classifier at C's build time because C has a dependency on swt (transitive via A). That dependency is only fully-determined by a property, so you have to have a way of evaluating the property in C's pom.

  • A depends on swt-${classifier}
  • C depends on A
  • therefore C depends on swt-${classifier}
  • therefore C's pom must define the property. It can be defined by a profile (as in A), or manually at runtime (bad for reproducibility), but you can't build C without it.

It's as simple (and puzzling) as that.

If you're expecting the property to somehow get fully "resolved" along the way, and be already well-defined by the time you build C, you are not understanding how Maven treats those properties. It leaves them alone. There was an attempt to do some different stuff in Maven 2.1 (the classifier property expression would be transformed to its value when you installed A), but it was not successful, caused many surprising behaviours, it was reverted for 2.2, and in fact caused 2.1 to be quickly deprecated. For more details, and some hints as to how complicated the problem really is, see the link below.

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

Until the Maven developers decide otherwise, I think we will continue to have the behaviour that has been around since 2.0: "Expressions in artifact coordinates are ignored. Users have plenty of rope with which to hang themselves"

Once you get used to it, though, it's not confusing anymore. It's only when you're trying to second-guess Maven that you get surprised.

故事灯 2024-10-08 17:28:46

Maven 正在尝试查找工件 org.eclipse.swt:swt:3.6.1 但坐标未正确解析。该错误表明 POM.xml 中的 块无法识别 ${swt.classifier} 。由于该值显示在 块中,您可以验证您正在运行的 Maven 命令吗?

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

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

Maven is trying to find the artifact org.eclipse.swt:swt:3.6.1 but the coordinates aren't being resolved correctly. The error is saying that ${swt.classifier} isn't being recognized from a <properties/> block in your POM.xml. Since that value shows up in a <profile/> block, can you verify what Maven command you are running?

Try this: mvn dependency:resolve -P windows-x86

Also, verify that both the version of SWT and the Classifier are actually correct. The latest version I see on Maven Central is not 3.6.0, but 3.3.0-v3346

心房敞 2024-10-08 17:28:46

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

This isn't possible as of Maven 3.1.0. Here is the relevant feature request: https://issues.apache.org/jira/browse/MNG-1388

雨后咖啡店 2024-10-08 17:28:46

我知道此问题与 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- 之类的问题后第 4140 章页面,我完全困惑了。

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

I know this issue is related to https://issues.apache.org/jira/browse/MNG-3228 but I'm not sure how to fix it.

I'm not sure there is a link with this issue, I don't see anything related to profile activation in the pom.xml shown above.

Actually, I'm not even sure to understand the expected result. From where is the classifier supposed to come? Maybe I'm missing some parts but I think you should install/deploy a qualified version of B (with a fully resolved POM) and have C depend on this qualified version.

How would I need to modify B's POM to deploy a qualified version? I am expecting SWT's classifier to get resolved at B's build-time, not C's build-time.

Yes but at C's build-time, C needs B and B's dependencies so the installed/deployed .pom of B has to be fully resolved. At least, that's how I think things can work.

But I must admit I'm not sure how to handle this case exactly and after reading issues like MNG-4140 or the Artifact-Coordinate Expression Transformation page, I'm totally confused.

I suggest to post this on the maven users list for the right way (and I'll follow the thread closely because I think I have some broken POMs using profiles, properties and dependencies to fix now, thanks :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文