有没有一种方法可以在Maven中引用依赖项或artifactItem中的特定元素?

huangapple go评论71阅读模式
英文:

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

问题

目前,我有一个pom.xml文件,在构建时从mvnrepository获取依赖的Javadoc jars并解压到特定文件夹中:

	<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>
    					<!-- 其他artifactItem项 -->
					</artifactItems>
				</configuration>
			</plugin>
    	</plugins>
	</build>

问题是,如果我不为每个artifact指定输出目录字段,Javadoc会解压到一个文件夹中(这也可以在unpack目标的配置中进行配置 - https://maven.apache.org/plugins-archives/maven-dependency-plugin-2.6/unpack-mojo.html ),但我希望它们能够以清晰的结构保存在文件夹中。因此,我为每个artifactItem添加了一个directory条目。但是,我必须手动编写文件夹名称。是否有一种方式可以参考现有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 artifact项中的outputDirectory,但它们都将相同。
谢谢!

英文:

Currently, I have a pom.xml, which, upon build, gathers dependency Javadoc jars from mvnrepository and unpacks them in specific folders:

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

The thing is, if I do not specify the output directory field for each artifact, the javadoc gets unpacked all in one folder (which is also configurable for the unpack goal - https://maven.apache.org/plugins-archives/maven-dependency-plugin-2.6/unpack-mojo.html ), and I want them to be clearly structured in folders. So I added a directory entry for each artifactItem. However, I have to write the folder name manually. Is there a way to refer the existing artifactItem's fields, in a way similar to this:

		                &lt;artifactItem&gt;
							&lt;groupId&gt;groupid1&lt;/groupId&gt;
							&lt;artifactId&gt;artifactid1&lt;/artifactId&gt;
							&lt;version&gt;1.0.0&lt;/version&gt;
							&lt;classifier&gt;javadoc&lt;/classifier&gt;
							&lt;outputDirectory&gt;${project.build.directory}/dependency-javadoc/${artifactItem.artifactId}-${artifactItem.version}&lt;/outputDirectory&gt;
						&lt;/artifactItem&gt;

This way,I will be able to just copy/paste the outputDirectory in all javadoc artifact entries, but it will be the same.
Thanks!

答案1

得分: 1

这是一个有趣的问题。我记得过去曾经有过在同一个POM中将POM声明用作属性的要求,但那时只有一些值,所以我当时硬编码了这些值。然而,我认为我们在这里运气不太好。至少用我首先想到的方法来说是这样的:

编写一个像“POM Strings Maven Plugin”这样的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>(或者<version>,或者任何确保唯一性的东西):

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

This is an interesting question. I remember having had this requirement of using POM declarations as properties in the same POM in the past, but I hardcoded the values then since there were just a few of them. However, I think we're out of luck here. At least with the approach that came into my mind first:

Writing a Maven Plugin like e.g POM Strings Maven Plugin (and in fact I did that here for a POC of my idea) with a goal:

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

which finds all XML text nodes (under &lt;artifactItems&gt; in your case) in the POM, then finds their full XML tree paths and creates Maven project properties for them that look like:

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

After declaring its execution at e.g. the initialize phase of your projects your declarations will look like (with line breaks for easier reading):

&lt;outputDirectory&gt;
${project.build.directory}/dependency-javadoc/
${/project/build/plugins/plugin/configuration/artifactItems/artifactItem/artifactId}
-
${/project/build/plugins/plugin/configuration/artifactItems/artifactItem/version}
&lt;/outputDirectory&gt;

The problem, however, is this inconspicuous, innocent "...", since the full paths are not unique in this case. There are two possible values for each of them. To resolve this a key would have to be introduced (by finding the first unique parent) so that the properties will look like:

/project/build/plugins/plugin/configuration/artifactItems[&lt;key1&gt;]/artifactId=artifactid1
/project/build/plugins/plugin/configuration/artifactItems[&lt;key1&gt;]/version=1.0.0
/project/build/plugins/plugin/configuration/artifactItems[&lt;key2&gt;]/artifactId=artifactid2
/project/build/plugins/plugin/configuration/artifactItems[&lt;key2&gt;]/version=2.0.0

If this key would be a numerical index the declaration order would be crucial, which contradicts the declarative nature of POMs and for that it's not the Good, but the Bad and the Ugly<sup>[1]</sup>:

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

If this key would be an associative textual key, the question is which value should be taken and if this is decidable somehow you would have to do what you wanted to avoid originally: hardcode the &lt;artifactId&gt;s (or &lt;version&gt;s, or whatever ensures uniqueness):

/.../artifactItems[&#39;artifactid1&#39;]/artifactId=artifactid1
/.../artifactItems[&#39;artifactid1&#39;]/version=1.0.0
/.../artifactItems[&#39;artifactid2&#39;]/artifactId=artifactid2
/.../artifactItems[&#39;artifactid2&#39;]/version=2.0.0

huangapple
  • 本文由 发表于 2020年8月7日 19:33:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/63300970.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定