apache_maven

In which order are Apache Maven profiles executed? are Apache Maven profiles ordered? how can you insured that Apache Maven profiles are activated in the right order?

You normally don’t end up with these questions, issues may only appear if

  • Some profiles are dependent each other,
  • Some profiles can not run in any order,

The use case behind this article is very simple, as I have a a continuous build were:

  • 5 web applications have  to be deployed into a remote tomcat in phase pre-integration-test,
  • 2 databases are created for test cases in phase generate-test-resources
  • 1 more database is created and needed for runtime, done in phase pre-integration-test
  • One of these web applications is able to inject data into database using web services, a profile do this in a profile in phase pre-integration-test
  • Selenium test cases are run in phase integration-test

All these steps are done using several Apache Maven pom profiles.

As it is a bit complicated to explain, lets first refresh some Apache Maven concepts

Apache Maven Goals

First you’ll have to keep in the mind Apache Maven lifecycle of modules, 21 goals out of the box:

  • Validate: validate the project is correct and all necessary information is available 
  • generate-sources: generate any source code for inclusion in compilation    
  • process-sources: process the source code, for example to filter any values    
  • generate-resources: generate resources for inclusion in the package    
  • process-resources: copy and process the resources into the destination directory, ready for packaging  
  • compile: compile the source code of the project    
  • process-classes: post-process the generated files from compilation, for example to do byte code enhancement on Java classes    
  • generate-test-sources: generate any test source code for inclusion in compilation
  • process-test-sources: process the test source code, for example to filter any values    
  • generate-test-resources : create resources for testing 
  • process-test-resources: copy and process the resources into the test destination directory    
  • test-compile: compile the test source code into the test destination directory    
  • test: run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed
  • prepare-package: perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package    
    package     take the compiled code and package it in its distributable format, such as a JAR    
    pre-integration-test: perform actions required before integration tests are executed. This may involve things such as setting up the required environment   
  • integration-test: process and deploy the package if necessary into an environment where integration tests can be run     (selenium test cases for example)
    post-integration-test: perform actions required after integration tests have been executed. This may including cleaning up the environment
  • verify     run any checks to verify the package is valid and meets quality criteria    
  • install     install the package into the local repository, for use as a dependency in other projects locally
  • deploy    code is deployed in artifactory or copied with ftp/scp for distribution

if you run the goal compile

mvn compile

on a simple multi module project, EVERY modules, one after the others,  will go through these phases
validate –> generate-sources –> process-sources –> generate-resources –> process-resources –> compile

Apache Maven reactor

The reactor is the part of Apache Maven that allows to execute a goal on a set of modules. As mentioned in the Apache Maven 1.x documentation on multi-modules builds, while modules are discreet unit of work, they can be gathered together using the reactor to build them simultaneously and:

The reactor determines the correct build order from the dependencies stated by each project in their respective project descriptors, and will then execute a stated set of goals. It can be used for both building projects and other goals, such as site generation.

The reactor is what makes multi-modules build possible: it computes the oriented graph of dependencies between modules, derive the build order from this graph and then execute goals on the modules. In other words, a "multi-modules build" is a "reactor build" and a "reactor build" is a "multi-modules build".

A simple multi modules project

For the sake of the exmaple, it has modules and profiles dependencies, in myProject/pom.xml


remoting
web
monitoring
common
services

or if you prefer the directory layout

myProject
    |_ pom.xml
    |_common
                 |_src
                 |_pom.xml
    |_ web
                 |_src
                 |_pom.xml
    |_ remoting
                 |_src
                 |_pom.xml
    |_ services
                 |_src
                 |_pom.xml
    |_ web
                 |_src
                 |_pom.xml

Lets assume also I would like to apply a list of profiles named

  • deployWeb, deploy the war module using cargo to a running tomcat instance
  • createDatabase, create a mysql database from scratch
  • runSelenium, run selenium test in phase integration test against web, assume database is created first
  • deployMonitoring, deploy the war module using cargo to a running tomcat instance, query the web at startup to get some infos.

