Calvin
Calvin

Reputation: 2912

Can `${...}` properties appear in the `<parent>` section of a POM file?

Maven's POM reference says that property values "are accessible anywhere within a POM".

But that can't possibly be 100% true. The resolved value of a property depends on the POM's parent, so using a property in the <parent> section seems like it would create a circular dependency:

For example, is it legal to write

    <parent>
      <groupId>my.group</groupId>
      <artifactId>${project-prefix}-common</artifactId>
      <version>xyz</version>
    </parent>

And if so, what value does Maven use for ${project-prefix}?

Maven's own documentation suggests that properties can be used in a <parent> section, but in my own experimentation (Maven 3.9.8) I've found the behavior nigh-impossible to predict (at least for me, a POM novice).

Are properties actually allowed in the <parent> section? Also, is there any official documentation on how properties within a <parent> section are supposed to work?

Upvotes: 1

Views: 68

Answers (1)

Nikolas
Nikolas

Reputation: 44398

Maven's POM reference says that property values "are accessible anywhere within a POM".

Yes, this is true.

But that can't possibly be 100% true. The resolved value of a property depends on the POM's parent, so using a property in the section seems like it would create a circular dependency:

  • To know the parent's coordinates you need the parent's properties
  • To know the parent's properties you need the parent's coordinates

You confuse circular dependencies with property values resolving. These are based on distinct mechanisms. While I don't know the internals of Maven, the parent POM can access a property value defined in its descendant.


Example

Here is a simplified example I use in an unnamed project:

Parent POM

Properties (the jib-maven-plugin.to.image property is resolved in the children):

<properties>
    <jib-maven-plugin.to.image-registry/>
    <jib-maven-plugin.to.image-artefact/>
    <jib-maven-plugin.to.image>${jib-maven-plugin.to.image-registry}${jib-maven-plugin.to.image-artefact}</jib-maven-plugin.to.image>

    ...
</properties>

Usage:

<plugins>
    <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>jib-maven-plugin</artifactId>
        <version>${jib-maven-plugin.version}</version>
        <configuration>
            <skip>${jib-maven-plugin.skip}</skip>
            <from>
                <image>${jib-maven-plugin.from.image}</image>
                <platforms>
                    <platform>
                        <architecture>amd64</architecture>
                        <os>linux</os>
                    </platform>
                </platforms>
            </from>
            <to>
                <image>${jib-maven-plugin.to.image}</image>
                <auth>
                    <username>${env.HARBOR_USERNAME}</username>
                    <password>${env.HARBOR_PASSWORD}</password>
                </auth>
                <tags>
                    <tag>latest</tag>
                    <tag>${docker-images.version}-${buildDate}</tag>
                    <tag>${docker-images.version}-${buildDate}-${buildNumber}</tag>
                </tags>
            </to>
            <container>
                <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
                <mainClass>${main-class}</mainClass>
                <user>nobody</user>
                <workingDirectory>/app/resources</workingDirectory>
                <labels>
                    <org.opencontainers.image.vendor>Vendor</org.opencontainers.image.vendor>
                    <org.opencontainers.image.title>Title</org.opencontainers.image.title>
                    <org.opencontainers.image.description>Description</org.opencontainers.image.description>
                    <org.opencontainers.image.version>${project.version}</org.opencontainers.image.version>
                </labels>
            </container>
        </configuration>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>${jib-maven-plugin.goal}</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

    ...
</plugins>

Children POMs

foo (child 1) pom.xml:

<profiles>
    <profile>
        <id>docker-local</id>
        <properties>
            <jib-maven-plugin.skip>false</jib-maven-plugin.skip>
            <jib-maven-plugin.goal>dockerBuild</jib-maven-plugin.goal>
            <jib-maven-plugin.to.image-registry/>
        </properties>
    </profile>
    <profile>
        <id>docker-harbor</id>
        <properties>
            <jib-maven-plugin.skip>false</jib-maven-plugin.skip>
            <jib-maven-plugin.goal>build</jib-maven-plugin.goal>
            <jib-maven-plugin.to.image-registry>mycompany-1.com/foo/</jib-maven-plugin.to.image-registry>
        </properties>
    </profile>
</profiles>

bar (child 2) pom.xml:

<profiles>
    <profile>
        <id>docker-local</id>
        <properties>
            <jib-maven-plugin.skip>false</jib-maven-plugin.skip>
            <jib-maven-plugin.goal>dockerBuild</jib-maven-plugin.goal>
            <jib-maven-plugin.to.image-registry/>
        </properties>
    </profile>
    <profile>
        <id>docker-harbor</id>
        <properties>
            <jib-maven-plugin.skip>false</jib-maven-plugin.skip>
            <jib-maven-plugin.goal>build</jib-maven-plugin.goal>
            <jib-maven-plugin.to.image-registry>mycompany-1.com/bar/</jib-maven-plugin.to.image-registry>
        </properties>
    </profile>
</profiles>

Upvotes: 0

Related Questions