Archive for December, 2008

Reading more and more Apache mailing lists you often face tougher questions than you can possibly answer but also blatantly obvious (kinda lazy) questions which you’d like to answer in a very nasty and impolite way…

But then as usual “Someone’s did it” and here you are a couple of geek tools when you want to subtly insult an obvious guy:

http://letmegooglethatforyou.com/

and the more impolite

http://www.justfuckinggoogleit.com/

For example, do you want to know how to get more information about me and my work, well. click here if you dare ;)

When building a multimodule project in Maven, you often use POM inheritance to centralize plugin configuration and even executions. While centralized configuration is most of time fairly straightforward, the centralization of a plugin definition may force (or try to force) all or your submodules to follow the same *customized* build lifecycle which may even not apply to their packaging.

Think for example of having a cargo-maven-plugin configuration centralized for a project of 3 WAR projects and a JAR: I don’t think your appserver will be happy of receiving a your JAR as a deployable because you too smartly centralized a configuration which deploys after the packaging phase (I wouldn’t be happy either… ;) )

I solved this problem using profiles and working on the fact that a profile is inherited only when it’s defined also in the child pom, so not definying your plugin/plugins configuration in the main build.

I have a project structure composed of multiple (WAR and JAR) artifacts with cross dependencies and a super pom, something like:

project_root
|-- project_war1
|-- project_war2
|-- project_jar1

So basically I have a (for jboss using cargo) a super pom which defines all cargo plugin configuration in a profile called ‘deploy’ , which goes something like this:

<profile>
<!-- Profile to deploy to a local jboss instance, due to http://jira.codehaus.org/browse/CARGO-416 -->
<id>deploy</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<configuration>
<container>
<containerId>jboss4x</containerId>
<type>remote</type>
</container>
<configuration>
<type>runtime</type>
<properties>
<cargo.hostname>${cargo.hostname}</cargo.hostname>
<cargo.servlet.port>${cargo.servlet.port}</cargo.servlet.port>
<cargo.remote.password>${cargo.remote.password}</cargo.remote.password>
<cargo.remote.username>${cargo.remote.username}</cargo.remote.username>
</properties>
</configuration>
</configuration>
</plugin>
</plugins>
</build>
</profile>

Properties for this profile are configured in the superpom <properties> section, which goes something like:
<properties>
<!-- src/main/properties/<env>/application.properties is loaded for all subproject -->
<env>local</env>
<cargo.hostname>localhost</cargo.hostname>
<cargo.remote.password/>
<cargo.remote.username/>
<cargo.servlet.port>8080</cargo.servlet.port>
</properties>

Then, for every project which I’d like to deploy I configure in the specific child pom an profile with same id (“deploy” in our case) as this one which actually binds the specified plugin configuration to an actual lifecycle phase (typically in the pre-integration-test):


<profile>
<id>deploy</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<executions>
<execution>
<id>deploy</id>

<goals>
<goal>deployer-redeploy</goal>
</goals>
<phase>pre-integration-test</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

So basically running my build from the super pom by explicitly activating the plugin (because according to [1] inherited profiles only gets runĀ  if explicitly called by id with -P option and not with the other activation methods described here [2] ):

mvn clean install -P deploy

I get only the selected sub projects to be deployed with cargo while other projects (that do not inherit the profile) will only run the default build lifecycle (so with neither cargo configuaration nor binding it to a phase).

As a side note, I also use “environmental” profiles (using the <env> variable) so that different cargo (buildtime) properties and and application (runtime) properties are selected, e.g. :


<profile>
<id>accpt</id>
<properties>
<cargo.hostname>accpt.yourcompany.com</cargo.hostname>
<cargo.remote.password>accptJbossPassword</cargo.remote.password>
<cargo.remote.username>accptJbossUsername</cargo.remote.username>
<cargo.servlet.port>80</cargo.servlet.port>
<env>test</env>
</properties>
</profile>

which allows me to have my selected subprojects deployed to different environment by combining profiles:

mvn clean install -Pdeploy,accpt

I believe deploying and one of the things which maven does best, and hopefully this post can let you have a better understanding of which degree of configurability you can get with can get with this tool!

Enjoy!