Maven calculate the module order in reactor based on dependencies, as seen in logs file after running

mvn compile

[INFO] Reactor build order:  Unnamed - com.waltercedric:myproject:pom:0.0.1-SNAPSHOT
Unnamed - com.waltercedric:common:jar:0.0.1-SNAPSHOT
Unnamed - com.waltercedric:services:jar:0.0.1-SNAPSHOT
Unnamed - com.waltercedric:remoting:ear:0.0.1-SNAPSHOT
Unnamed - com.waltercedric:web:war:0.0.1-SNAPSHOT
Unnamed - com.waltercedric:monitoring:war:0.0.1-SNAPSHOT

Example

It start to be complicated when you provide a list of profile using Apache Maven command line like this

mvn post-integration-test –PdeployWeb,createDatabase,runSelenium,deployMonitoring

Chances are high that you will get profile executed in wrong order, too early or too late..

Rule 1 profiles are activated (if found) following reactor modules order

The first rule is that profiles are activated in module reactor order first, if myProject is first it will go through all 18 phases of  Apache Maven (from validate to post-integration-test in my example). Keep in mind also that the list of profiles will be applied to EVERY modules in EVERY phase starting at the top most module in reactor.

  • On modules myproject:
    •  Apache Maven will activate profiles PdeployWeb,createDatabase,runSelenium,deployMonitoring if one or more in the list are present in myproject/pom.xml
  • On modules common,
    • Apache Maven will activate profiles PdeployWeb,createDatabase,runSelenium,deployMonitoring if one or more in the list are present in common/pom.xml
  • and so on….

Rule 2  Reactor modules order “may” be changed

And now the tricky part, you can normally NOT change the module order in reactor, that’s ok but….

The order you define in myProject/pom.xml for   (=module aggregation) is still kept if the maven dependencies resolver don't see any problems

Not clear enough? look at the 2 examples below:

myProject/pom.xml mvn post-integration-test
Reactor build order (seen in logs)
Remarks

remoting
web
monitoring

common
services
  1. myProject
  2. common
  3. services
  4. remoting
  5. web
  6. monitoring
Maven adapt the order based on oriented graph of dependencies between modules.

remoting
monitoring
web

common
services
  1. myProject
  2. common
  3. services
  4. remoting
  5. monitoring
  6. web
Swapping module having no direct connections each others and having no conflicting dependencies to other may result in a different order in reactor!!!! and also different profile execution order.

Since Apache Maven has detected that the module monitoring and web have no connections, it accept the “human/natural” order found in myproject/pom.xml.

You may have to use this technique to distribute your profiles in pom.xml while still keeping the profile order execution under control.

Rule 3 Maven profile order is not taken from command line

The order of profile in the Apache Maven command line  –P list is not taken into account, running the expected profiles order

mvn post-integration-test –PdeployWeb,createDatabase,runSelenium,deployMonitoring

is equivalent to

mvn post-integration-test –PcreateDatabase,deployMonitoring, deployWeb,runSelenium

 

 

It is a good things, as it  simply make no sense across all modules and all Maven phase all combined together.

Rule 4 You can force profiles to run in an order if you SORT them accordingly into ONE pom.xml

Apache Maven recommend to place profiles into the module where they are acting.

If I want to insure that profiles deployWeb, createDatabase are run before the profiles runSelenium you have to keep that order in the pom.xml even if these profiles are acting in different Maven phase

  • createDatabase  may run in phase generate-test-resources 
  • deployWeb run in phase pre-integration-test
  • runSelenium run in phase integration-test

Considering the module ordering in reactor, a good pom.xml candidate could be web/pom.xml like this



    createDatabase
 


    deployWeb
 


    runSelenium
 

References

Profiles">http://maven.apache.org/pom.htmlProfiles

comments powered by Disqus

You might like also

