Search code examples
mavenpom.xmlmaven-enforcer-plugin

Require Maven property to be defined in child modules


I recently used the Maven Enforcer Plugin to mandate that all POMs define a foo.bar property. I placed this statement in my corporate POM and assumed it would then apply to my child projects.

To my dismay (but not surprise), the rule was also enforced on my corporate POM. As a result, I dutifully defined a placeholder foo.bar property and thought I was done.

Unfortunately, all the child projects inherit this property and thereby pass the enforcer test. I'm left unable to determine whether the children have explicitly defined this property or simply inherited a nonsense value. Can anyone suggest a way to either:

  • ensure this (particular) rule is not applied to my coporate POM; or

  • ensure my placeholder property is not inherited by the child projects; or

  • solve my problem another way?

In case it helps, the definition of my enforcer rules is shown below. This snippet is from my corporate POM.

<!-- Enforce good behaviour in child POMs -->
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <version>1.2</version>
  <executions>
    <execution>
      <id>enforce-good-behaviour</id>
      <goals>
        <goal>enforce</goal>
      </goals>
      <configuration>
        <rules>
          <requireProperty>
            <property>foo.bar</property>
            <message>NAUGHTY!</message>
            <regex>.+</regex>
            <regexMessage>The property must contain at least one character.</regexMessage>
          </requireProperty>
        </rules>
      </configuration>
    </execution>
  </executions>
</plugin>

My goal was to automatically use this property value as part of an SCM tagging instruction. I have the following snippet in my corporate POM that defines a nice tagging scheme for my child projects:

<!-- Ensure we use a consistent tagging scheme for releases -->
<plugin>
  <artifactId>maven-release-plugin</artifactId>
  <configuration>
    <tagNameFormat>a.b.c.${foo.bar}</tagNameFormat>
    <useReleaseProfile>false</useReleaseProfile>
  </configuration>
</plugin>

Solution

  • I had this exact same dilemma. Here's how I solved it.

    In the corporate POM, I added a profile like this:

        <profile>
        <!-- When we are building the corporate base projects we don't want 
             to require that all of the properties that should be provided by 
             child projects (inheriters) are defined. So we activate this 
             profile when building the corporate projects to bypass anything 
             that only applies to children (the leaf projects). 
             Add "-Dcorporate.build=true" on the maven cmd line when building
             and releasing the corporate POMs to accomplish this. -->
            <id>corporate-pom-build</id>
            <activation>
                <property>
                    <name>corporate.build</name>
                    <value>true</value>
                </property>
            </activation>
            <properties>
                <enforcer.skip>true</enforcer.skip>
                <remoteresources.skip>true</remoteresources.skip>
                <assembly.skipAssembly>true</assembly.skipAssembly>
            </properties>
        </profile>
    

    Then, as the comment says, I build the corporate POMs with

    mvn -Dcorporate.build=true clean deploy

    Other things you want to skip could go in that profile as well. Works like a charm.