Accessing Maven Properties From Your Code

The Maven POM hosts a number of implicit and explicit properties which you can use to flexibly configure your build. Besides a set of pre-defined properties such as the POM’s properties (e. g. ${project.version}), the operation system’s environment variables (${env.*}), or Java system properties (e.g. ${java.home}) you can define your own set of properties helping you decouple your build configuration from some particular environment.

Now it would be nice if you could access these properties directly from your source code. A common use case where this is desirable is to show the current version number of your build in some info field on your UI. In this post I’ll show you how to easily accomplish this using Maven’s resource filtering feature.

More specifically, it is Maven’s Resources Plugin which is responsible for including build properties into your resources. The trick is to enable resource filtering in your POM and have Maven substitute all variable references in your resources with their respective values.

In your POM, you enable resource filtering by specifying the directory (and optionally individual resources) whose contents should be filtered. The following configuration will include main.properties into the filtering process while excluding all other resource files from filtering:

<build>
  ...
  <resources>
    <!-- include main.properties -->
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
      <includes>
        <include>main.properties</include>
      </includes>
    </resource>

    <!-- exclude everything else from filtering -->
    <resource>
      <directory>src/main/resources</directory>
      <filtering>false</filtering>
      <excludes>
        <exclude>main.properties</exclude>
      </excludes>
    </resource>
    ...
  </resources>
  ...
</build>

Note that when you enable resource filtering only for individual files like in the example above, you also need to apply the second <resource>-section where you disable resource filtering for all other files. If you omit this section, resources not listed in the first include will not be processed by the resource plugin – they will thus be missing in your final build artifact! Of course you can alternatively enable resource filtering for all your resources like so:

 <resource>
  <directory>src/main/resources</directory>
  <filtering>true</filtering>
</resource>

Using the <exludes> and <includes> sections, you can further narrow down the set of files to be included into the filtering process.

The properties file main.properties can contain an entry referring to the version property of the POM or any other Maven property:

# main.properties
fooapp.current.version = ${project.version}

During Maven’s process-resources life-cycle phase, which is executed before the compile phase by default, this variable is substituted with the current value from the POM resulting in something like

# main.properties
fooapp.current.version = 1.0-SNAPSHOT

being copied to the build target. From this point, it is easy to load these filtered properties into your application to further process them there, for instance by displaying the current version number in your UI.

Short URL for this post: http://wp.me/p4nxik-IM
Roland Krüger

About Roland Krüger

Software Engineer at Orientation in Objects GmbH. Find me on Google+, follow me on Twitter.
This entry was posted in Build, config and deploy and tagged , . Bookmark the permalink.

3 Responses to Accessing Maven Properties From Your Code

  1. crism60 says:

    Thanks man, this helped a lot!

  2. Chris Passante says:

    This caused a build loop in Eclipse for me. If the maven and java builders are both enabled the java builder detects the change and kicks off and then Maven sees a change and kicks off…repeat. I wish I could find a work around because it is handy to have this feature.

    • Roland Krüger Roland Krüger says:

      Hey Chris, this is strange. This sounds to me like a misconfiguration in some place. The Java Builder should actually not kick in after Maven has processed the resources, since resource filtering should take place in src/main/resources (filtering the Java sources directly should be avoided anyway).

Leave a Reply