动态maven artifactId

时间:2016-01-26 20:02:30

标签: scala maven sbt maven-3 pom.xml

POM是否可以声明(或至少发布)包含系统属性的artifactId?我的意思是实际项目的artifactId,而不是依赖项。

我正在使用maven构建一个scala项目,因此,为了允许在pom.xml中发布不同scala版本的项目,我想声明:

<artifactId>myproject_${scalaBinaryVersion}</artifactId>

然而maven 3.3。抱怨

  

[警告]&artifact; artifactId&#39;包含表达式但应该是常量

由于我希望这个项目可以与sbt互操作,因此发布带有scala二进制版本后缀的工件的最佳方法是什么?

3 个答案:

答案 0 :(得分:11)

Maven方式这样做将使用classifiers。从官方文档中,一个示例完全符合您的情况(对于不同的Java版本,但您可以用Scala替换Java):

  

分类器允许区分从同一POM构建但内容不同的工件。它是一些可选的任意字符串 - 如果存在 - 将附加到版本号之后的工件名称。   作为此元素的动机,请考虑一个项目,该项目提供针对JRE 1.5的工件,但同时也是一个仍支持JRE 1.4的工件。第一个工件可以配备分类器jdk15,第二个工件可以配备jdk14,以便客户可以选择使用哪个。

您可以将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。然后,Install Plugin只会安装已分类的插件。

更新:如何使用动态依赖关系安装动态artifactId

如果不同的动态版本需要不同的传递依赖性,那么分类器确实不合适 然而,可以实现具有动态依赖性(并且因此动态传递依赖性)的动态artifactIds。以下是我使用(并成功测试)的方法:

作为首选项,我在配置文件中隔离了动态行为,但您显然可以将其移回默认构建(或默认情况下配置文件处于活动状态)。

首先,让我们在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>&lt;artifactId&gt;${project.artifactId}&lt;/artifactId&gt;</token>
                                <!-- Replace to -->
                                <value>&lt;artifactId&gt;${project.artifactId}_${scalaBinaryVersion}&lt;/artifactId&gt;</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 Resources Plugin过滤现有的pom文件,并将copying过滤到目录target\${scalaBinaryVersion}。复制的pom将具有动态版本的依赖项,因为Resources Plugin将替换它们。但是,它不会有动态artifactId(还)。
  • 完成动态pom文件。 Replacer插件将使用动态值替换artifactId XML元素(在target文件夹上工作,因此临时文件上的所有内容都已完成)
  • 跳过默认安装的生成
  • 使用动态pom文件执行自定义install-file installation(过滤,复制和替换的文件,提供动态依赖关系(以及动态传递依赖关系)和动态artifactId

因此,执行以下maven调用:

mvn clean install -Pbuild-scala-version -DscalaBinaryVersion=hello -Ddependency.version=4.4

Maven将在本地缓存中有效地为动态artifactId,动态依赖版本和动态pom安装新工件。
注意:如果相关的依赖版本和动态scala版本相同,那么您可以保存参数并使调用更短且更一致。

答案 1 :(得分:0)

如果您正在使用maven,那么我将使用带有maven helper plugin的多pom进行搜索,因此artifactId在每个模块中都是常量。

答案 2 :(得分:0)

我们遵循此处建议的属性(通过配置文件)方法:scala-maven-plugin FAQ

<artifactId>something_${scala.compat.version}</artifactId>

<properties>
 <scala.compat.version>2.12</scala.compat.version>
</properties>

maven仍会发出警告(有充分理由),但在flatten-maven-plugin的帮助下,我们构建/安装了已更换变量的poms。