Sonatype

Previous: Appendix 3

Properties

A large portion of Maven's portability may be attributed to its use of properties. Like properties in Ant or variables in Make, Maven properties represent a value to be set at runtime (as opposed to a hardcoded value like a String or Integer). This is a list of the most common properties in Maven's core.

This is the base directory of the currently running project... where the POM file lives.

These properties corrospond to values in the system's settings.xml file. Note that the settings.xml file can be in the Maven installation /conf directory, as well as the current user's home directory (${user.home}) /.m2 directory. Their values are merged, with the user settings winning.

 settings.*
  localRepository
 Environment variable ... highly system specific, but some assumptions can often be made.
 env.*
   PATH
   M2_HOME
   JAVA_HOME

Java runtime's System.properties.

Filtering

Filtering is an integral part of Maven resources, and is a chief reason why resources are seperated from source code (the next is seperation of concerns). Filtering is simple to do in Maven:

<project>
  ...
  <build>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>

  <properties>
    <some.property.name>property value!</some.property.name>
  </properties>
  ...
</project>

Now any file under src/main/resources which contains the denotion ${some.property.name} will be replaced by the building property value... in the above case "property value!".

Tips and Tricks

Using maven-antrun-plugin to View Property Values

This is a simple way to view the values of any properties you may be curious. Echo the ${property.you.want} through the goal configuration. Note that it is important that you bind the antrun:run goal to a phase (validate is best) and execute that, rather than run the antrun:run goal directly. This is because the lifecycle may load properties that are not loaded when executing a goal in solarity.

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany</groupId>
  <artifactId>prop-test</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <executions>
          <execution>
            <phase>validate</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <tasks>
                <echo>$PATH=${env.PATH}</echo>
              </tasks>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Executing mvn validate yeilds the following results on my computer:

[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------------
[INFO] Building Unnamed - com.mycompany:prop-test:pom:1.0-SNAPSHOT
[INFO]    task-segment: [validate]
[INFO] ----------------------------------------------------------------------------
[INFO] [antrun:run {execution: default}]
[INFO] Executing tasks
     [echo] $PATH=/usr/local/bin:/sw/bin:/sw/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/maven-2.0.6/bin
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: < 1 second
[INFO] Finished at: Sat Apr 28 11:58:20 CDT 2007
[INFO] Final Memory: 2M/4M
[INFO] ------------------------------------------------------------------------

Synchronize versions/groups with an Inherited Property

Create a parent/multi-module POM with a specific version. Then for all inheriting projects, set their version via dependencyManagement as a property. For example:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.group</groupId>
  <artifactId>parent</artifactId>
  <version>1.1-alpha-4-SNAPSHOT</version>

  <modules>
    <module>sub-project-a</module>
    <module>sub-project-b</module>
  </modules>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>${groupId}</groupId>
        <artifactId>sub-project-a</artifactId>
        <version>${version}</version>
      </dependency>
      <dependency>
        <groupId>${groupId}</groupId>
        <artifactId>sub-project-b</artifactId>
        <version>${version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
  ...
</project>

This makes synchronizing versions easier, since inter-dependencies need not both with the task of synchronizing when the version changed, or bother with specifying groupIds.

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.mycompany.group</groupId>
    <artifactId>parent</artifactId>
    <version>1.1-alpha-4-SNAPSHOT</version>
  </parent>
  <artifactId>sub-project-a</artifactId>

  <dependencies>
    <dependency>
      <groupId>${groupId}</groupId>
      <artifactId>sub-project-b</artifactId>
    </dependency>
  </dependencies>
</project>

If you release using the maven-release-plugin, not only will all of your projects be incremeneted, but also all inter-dependencies will be synchronized as well.

GOTCHA: maven-release-plugin will not currently increment properties used as versions - eg. via the properties element. This may be fixed in later version of the plugin. For now, just stick with using the ${version} property.


Previous: Appendix 3