Maven

Maven. Share properties between modules.

We have the following situation:  a set of global properties and multiple maven modules. Some properties are required by something inside a module, others are required by another module. How can we achieve this?  One way would be to have a copy of the properties available for each module. It will work, but it’s not maintainable. Each change needs to be synchronised with all files. Manually it’s a nightmare. Sure you could create a batch script to do this, but that’s not what we want.

Luckily there are some solutions.

 Properties

 <profile>
    <id>local</id>
    <activation>
       <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
       <module11.name>Module Eleven</module11.name>
       <module12.name>Module Twelve</module12.name>
       <module21.name>Module TwentyOne</module21.name>
       <module22.name>Module TwentyTwo</module22.name>
    </properties>
    <build>
       <resources>
          <resource>
             <directory>src/main/resources</directory>
             <filtering>true</filtering>
          </resource>
       </resources>
    </build>
 </profile>

This is the easier and straightforward solution. The drawback is that the config properties must be kept in maven. If this does not bother you this is a good way to go.

Properties maven plugin

Pretty much the same thins as above. The difference consists in the fact that you can specify the properties in an external file that can be accessible by all the modules.

<build>
    <plugins>
       <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>properties-maven-plugin</artifactId>
          <version>1.0.0</version>
          <executions>
             <execution>
                <phase>initialize</phase>
                <goals>
                   <goal>read-project-properties</goal>
                </goals>
                <configuration>
                   <files>
                      <file>/Users/sergiu/global.properties</file>
                   </files>
               </configuration>
             </execution>
          </executions>
       </plugin>
    </plugins>
    <resources>
       <resource>
          <directory>src/main/resources</directory>
          <filtering>true</filtering>
       </resource>
    </resources>
 </build>

If you don’t want to use an external file instead of the file configuration you could go with

<urls>
   <url>file:///${env.HOME}/global.properties</url>
</urls>

It’s more cleaner and nicer.

build-helper-maven-plugin and maven-dependency-plugin

There’s another solution that I would not recommend but I will explain it whatsoever. But look at the bright side: you will learn two new maven plugins.

It involves that each module should have a copy of the properties. The helper plugin will create an artifact from the properties file and it will install it in the local repository. What’s important here is the fact that this must not apply for the sub-modules, so it must not be inherited.

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <version>1.3</version>
  <inherited>false</inherited>
  <executions>
     <execution>
        <id>attach-artifacts</id>
        <phase>package</phase>
        <goals>
           <goal>attach-artifact</goal>
        </goals>
        <configuration>
           <artifacts>
              <artifact>
                 <file>global.properties</file>
                 <type>properties</type>
                 <classifier>filter</classifier>
              </artifact>
            </artifacts>
          </configuration>
       </execution>
   </executions>
</plugin>

The dependency plugin downloads from the local repository the properties and copies them to each module. You will have lots of files, but you don’t need to synchronize them as it will be done automatically at each build.

<plugin>
   <artifactId>maven-dependency-plugin</artifactId>
   <executions>
      <execution>
         <id>copy</id>
         <phase>generate-sources</phase>
         <goals>
            <goal>copy</goal>
         </goals>
         <configuration>
            <artifactItems>
               <artifactItem>
                  <groupId>com.so</groupId>
                  <artifactId>maven</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <classifier>filter</classifier>
                  <type>properties</type>
                  <overWrite>false</overWrite>
                  <destFileName>global.properties</destFileName>
                </artifactItem>
             </artifactItems>
             <outputDirectory>
                ${project.basedir}
             </outputDirectory>
           </configuration>
        </execution>
    </executions>
 </plugin>

And finally the resources

 <filters>
    <filter>
       global.properties
    </filter>
 </filters>
 <resources>
    <resource>
       <directory>src/main/resources</directory>
       <filtering>true</filtering>
     </resource>
 </resources>

The drawback is that the files will remain there. You have to clean them up. Or if you don’t care leave them, they will be overwritten the next time the build will run.

SOURCE CODE

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s