Joomla Extensions Demo

Support

Do not submit a bug report if you need technical support or have questions.

Forums

Post your suggestions ask for help in the community forums

Wiki

Visit the Wiki extensive and up to date documentation at your fingertips.

Contact Me

Missing images/links, any comments, suggestions, need help? Contact me

Skype

Need desperately help?
Skype Me™! But dont abuse of it!

Maven project filtering

User Rating:  / 0
PoorBest 

apache_maven

Depending on your project requirements/number of customers, you may have to support different target environment. This article will help you to make your Maven build a bit more portable in that sense. Maven can help you avoiding having stage dependent data across all your Maven projects/ modules very easily thanks to resources filtering.

Let’s imagine you want to build your software against many different runtime stack:

  • One is against your developer environment: eclipse, Tomcat, Mysql
  • One is running in a server with Tomcat, Mysql.
  • One is running in JBOSS 

And that your software is somehow configurable, can be through properties files, xml files, environment variables. Some of your configurations files are containing data that are depending on runtime (paths, password, login, connection settings to database, profiling/tuning settings)

Some guidelines about resources filtering

Rules 1  you can’t filter pom.xml use profile keys

if you have stage specific values pair key (login/password/paths) in pom.xml, you have to

  • use key/value pair properties in pom.xml (between <properties></properties>) or
  • use key/value pair properties that you override in pom.xml/settings.xml profiles or
  • use environment variables (not very efficient by the way and messy if you have too many)

Rules 2 you can filter resources

If you have stage specific values pair key (login/password/paths) in resources located at

  • src/main/ressources
  • src/test/resources
  • src/main/webapps
  • Anywhere else depending on your module archetype (an archetype is an helper to create a standardized Maven module)

Then Maven filtering is the solution for your issues.

Rules 3 profiles at rescue for new runtime

Profiles can be defined in settings.xml or pom.xml. Maven has a very good documentation online HERE. Never forget that many profiles can be active at a time, either because you want it (start build with –P profilename1, profilename2) or based on external conditions (can be OS, path, existence/absence of files, etc..)

Rules 4 Learn the hard way

ATTENTION: resources  in module with packaging pom are not filtered nor copied to target directories. Don’t use src/main/resources in modules with packaging pom as it wont be copied and filtered to /target

Tell Maven what to filter

In order to use filters you must specify a resource directory and set filtering to true. The remaining elements are not required. Activate filtering for all files found in /src/main/resources. All files which contains the denotation ${some.property.name} will be replaced by the building property value defined in <properties></properties>

Warning: Do not filter files with binary content like images, PDF, ZIP, GIF, JPG:  This will most likely result in corrupt output. If you have both text files and binary files as resources, you need to declare two mutually exclusive resource sets.

