java - 如何在子 pom 中使用父 pom 的配置文件属性?

标签 java maven pom.xml parent-pom

当前场景:

父pom有一个distributionManagement部分,里面定义了两个repositories(releases和snapshots);引用如下:

父 pom:

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <properties>
        <buildVersion>0.7</buildVersion>
    </properties>

    <groupId>x.y.z</groupId>
    <artifactId>abc</artifactId>
    <version>${buildVersion}</version>
    <packaging>pom</packaging>

    <modules>
        <module>moduleA</module>
        <module>moduleB</module>
        <module>moduleC</module>
    </modules>

    <dependencies>

    </dependencies>

    <distributionManagement>
        <repository>
            <id>releases</id>
            <url>http://xyz/nexus/content/repositories/releases/</url>
        </repository>
        <snapshotRepository>
            <id>snapshots</id>
            <url>http://xyz/nexus/content/repositories/snapshots/</url>
        </snapshotRepository>
    </distributionManagement>

    <profiles>
    <profile>
        <id>snapshots-enabled</id>
        <properties>
            <repositoryUrl>http://xyz/nexus/content/repositories/snapshots/</repositoryUrl>
            <repositoryId>snapshots</repositoryId>
        </properties>
    </profile>
    <profile>
        <id>release-enabled</id>
        <properties>
            <repositoryUrl>http://xyz/nexus/content/repositories/releases/</repositoryUrl>
            <repositoryId>releases</repositoryId>
        </properties>
    </profile>
</profiles>

</project>

基于同一个 pom 中指定的“版本”,maven 自动识别是在 release 中部署 Artifact 还是在 nexus 中部署快照存储库。 (我相信这是通过版本是否有任何“-SNAPSHOT”后缀来完成的。)

有一个子 pom,其中定义了一些部署文件目标;引用如下:

子 pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>x.y.z</groupId>
        <artifactId>abc</artifactId>
        <version>${buildVersion}</version>
    </parent>

    <groupId>${parent.groupId}</groupId>
    <artifactId>childArtifactId</artifactId>
    <version>${parent.version}</version>
    <packaging>war</packaging>
    <name>MyChildProject</name>    

    <build>
        <sourceDirectory>src</sourceDirectory>

        <plugins>
            <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-deploy-plugin</artifactId>
            <version>2.8.2</version>
            <executions>
                <execution>
                    <id>deploy-TA</id>
                    <configuration>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>TA</artifactId>
                        <version>${project.version}</version>
                        <url>http://xyz/nexus/content/repositories/releases/</url>
                        <repositoryId>releases</repositoryId>
                        <file>${basedir}/target/TA.war</file>
                    </configuration>
                    <phase>deploy</phase>
                    <goals>
                        <goal>deploy-file</goal>
                    </goals>
                </execution>
                <execution>
                    <id>deploy-OA</id>
                    <configuration>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>OA</artifactId>
                        <version>${project.version}</version>
                        <url>http://xyz/nexus/content/repositories/releases/</url>
                        <repositoryId>releases</repositoryId>
                        <file>${basedir}/target/OA.war</file>
                    </configuration>
                    <phase>deploy</phase>
                    <goals>
                        <goal>deploy-file</goal>
                    </goals>
                </execution>
                <execution>
                    <id>deploy-CSA</id>
                    <configuration>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>CSA</artifactId>
                        <version>${project.version}</version>
                        <url>http://xyz/nexus/content/repositories/releases/</url>
                        <repositoryId>releases</repositoryId>
                        <file>${basedir}/target/CSA.war</file>
                    </configuration>
                    <phase>deploy</phase>
                    <goals>
                        <goal>deploy-file</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        </plugins>

    </build>

</project>

问题:

正如您在上面的子 pom 中看到的,我必须为每个配置标签明确指定 url 和 repositoryId 标签。没有它们,就会抛出错误并且部署文件目标失败。

现在,我不想在子 pom 中硬编码它们的值。相反,我想有条件地从父 pom 继承这些值:如果父使用发布存储库,那么子也应该使用相同的。如果父级使用快照存储库,那么子级也应该使用相同的。 (再次注意,父 pom 中没有指定使用各自存储库的条件,而是如上所述由 maven 自动完成)

那么我如何根据父/子 pom 中的某些条件评估在子 pom 中制作这个条件值填充?

我尝试过的事情:

我在父 pom 中添加了配置文件部分,如下所示:

<profiles>
    <profile>
        <id>snapshots-enabled</id>
        <properties>
            <repositoryUrl>http://xyz/nexus/content/repositories/snapshots/</repositoryUrl>
            <repositoryId>snapshots</repositoryId>
        </properties>
    </profile>
    <profile>
        <id>release-enabled</id>
        <properties>
            <repositoryUrl>http://xyz/nexus/content/repositories/releases/</repositoryUrl>
            <repositoryId>releases</repositoryId>
        </properties>
    </profile>
</profiles>

如上所示,有两个配置文件,每个配置文件都具有相同的属性和不同的值。但是,我无法使用它们的 ID 在父 pom 或子 pom 中填充上述属性。例如。在父 pom 中使用 ${repositoryUrl} 或在子 pom 中使用 ${parent.repositoryUrl} 不起作用。 IntelliJ 立即将其显示为红色。尽管如此,如果我仍然尝试使用命令“mvn deploy -P release-enabled”,部署仍然会失败,因为 maven 无法动态替换上述属性的值。 (我在配置文件中没有激活部分的原因是因为我需要稍后通过 TeamCity 构建整个项目,它不会有环境变量。因此,仅作为命令行的一部分,我将传递应该使用哪个配置文件的信息.)

关于如何在父/子 pom 中动态填充值的任何建议?是否有任何 if-else 类型的表达式评估可能,可能基于在执行“mvn deploy”命令时可以传递的一些参数?

最佳答案

您不能在父定义中有参数版本,否则您如何能够检索到正确的值?

<parent>
    <groupId>x.y.z</groupId>
    <artifactId>abc</artifactId>
    <version>${buildVersion}</version>
</parent>

您应该做的是在父 pom 中定义正确的版本:

<groupId>x.y.z</groupId>
<artifactId>abc</artifactId>
<version>0.7</version>
<packaging>pom</packaging>

摆脱 buildVersion 变量并使用 pom version plugin一次更改所有模块的版本:

mvn versions:set -DnewVersion=0.8-SNAPSHOT

来自文档:

The set goal can be used to update the version of the current module. It will automatically climb up local directories to find the aggregation root. It will automatically update explicitly referenced dependencies. You specify the version to update to via the newVersion property

关于java - 如何在子 pom 中使用父 pom 的配置文件属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49044455/

相关文章:

java - 为什么子类运行父类(super class)构造函数?

java - 通过 JNI 更快的 Math.exp()?

maven - 提取pom.xml中的版本

java - Maven:差异模块-java包

java - 在 Intellij/idea 中的 Cucumber/Java 项目中创建可执行 JAR

java - 使用 Maven 时,<fork>true</fork> 在 pom.xml 中意味着什么?

java - 使用 flandmark (Javacv) 显示每个关键点的协调

java - Spring Data Neo4j (SDN) 查询参数不使用转换器

java - 多个 Spring-Boot (Web) 项目

java - Intellij IDEA : synchronization of updatings in the pom-file and external libraries