Require Maven property to be defined in child modules

Duncan Jones picture Duncan Jones · Feb 7, 2013 · Viewed 7.2k times · Source

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>

Answer

user944849 picture user944849 · Feb 7, 2013

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.