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

时间:2018-03-01 07:15:24

标签: java maven pom.xml parent-pom

当前情况:

父pom有一个distributionManagement部分,其中定义了两个存储库(版本和快照);请参阅以下内容:

家长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>

基于&#39;版本&#39;在同一个pom中指定,maven会自动识别是否在nexus的版本或快照存储库中部署工件。 (我相信这是使用是否有任何&#39; -SNAPSHOT&#39;后缀版本来完成。)

有一个child-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部分,如下所示:

<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&#39;”,部署仍然会失败,因为maven无法动态替换上述属性的值。 (我在配置文件中没有激活部分的原因是因为我需要稍后通过TeamCity构建整个项目,这将不具有环境变量。因此,作为命令行的一部分,我将传递应使用哪个配置文件的信息。)

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

2 个答案:

答案 0 :(得分:0)

你不能在父定义中有参数版本,你怎么能够检索正确的值,否则?

<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

来自doc:

  

设定目标可用于更新当前模块的版本。它将自动爬上本地目录以查找聚合根。它将自动更新显式引用的依赖项。您可以通过newVersion属性

指定要更新的版本

答案 1 :(得分:0)

首先,虽然您可以通过命令行定义版本,但它并不是真的可取。问题是这破坏了代码的构建可移植性。如果我查看你的代码,我将不知道这是什么版本,或者我应该使用它来构建它。另外,如果你这样做,然后在Git中标记代码,如果有人稍后检查了代码,他们就不会知道你使用的是什么版本的字符串,他们会猜测(除非他们在你的队)。

其次,以这种方式定义属性非常棘手。当您传递这样的版本时,需要首先安装父服务器,除非它是聚合器的一部分作为子模块。

在上面的示例中,父级也是聚合器。我建议把它放在一个单独的模块中。