Fetching artifact programmatically through REST/API in Nexus 3.x
There is so many case where it is desirable to pull down artifact from Sonatype Nexus using REST API, unfortunately Nexus 3.x Rest API are still under development... Some use cases in Nexus 2.x: You have a script that uses REST call to pull down the LATEST maven artifacts every night from Nexus and deploys them. You make extensive use of the REST API in all your puppet modules You use the Atlassian Puppet module for Nexus for creating repository, …
720 Days ago
git-branch-renamer-maven-plugin
When working with many feature/release/bugix/hotfix branches, it is a bad idea to start changing the pom version as this will create merge conflicts using pull request. this plugin allow you to keep in ALL branches the same pom version for all your projects, for example MASTER-SNAPSHOT the version will be derived from branch name automagically :-) You may want to read more first these 2 short articles Update Maven pom version on GIT checkout in TeamCity maven-release-plugin with GIT git-branch-renamer-maven-plugin …
732 Days ago
Review: Getting Started with Apache Maven by Russell Gold
Some time ago I was asked if I would like to write a review about one of the new video courses from Packt Publishing. It was "Getting Started with Apache Maven" http://bit.ly/1fycmpP by Russell Gold and since I have been using Maven for some years now (since 2007) and did publish some articles myself, I thought it would be nice to help them promote Apache Maven. The course is organized in eight chapters, forty videos with a length between two …
1919 Days ago
Update Maven pom version on GIT checkout in TeamCity
Here is a solution to the following problems Deriving Maven artifact version from GIT branch, Update pom version on GIT checkout automatically, Add the ability to use Pull request with Apache Maven. You have a workflow requirement that require you to have the artifact version of a module externally defined from the current branch in GIT. For example You want to start working on a new feature branch “feature-memory-improvement”, so you branch from master a new branch named feature/feature-memory-improvement Having …
1924 Days ago
Easily Compress Web Application Resources with EhCache
Resources such as JavaScript and CSS files can be compressed before being sent to the browser, improving network efficiencies and application load time in certain case. If you are not using Apache with mod_deflate or nginx in front of your web application, you may need to implement resources compression yourself…. Wait! don’t start writing your own filter to compress files like CSS, html, txt, javascript it is way more difficult than you think to properly handle http response headers and …
2406 Days ago
Tomcat 7 and Apache Maven
Here is 3 different way to control the lifetime a local Tomcat 7 container using Apache Maven. A typical scenario would be to start a servlet container prior to running integration tests (Selenium, SAHI or using any other framework you can think of ) With the following examples, you will be able to start an instance of Tomcat 7 running your web application in the pre-integration-test phase and stop the instance in the post-integration-test phase. You can also decide to …
2406 Days ago
Apache Maven copy local file to a remote server server using SSH
I will show you in an Apache Maven configuration file how to copy files to server each time the package phase is executed. Solution with Ant SCP task This snippet of code is a ready to use code that make use of Apache Ant task scp, Just put this snippet of code in your Maven module where the assembly is executed or anywhere else to push all tar.gz files to a server just run a maven mvn package, you can …
2594 Days ago
Apache M2Eclipse: Get rid of Duplicate resources when opening resources and types
In this small post, I’ll show you how to remove duplicated resources in the Open Resource view of Eclipse Eclipse – M2Eclipse – Subversive …
2600 Days ago
Apache Maven 3 Cookbook
&160; First a big thanks to Packt Publishing for having sent me this book to review! I did enjoy going through this book, while I did not learn a lot of new stuff (I am using Apache Maven daily since 2006!), I found it to be concise and would recommend it anytime to any of my colleagues. But let’s go through my review of this cookbook of over 50 recipes towards optimal Java Software Engineering with Maven 3: Apache Maven
2742 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 next coming days Grasp the fundamentals and extend Apache Maven 3 to meet your needs Implement engineering practices in your application development process with Apache Maven Collaboration techniques for Agile teams with Apache Maven Use Apache Maven with Java, Enterprise Frameworks, and various other cutting-edge technologies Develop for Google Web Toolkit, Google App Engine, and Android Platforms using Apache Maven You …
2788 Days ago