有没有办法使用 Maven 来引用依赖项或 artifactItem 中的特定元素?

Is there a way to refer, with Maven, specific elements within a dependency or artifactItem?

目前,我有一个 pom.xml,它在构建时从 mvnrepository 收集依赖 Javadoc jar 并将它们解压缩到特定文件夹中:

    <build>
        <finalName>${parent.artifactId}</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>unpack-javadoc-jars</id>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <artifactItems>
                        <artifactItem>
                            <groupId>groupid1</groupId>
                            <artifactId>artifactid1</artifactId>
                            <version>1.0.0</version>
                            <classifier>javadoc</classifier>
                            <outputDirectory>${project.build.directory}/dependency-javadoc/artifactid1-1.0.0</outputDirectory>
                        </artifactItem>
                        <artifactItem>
                            <groupId>groupid2</groupId>
                            <artifactId>artifactid2</artifactId>
                            <version>2.0.0</version>
                            <classifier>javadoc</classifier>
                            <outputDirectory>${project.build.directory}/dependency-javadoc/artifactid2-2.0.0</outputDirectory>
                        </artifactItem>
    ...
                        </artifactItems>
                </configuration>
            </plugin>
        </plugins>
    </build>

问题是,如果我没有为每个工件指定输出目录字段,javadoc 将全部解压到一个文件夹中(也可以为解压目标配置 - https://maven.apache.org/plugins-archives/maven-dependency-plugin-2.6/unpack-mojo.html),我想要它们在文件夹中结构清晰。所以我为每个 artifactItem 添加了一个目录条目。但是,我必须手动编写文件夹名称。有没有一种方法可以引用现有的 artifactItem 的字段,方式类似于:

                        <artifactItem>
                            <groupId>groupid1</groupId>
                            <artifactId>artifactid1</artifactId>
                            <version>1.0.0</version>
                            <classifier>javadoc</classifier>
                            <outputDirectory>${project.build.directory}/dependency-javadoc/${artifactItem.artifactId}-${artifactItem.version}</outputDirectory>
                        </artifactItem>

这样,我将能够 copy/paste 所有 javadoc 工件条目中的 outputDirectory,但它是相同的。 谢谢!

这是一个有趣的问题。我记得过去曾有过使用 POM 声明作为同一 POM 中的属性的要求,但我当时对这些值进行了硬编码,因为它们只有几个。但是,我认为我们在这里不走运。至少我首先想到的方法是:

编写一个 Maven 插件,例如 POM Strings Maven 插件(事实上,我在这里是为了我的想法的 POC),目标是:

pom-strings:toProperties -Dxpath=//artifactItems/*/text()[normalize-space()]

它在 POM 中找到所有 XML 文本节点(在你的情况下在 <artifactItems> 下),然后找到它们的完整 XML 树路径并为它们创建 Maven 项目属性喜欢:

/project/build/plugins/plugin/configuration/artifactItems/artifactItem/artifactId=...
/project/build/plugins/plugin/configuration/artifactItems/artifactItem/version=...

在例如声明其执行之后在项目的 initialize 阶段,您的声明将如下所示(带有换行符以便于阅读):

<outputDirectory>
${project.build.directory}/dependency-javadoc/
${/project/build/plugins/plugin/configuration/artifactItems/artifactItem/artifactId}
-
${/project/build/plugins/plugin/configuration/artifactItems/artifactItem/version}
</outputDirectory>

然而,问题是这个不起眼的、无辜的“...”,因为在这种情况下完整路径不是唯一的。它们中的每一个都有两个可能的值。要解决此问题,必须引入一个键(通过找到第一个唯一的父级),以便属性看起来像:

/project/build/plugins/plugin/configuration/artifactItems[<key1>]/artifactId=artifactid1
/project/build/plugins/plugin/configuration/artifactItems[<key1>]/version=1.0.0
/project/build/plugins/plugin/configuration/artifactItems[<key2>]/artifactId=artifactid2
/project/build/plugins/plugin/configuration/artifactItems[<key2>]/version=2.0.0

如果这个键是一个数字索引,声明顺序将是至关重要的,这与 POM 的声明性质相矛盾,因此它不是好的,而是坏的和丑陋的[1]:

/.../artifactItems[0]/artifactId=artifactid1
/.../artifactItems[0]/version=1.0.0
/.../artifactItems[1]/artifactId=artifactid2
/.../artifactItems[1]/version=2.0.0

如果这个键是一个关联的文本键,问题是应该取哪个值,如果这个值是可决定的,你将不得不做你最初想避免的事情:硬编码 <artifactId>s (或 <version>s,或确保唯一性的任何内容):

/.../artifactItems['artifactid1']/artifactId=artifactid1
/.../artifactItems['artifactid1']/version=1.0.0
/.../artifactItems['artifactid2']/artifactId=artifactid2
/.../artifactItems['artifactid2']/version=2.0.0