Notes

  • Resources filtering definition has to be place between <build> and </build> , If you have a Maven project and a parent pom, it may belong to that particular pom.xml in order to avoid redundant definitions in all child pom.
  • if you want to filter all *.xxx files at any level in directory hierarchy you need both *.xxx (current level) and **/*.xxx (any level deeper)
  • The first resource set defines the files to be filtered and the other resource set defines the files to copy unaltered as illustrated below:

 

       <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                  <include>*.properties</include>
                  <include>*.xml</include>
                  <include>**/*.xml</include>
                  <include>**/*.properties</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
            <excludes>
                <exclude>*.properties</exclude>
                  <exclude>*.xml</exclude>
                  <exclude>**/*.xml</exclude>
                  <exclude>**/*.properties</exclude>
            </excludes>
        </resource>    
        
        <resource>
            <directory>src/main/webapp/WEB-INF</directory>
            <filtering>true</filtering>
            <includes>
                <include>*.properties</include>
                  <include>*.xml</include>
                  <include>**/*.xml</include>
                  <include>**/*.properties</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/webapp/WEB-INF</directory>
            <filtering>false</filtering>
            <excludes>
                <exclude>*.properties</exclude>
                  <exclude>*.xml</exclude>
                  <exclude>**/*.xml</exclude>
                  <exclude>**/*.properties</exclude>
            </excludes>
        </resource>
    </resources>
    
    <testResources>
            <testResource>
            <directory>src/test/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>*.properties</include>
                  <include>*.xml</include>
                  <include>**/*.xml</include>
                  <include>**/*.properties</include>
            </includes>
        </testResource>
        <testResource>
            <directory>src/test/resources</directory>
            <filtering>false</filtering>
            <excludes>
                <exclude>*.properties</exclude>
                  <exclude>*.xml</exclude>
                  <exclude>**/*.xml</exclude>
                  <exclude>**/*.properties</exclude>
            </excludes>
        </testResource>
    </testResources>

 

With the above configuration, we tell Maven that any files .xml, .properties files has to be processed and filtered.

Give filter definitions to Maven

Maven let you define N filters per modules as default: you can have different filters for every pom.xml. This may create some management issues. You can still decide to use one file (per runtime stack, or per profile) but you’ll have to use an absolute path to it.

You can add a filters in your parent pom.xml by adding, I name these filter static, as they exist or not. You can also define dynamic filer in profile: the profile is active, the filter is added.

<filters>
        <filter>${filter1}</filter>
        <filter>${filter2}</filter>
        <filter>${filter3}</filter>
    </filters>

<filter> should be a file, usually a properties file that contains key/values pair that will be replaced at runtime.

Note here that in order to be able to build against different target runtime, I do use a profile key/value pair properties

Using Maven profiles to target multiple runtime environment

Definition and motivation of using profiles

Maven 2.0 goes to great lengths to ensure that builds are portable. Among other things, this means allowing build configuration inside the POM, avoiding all file system references (in inheritance, dependencies, and other places), and leaning much more heavily on the local repository to store the metadata needed to make this possible.

However, sometimes portability is not entirely possible. Under certain conditions, plugin may need to be configured with local file system paths. Under other circumstances, a slightly different dependency set will be required, and the project's artifact name may need to be adjusted slightly. And at still other times, you may even need to include a whole plugin in the build lifecycle depending on the detected build environment.

To address these circumstances, Maven 2.0 introduces the concept of a build profile. Profiles are specified using a subset of the elements available in the POM itself (plus one extra section), and are triggered in any of a variety of ways. They modify the POM at build time, and are meant to be used in complementary sets to give equivalent-but-different parameters for a set of target environments (providing, for example, the path of the app server root in the development, testing, and production environments). As such, profiles can easily lead to differing build results from different members of your team. However, used properly, profiles can be used while still preserving project portability. This will also minimize the use of -f option of maven which allows user to create another POM with different parameters or configuration to build which makes it more maintainable since it is running with one POM only. [from http://maven.apache.org/guides/introduction/introduction-to-profiles.html]

In eclipse, you may want also to run your application against a simplified stack, for example by using Tomcat/Mysql. I propose you a strategy that should be able to target many runtime.

First I replace all specific values through my application with keys ${aaaa.bbb.ccc} you determine the value of aaaa and bbb an ccc if you want to categorize them, but nothing stop you to just use ${aaa}

examples:

  • ${database.mysql.url}
  • ${log4j.default.level} but it can be also only
  • ${log4jdefaultlevel}

I create

  • a file in my Maven project at /etc/filter/eclipse.properties, I populate this file with keys/values that I use across all my configurations files in my application.
  • another file at /etc/filter/common.properties, I populate this file with keys/values that are independent of the runtime: can be logging information, timeout, etc..
  • another file at /etc/filter/jboss.properties, it contains all specific keys/values pair for that stage.

You will have to put keys and their values to have the following valid configurations

  • common.properties + jboss.properties –> replace all keys and make your application work in Jboss
  • common.properties + eclipse.properties –> replace all keys and make your application work in eclipse

I now define in settings.xml  the following profiles

  • id “Common” that will be always active, it make sense to have a common filter for all runtime or stack as long as you only put common key/values pair. The key ${filter1} has the value /etc/filter/common.properties
  • id “Eclipse” that will be active only If I detect an  eclipse environment,  the key ${filter2} has the value /etc/filter/eclipse.properties
  • id “Jboss” that will be not active as default, it will contains a properties key ${filter2} has the value /etc/filter/jboss.properties

Lets look at the profile “common” in your globals settings.xml (you can also add it to your pom.xml)

<profile>
    <id>common</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
        <filter1>${basedir}/etc/filter/common.properties</filter1>
    </properties>
</profile>

It define the filter1 and is always active

The “eclipse” profile, only active when eclipse.exe is detected activate another filter

<profile>
    <id>eclipse</id>
    <activation>
        <file>
            <exists>c:\eclipse\eclipse.exe</exists>
        </file>    
    </activation>
    <properties>
        <filter2>${basedir}/etc/filter/eclipse.properties</filter2>
    </properties>
</profile>

 

Note that the above filters are using ${basedir} reserved property, this is replaced by maven by the current artificatid (or module), so with the example above, you will have to create an etc/filter in all your modules (if you have a multi module setup). If you want to avoid this, you will have to use an absolute path instead of ${basedir}

The Jboss profile use the same principle as the “eclipse” profile, detect a file or a hostname (jbossbuildagent)

Make this run in Teamcity/Hudson/Bamboo

If you activate your profile based on activation settings, you will have nothing to do. If some of your profiles are not activated as default, don’t forget to add a –P profilename1, profilename2, .. in your maven goals list.

 

References

You might also like:
Apache Maven copy local file to a remote server server using
40 days ago
Apache Maven copy local file to a remote server server using
I will show you in an Apache Maven configuration file how to copy files to server each time the pa
Apache M2Eclipse: Get rid of Duplicate resources when openin
46 days ago
Apache M2Eclipse: Get rid of Duplicate resources when openin
In this small post, I’ll show you how to remove duplicated resources in the Open Resource view o
Apache Maven 3 Cookbook
188 days ago
Apache Maven 3 Cookbook
  First a big thanks to Packt Publishing for having sent me this book to review! I did enj
Apache Maven 3 Cookbook Review
234 days ago
Apache Maven 3 Cookbook Review
Thanks to Packt Publishing for having sent me this book to review. I will publish a review in the
List conflicting dependencies in the Maven reactor
350 days ago
List conflicting dependencies in the Maven reactor
The Maven Dependency Plugin among other things include a dependency:analyze-duplicate The depe
Break Maven build when there is a dependency conflict
350 days ago
Break Maven build when there is a dependency conflict
Scenarios You want to control Maven during dependency resolution and break the build i
OSGi-Bundle with the Maven-Bundle-Plugin
351 days ago
OSGi-Bundle with the Maven-Bundle-Plugin
OSGi (Open Service Gateway Initiative) is a Java framework for developing and deploying modu
Apache Maven Cargo deploy with Tomcat 7
361 days ago
Apache Maven Cargo deploy with Tomcat 7
Following the post about Deploy to Tomcat 6 using Maven, here is a ready to use example with the
blog comments powered by Disqus
Parent Category: Framework
Category: Apache Maven

Donations

Thank You for supporting my work
Subscribe to me on YouTube

Latest Articles

  • In this series of post I will outline some common techniques to help Joomla extensions development. As you know Jooml... ...
  • CedTag  has been updated to version 2.5.3 and correct a lot of bugs and contains some nice features. CedTag is t... ...
  • CedThumbnails has been updated to version 2.5.5 and contains 1 new features for both Joomla 1.7 and Joomla 2.5. For ex... ...
  • CedSmugmug  has been updated to version 2.5.2 and correct some bugs and contains some nice features. CedSmugmug&... ...
  • If you want an extra gigabyte of storage on your Dropbox account, the online cloud service invites you to compete in i... ...

Subscribe

Latest Comments

Popular Posts

rockettheme advertisement

dropbox logo

Help Us & Leave Feedback!

  • Do you have an excellent article idea you would like to read about here? Share it!
  • Do you have some interesting tips how we could improve our site?
  • Something missing here? Help us make this blog a better place, leave feedback!
We would love to hear from you! Be active! Write us now!