Some Maven tips

First post of the year, here are some Maven tips you might find useful (or obvious for experienced users):

  • How to version commercial libraries in your SCM and use them as dependency ?

In case you don’t have your own central repository and you’d like to version your libraries in your SCM server, you can declare in your pom a repository like this :

<repository>
  <id>sipphonyrepo</id>
  <url>file:///${basedir}/../repository</url>
</repository>

The ‘repository’ directory should be versioned in your scm server but it also means that it should be checked out with your project. Also like any other repository, the dependencies will be copied in your local repository.

*How to just copy files ?

It might be useful on a development machine to copy files while installing an artifact, for instance you might want to copy a JBoss datasource file to a JBoss profile to make sure it’s deployed. For this you can use the Maven resource plugins. For instance the following plugin statement will copy the datasource file to your JBoss server’s default profile deployment directory if JBOSS_HOME environment library is defined (on the development machine) :
<profile>
<id>jboss.deploy</id>
<activation>
<property>
<name>env.JBOSS_HOME</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactid>maven-resources-plugin</artifactid>
<version>2.3</version>
<executions>
<execution>
<id>copy-ds</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>install</phase>
<configuration>
<outputdirectory>${env.JBOSS_HOME}/server/default/deploy</outputdirectory>
<resources>
<resource>
<directory>${basedir}</directory>
<includes>
<include>mysql-ds.xml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
  • How to perform complex build build logic ?

One solution would be to use profiles for that like in the above example. But it can quickly become cumbersome and limited. So a good option is to use Ant Maven plugin with ant-contribs dependency for control statements and loops or even better the groovy GMaven plugin (avoiding XML verbosity).Profiles have still the benefit of clearly identifying an intent in your build. The following command will list all profiles:

mvn help:all-profiles

If build logic can be extracted and used in different contexts, it’s time to create a plugin. It’s quite simple.

  • How to create an artifact of a zip or tar ?

One obvious solution is to use maven assembly plugin but if you need to add some custom logic during packaging, you could just create the zip or tar file with Ant maven plugin or groovy GMaven plugin and gant during the package phase. Then attach the file to your project with Maven build helper plugin and its attach-artifact goal to install it in your repository during the install phase. Once installed in your local repository, the zip or tar file can be become a dependency, just use the proper type in the dependency declaration.

<type>zip</type>
  • How to create a full delivery layout with multiple archetype ?

My advice for creating a comprehensive delivery directory structure would be to use a dedicated module, take advantage of ant,assembly and resource plugins for that. Struts2 has such a module : see the assembly module’s pom

Stat your commits

I recently discover the StatSCM maven plugin and it made our team day . It gives useful information about your Subversion activity (it supports other SCM systems) giving precise developers activity information or file statistics. It also generates some nice charts. I found it very useful to monitor what the team members commit: for instance we discovered that a trainee was the developer of the month (ranked by LOC commited) because he commited some very large csv test files.First to enable it, configure the dependency and declare the report in the reports section of your maven parent pom file:

<pom>
<build>
<plugins>
<plugin>
<groupid>net.sf</groupid>
<artifactid>stat-scm</artifactid>
<dependencies>
<dependency>
<groupid>net.sf</groupid>
<artifactid>stat-svn</artifactid>
<version>0.4.0-StatSCM</version>
</dependency>
<dependency>
<groupid>org.apache.maven.reporting</groupid>
<artifactid>maven-reporting-impl</artifactid>
<version>2.0.4</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupid>net.sf</groupid>
<artifactid>stat-scm</artifactid>
<configuration>
<excludes>
<exclude>**/*.csv</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</reporting>
</pom>

And here some charts produced, like the number of LOC commited by each developer:Number of lines of codeThe day commit activity:Commits activityOr the ration between files addition/modification:

Xfire with Jibx

I uploaded on Google code hosting an example of Webservices with Xfire (1.2.1) and Jibx (1.1) built with Maven2. Services are defined and accessed through a Spring application context.Have a look if you are interested in such a solution. The built server war file is for Weblogic server 8.1 but you should be able to run it in any servlet engine (>2.3).

Where does Xfire and Jibx combination shine ?

  • When you need to adapt XML schemas to your Java model. Let’s say your client provides you the XML schemas that define the contract of your Webservice and you need to adapt them to your buisness interfaces. Generally, business facades are not exposed directly as Webservices and an adapter layer is coded on top of it. The goal of the adapter layer is to transform simple types (arrays, primitive types, simplified objects) to more complex ones (the ones of your business interface). Here with Jibx you can code transformation directly in the mapping file. The WSDL is still dynamically generated. This “design by contract” approach could also be used.
  • Performance. Jibx is supposed to be efficient since it uses a stax XML parser to perform unmarshalling and instantiate your Java objects. But unfortunately I didn’t run any benchmark to confirm this and compare Jibx XML binding with other binding libraries (JAXB 2, XMLBeans, Castor, etc.)

Maven quick tip: adding a local dependency

Well after almost 6 months of silence, here’s a maven quick tipif you need to add a dependency on a library without adding ityour local maven repository.Define the dependency scope as system and the path to your library:

<dependency>
<groupid>weblogic</groupid>
<artifactid>weblogic</artifactid>
<version>8.1.4</version>
<scope>system</scope>
<systempath>
${weblogic.home}/server/lib/weblogic.jar
</systempath>
</dependency>

Then, either declare the weblogic.home property in your pom :

<properties>
<weblogic.home>c:/bea/weblogic81</weblogic.home>
</properties>

or add it to your settings.xml file by adding it to a default profile:

<profile>
<id>dev</id>
<properties>
<weblogic.home>C:/bea/weblogic81</weblogic.home>
</properties>
</profile>
<activeprofiles>
<activeprofile>dev</activeprofile>
</activeprofiles>

I am not yet fully committed to maven but it really shines for kickstartingJ2EE projects with artifacts and easily downloadable dependencies libraries.