【问题标题】:Is there a way to refer, with Maven, specific elements within a dependency or artifactItem?有没有办法使用 Maven 来引用依赖项或 artifactItem 中的特定元素?
【发布时间】:2020-11-27 17:49:15
【问题描述】:

目前,我有一个 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>

这样,我将能够在所有 javadoc 工件条目中复制/粘贴 outputDirectory,但它是相同的。 谢谢!

【问题讨论】:

  • 为什么在构建过程中解压 javadoc?这通常由您的 IDE 完成,而 IDE 通常使用源包?
  • 我正在维护一个使用开源库的项目,我必须手边有 javadoc。基本上,我们只需要为每个使用的组件提供可用的 javadoc,并且它必须在构建过程中尽可能自动化。另一种解决方案是复制 javadoc jar 而不是解压缩它们,但我想先看看它是否可以这样工作。
  • 如果您的 IDE 配置正确,它将通过查看适当的库自动下载源代码/javadoc,并且在构建期间解压缩它们没有意义。让您的 IDE 完成工作stackoverflow.com/questions/31072667/…(也可以配置 Eclipse ..)

标签: java maven dependency-injection dependencies


【解决方案1】:

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

编写一个 Maven 插件,例如 POM 字符串 Maven 插件(事实上,我这样做是为了我的想法的 POC),其目标是:

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

在 POM 中找到所有 XML 文本节点(在您的情况下为 &lt;artifactItems&gt;),然后找到它们的完整 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

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

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

【讨论】:

  • 非常感谢您的评论。我想这种推荐没有自然的内置机制,所以只能使用一个额外的插件。我必须评估开销是否值得不手动编写属性(大约有 50 个开源 jar)。
  • @VelitchkoValkov 以上不仅仅是评论,而是答案。 (因此,可以是upvoted and even accepted。;)
猜你喜欢
  • 2018-04-16
  • 2011-06-10
  • 2020-09-14
  • 2020-10-01
  • 2018-05-02
  • 1970-01-01
  • 2010-11-28
  • 2016-04-12
相关资源
最近更新 更多