scala - 动态maven artifactId

标签 scala maven sbt maven-3 pom.xml

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

我正在使用 maven 构建一个 scala 项目,因此,为了允许为不同的 scala 版本发布项目,我想在 pom.xml 中声明:
<artifactId>myproject_${scalaBinaryVersion}</artifactId>
但是 Maven 3.3。提示

[WARNING] 'artifactId' contains an expression but should be a constant



由于我希望这个项目与 sbt 可互操作,那么发布后缀为 scala 二进制版本的 Artifact 的最佳方式是什么?

最佳答案

这样做的 Maven 方法是使用 classifiers .来自官方文档的示例与您的情况完全匹配(对于不同的 Java 版本,但您可以用 Scala 替换 Java):

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 插件的默认执行并将其绑定(bind)到不存在的阶段。因此 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>&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 资源插件和 copying 过滤现有的 pom 文件到目录target\${scalaBinaryVersion} .复制的 pom 将具有与动态版本的依赖关系,因为资源插件将替换它们。但是,它还没有动态 artifactId。
  • 完成动态 pom 文件。 Replacer 插件将替换 artifactId具有动态值的 XML 元素(在 target 文件夹中工作,因此临时文件中的所有内容)
  • 跳过默认安装的生成
  • 执行自定义install-file installation使用动态 pom 文件(过滤、复制和替换的文件,提供动态依赖项(以及动态传递依赖项)和动态 artifactId

  • 因此,执行以下 Maven 调用:
    mvn clean install -Pbuild-scala-version -DscalaBinaryVersion=hello -Ddependency.version=4.4
    

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

    关于scala - 动态maven artifactId,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35022831/

    相关文章:

    scala - 如何在 HUET zipper 内向上导航

    Scala 反射 : How to find a no-arg constructor via reflection (if there are multiple constructors) ? "no-arg"的类型签名是什么?

    scala - Spark将单列转换为数组

    java - 什么是 maven settings.xml 文件以及它与 pom.xml 有何不同

    scala - sbt 新的运行时异常

    java - 无法在 scala 中使用 jackson fastxml 将 json 数组反序列化为类对象

    maven - cobertura报告中行号旁边的颜色和数字是什么

    maven - Jenkins 多分支管道 - mvn 未被识别为命令

    windows - sbt 在运行 Play docker 容器时下载失败

    java - 没有maven的eclipse中java + scala + lift项目的环境