当前位置: 首页 > 知识库问答 >
问题:

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

丌官积厚
2023-03-14

当前情景:

父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>

基于同一pom中指定的“版本”,maven会自动识别是在发布中部署工件还是在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>

问题:

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

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

共有2个答案

云文栋
2023-03-14

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

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

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

白信鸿
2023-03-14

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

<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版本插件一次更改所有模块的版本:

mvn versions:set -DnewVersion=0.8-SNAPSHOT

从文件中:

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

 类似资料:
  • 我们有一个公司范围的Super Pom,用于定义我们使用的许多默认值。例如,Super Pom定义要使用的JDK版本以及其他参数。这由我们的项目继承为父pom。 我们的大多数项目都使用JDK1.7,但有一组项目仍在JDK1.6版本上。我在我的父母pom中添加了以下配置文件定义: 现在,我有一个名为的配置文件,我想在项目的pom中指定它应该默认使用这个。我该怎么做? 我尝试在项目的pom中添加: 但

  • 我正试着做一个包含所有项目的胖uber罐子。如果我做了“MVN包”,我得到一个uber jar下的“blah”项目标签文件夹。(blah项目有主类。)uber jar包含所有项目(作为文件夹而不是jar),但当我运行它时,它似乎无法识别feature1和feature2项目。 我在上面添加了feature1和feature2的依赖项,以便它们在uber jar文件中。这错了吗?附注。blahmes

  • Maven插件及其在父pom中定义的依赖项,我不希望我的子pom包含该插件依赖项。 例如,如果有1个父级和100个子级,99个使用该插件并希望在一个子级中排除该插件。 我们如何才能实现这一目标?

  • 我是使用maven和jenkins的新手。我正在尝试从父pom继承到子pom的依赖关系,它显示以下错误: 这是我的父母POM: 这是我的孩子波姆: 这是我如何尝试从父POM继承子POM中的依赖关系: 如果我在子POM中放置这些相同的依赖项,它会完美地工作。我使用jenkins在nexus中进行安装和部署。我使用的是maven-3.3.9。在jenkins中,我阅读了git中两个不同maven项目中

  • 13.2.2 不配置父POM使用Spring Boot 并不是每个人都喜欢继承spring-boot-starter-parent的POM。您可能需要使用自己公司标准的POM,或者您可能只是希望显式声明所有的Maven配置。 如果您不想使用spring-boot-starter-parent,您仍然可以通过使用scope=import依赖来继续享有依赖管理(但不是插件管理)的好处: <depend

  • 我有这样配置的父pom: 我的孩子波姆: 我想在我的类路径中使用4.3.5版本,因为目前我收到错误消息,不应修改父版本: 任何想法如何防止覆盖4.2.9版本?