动态maven artifactId
Dynamic maven artifactId
POM 是否可以声明(或至少发布)包含系统属性的 artifactId
?我指的是实际项目的artifactId,不是dependencies。
我正在使用 maven 构建一个 scala 项目,因此,为了允许针对不同的 scala 版本发布该项目,在 pom.xml 我想声明:
<artifactId>myproject_${scalaBinaryVersion}</artifactId>
然而 maven 3.3。抱怨
[WARNING] 'artifactId' contains an expression but should be a constant
因为我希望这个项目可以与 sbt 互操作,发布一个以 scala 二进制版本为后缀的工件的最佳方式是什么?
如果你为此使用 maven,我将 saggest 使用 multipom 和 maven helper plugin 所以每个模块中的 artifactId 都是常量。
这样做的 Maven 方式 是使用 classifiers。来自官方文档的示例与您的情况完全匹配(对于不同的 Java 版本,但您可以将 Java 替换为 Scala):
The classifier allows to distinguish artifacts that were built from the same POM but differ in their content. It is some optional and arbitrary string that - if present - is appended to the artifact name just after the version number.
As a motivation for this element, consider for example a project that offers an artifact targeting JRE 1.5 but at the same time also an artifact that still supports JRE 1.4. The first artifact could be equipped with the classifier jdk15 and the second one with jdk14 such that clients can choose which one to use.
您可以按如下方式配置 POM:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>${scalaBinaryVersion}</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
注意:我们正在添加 Maven Jar 插件的额外执行,因此该项目将创建两个 jar,一个普通的 + 一个带有指定(动态)分类器的额外的。
然后 Maven 会自动将分类的 jar 与普通 jar 一起发布(因为它会自动附加到构建中)。然后,您可以将其作为 Maven 的进一步依赖项导入到另一个项目中,将其分类器指定为 Maven GAV(本例中为 GAVC)的一部分:
<dependency>
<groupId>your.group.id</groupId>
<artifactId>your.constant.artifact.id</artifactId>
<version>your.version</version>
<classifier>your.dynamic.classifier</classifier>
</dependency>
如果你只想构建分类的而不是标准的(未使用的)jar,你可以跳过正常 jar 的创建,如下所示:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<id>scala-version-jar</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>${scalaBinaryVersion}</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
注意:我们只是覆盖 Jar 插件的默认执行并将其绑定到一个不存在的阶段。因此 Maven 只会生成分类的 Jar。安装插件将只安装分类的。
更新:如何使用动态依赖项安装动态 artifactId
如果不同的动态版本需要不同的传递依赖,那么分类器确实不适合。
然而,可以实现具有动态依赖性(以及动态传递依赖性)的动态 artifactId。下面是我使用的方法(并成功测试):
作为偏好,我在配置文件中隔离了动态行为,但您显然可以将其移回默认构建(或默认激活配置文件)。
首先,让我们在 pom 中定义需要动态版本的依赖项,因此通过如下属性:
<properties>
<scalaBinaryVersion>scalaversion</scalaBinaryVersion>
<dependency.version>4.11</dependency.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${dependency.version}</version>
</dependency>
</dependencies>
注意:为了举例,我在这种情况下使用 Junit 作为依赖项,而不是在 test
范围内,因为我希望它作为 compile
依赖项(同样,只是为了这个例子)。
然后让我们为我们的动态行为定义一个配置文件:
<profiles>
<profile>
<id>build-scala-version</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<finalName>${project.artifactId}_${scalaBinaryVersion}-${project.version}</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-pom</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${scalaBinaryVersion}</outputDirectory>
<resources>
<resource>
<directory>${basedir}</directory>
<includes>
<include>pom.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<id>replace-artifactid</id>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
<configuration>
<file>target/${scalaBinaryVersion}/pom.xml</file>
<token><artifactId>${project.artifactId}</artifactId></token>
<!-- Replace to -->
<value><artifactId>${project.artifactId}_${scalaBinaryVersion}</artifactId></value>
<outputDir>target${scalaBinaryVersion}\replacer</outputDir>
<outputFile>pom.xml</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
<execution>
<id>install-scala-version</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}_${scalaBinaryVersion}</artifactId>
<version>${project.version}</version>
<packaging>${project.packaging}</packaging>
<file>${project.build.directory}/${project.artifactId}_${scalaBinaryVersion}-${project.version}.jar</file>
<pomFile>${project.build.directory}/${scalaBinaryVersion}/replacer/pom.xml</pomFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
请注意,配置文件正在自定义并提供以下内容:
- 根据运行时(也称为动态)值,将具有动态名称的最终 Jar 名称更改为
${project.artifactId}_{scalaBinaryVersion}-${project.version}
- 通过 Maven 资源插件过滤现有的 pom 文件并将其 copying 到目录
target${scalaBinaryVersion}
。复制的 pom 将具有与动态版本的依赖关系,因为资源插件将替换它们。但是,它不会有动态的 artifactId(还)。
- 正在完成动态 pom 文件。 Replacer 插件将用动态值替换
artifactId
XML 元素(在 target
文件夹中工作,因此所有内容都在临时文件中)
- 跳过默认安装的生成
- 使用动态 pom 文件(过滤、复制和替换的文件,提供动态依赖项(以及动态传递依赖项)和动态 artifactId[=71] 执行自定义
install-file
installation =]
因此,执行以下 Maven 调用:
mvn clean install -Pbuild-scala-version -DscalaBinaryVersion=hello -Ddependency.version=4.4
Maven 将有效地在本地缓存中为动态 artifactId、动态依赖版本和动态 pom 安装一个新的工件。
注意:如果相关的依赖版本和动态 scala 版本相同,那么你可以保存一个参数并使调用更短和更一致。
我们遵循此处建议的基于属性(通过配置文件)的方法:scala-maven-plugin FAQ
<artifactId>something_${scala.compat.version}</artifactId>
<properties>
<scala.compat.version>2.12</scala.compat.version>
</properties>
maven 仍会发出警告(有充分的理由),但在 flatten-maven-plugin 的帮助下,我们 build/install 已替换变量的 poms。
POM 是否可以声明(或至少发布)包含系统属性的 artifactId
?我指的是实际项目的artifactId,不是dependencies。
我正在使用 maven 构建一个 scala 项目,因此,为了允许针对不同的 scala 版本发布该项目,在 pom.xml 我想声明:
<artifactId>myproject_${scalaBinaryVersion}</artifactId>
然而 maven 3.3。抱怨
[WARNING] 'artifactId' contains an expression but should be a constant
因为我希望这个项目可以与 sbt 互操作,发布一个以 scala 二进制版本为后缀的工件的最佳方式是什么?
如果你为此使用 maven,我将 saggest 使用 multipom 和 maven helper plugin 所以每个模块中的 artifactId 都是常量。
这样做的 Maven 方式 是使用 classifiers。来自官方文档的示例与您的情况完全匹配(对于不同的 Java 版本,但您可以将 Java 替换为 Scala):
The classifier allows to distinguish artifacts that were built from the same POM but differ in their content. It is some optional and arbitrary string that - if present - is appended to the artifact name just after the version number. As a motivation for this element, consider for example a project that offers an artifact targeting JRE 1.5 but at the same time also an artifact that still supports JRE 1.4. The first artifact could be equipped with the classifier jdk15 and the second one with jdk14 such that clients can choose which one to use.
您可以按如下方式配置 POM:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>${scalaBinaryVersion}</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
注意:我们正在添加 Maven Jar 插件的额外执行,因此该项目将创建两个 jar,一个普通的 + 一个带有指定(动态)分类器的额外的。
然后 Maven 会自动将分类的 jar 与普通 jar 一起发布(因为它会自动附加到构建中)。然后,您可以将其作为 Maven 的进一步依赖项导入到另一个项目中,将其分类器指定为 Maven GAV(本例中为 GAVC)的一部分:
<dependency>
<groupId>your.group.id</groupId>
<artifactId>your.constant.artifact.id</artifactId>
<version>your.version</version>
<classifier>your.dynamic.classifier</classifier>
</dependency>
如果你只想构建分类的而不是标准的(未使用的)jar,你可以跳过正常 jar 的创建,如下所示:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<id>scala-version-jar</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>${scalaBinaryVersion}</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
注意:我们只是覆盖 Jar 插件的默认执行并将其绑定到一个不存在的阶段。因此 Maven 只会生成分类的 Jar。安装插件将只安装分类的。
更新:如何使用动态依赖项安装动态 artifactId
如果不同的动态版本需要不同的传递依赖,那么分类器确实不适合。
然而,可以实现具有动态依赖性(以及动态传递依赖性)的动态 artifactId。下面是我使用的方法(并成功测试):
作为偏好,我在配置文件中隔离了动态行为,但您显然可以将其移回默认构建(或默认激活配置文件)。
首先,让我们在 pom 中定义需要动态版本的依赖项,因此通过如下属性:
<properties>
<scalaBinaryVersion>scalaversion</scalaBinaryVersion>
<dependency.version>4.11</dependency.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${dependency.version}</version>
</dependency>
</dependencies>
注意:为了举例,我在这种情况下使用 Junit 作为依赖项,而不是在 test
范围内,因为我希望它作为 compile
依赖项(同样,只是为了这个例子)。
然后让我们为我们的动态行为定义一个配置文件:
<profiles>
<profile>
<id>build-scala-version</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<finalName>${project.artifactId}_${scalaBinaryVersion}-${project.version}</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-pom</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${scalaBinaryVersion}</outputDirectory>
<resources>
<resource>
<directory>${basedir}</directory>
<includes>
<include>pom.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<id>replace-artifactid</id>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
<configuration>
<file>target/${scalaBinaryVersion}/pom.xml</file>
<token><artifactId>${project.artifactId}</artifactId></token>
<!-- Replace to -->
<value><artifactId>${project.artifactId}_${scalaBinaryVersion}</artifactId></value>
<outputDir>target${scalaBinaryVersion}\replacer</outputDir>
<outputFile>pom.xml</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
<execution>
<id>install-scala-version</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}_${scalaBinaryVersion}</artifactId>
<version>${project.version}</version>
<packaging>${project.packaging}</packaging>
<file>${project.build.directory}/${project.artifactId}_${scalaBinaryVersion}-${project.version}.jar</file>
<pomFile>${project.build.directory}/${scalaBinaryVersion}/replacer/pom.xml</pomFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
请注意,配置文件正在自定义并提供以下内容:
- 根据运行时(也称为动态)值,将具有动态名称的最终 Jar 名称更改为
${project.artifactId}_{scalaBinaryVersion}-${project.version}
- 通过 Maven 资源插件过滤现有的 pom 文件并将其 copying 到目录
target${scalaBinaryVersion}
。复制的 pom 将具有与动态版本的依赖关系,因为资源插件将替换它们。但是,它不会有动态的 artifactId(还)。 - 正在完成动态 pom 文件。 Replacer 插件将用动态值替换
artifactId
XML 元素(在target
文件夹中工作,因此所有内容都在临时文件中) - 跳过默认安装的生成
- 使用动态 pom 文件(过滤、复制和替换的文件,提供动态依赖项(以及动态传递依赖项)和动态 artifactId[=71] 执行自定义
install-file
installation =]
因此,执行以下 Maven 调用:
mvn clean install -Pbuild-scala-version -DscalaBinaryVersion=hello -Ddependency.version=4.4
Maven 将有效地在本地缓存中为动态 artifactId、动态依赖版本和动态 pom 安装一个新的工件。
注意:如果相关的依赖版本和动态 scala 版本相同,那么你可以保存一个参数并使调用更短和更一致。
我们遵循此处建议的基于属性(通过配置文件)的方法:scala-maven-plugin FAQ
<artifactId>something_${scala.compat.version}</artifactId>
<properties>
<scala.compat.version>2.12</scala.compat.version>
</properties>
maven 仍会发出警告(有充分的理由),但在 flatten-maven-plugin 的帮助下,我们 build/install 已替换变量的 poms。