Wednesday, October 13, 2010

Maven Magic at W-JAX 2010

From November 15th to November 19th the W-JAX conference will be held in Munich. The W-JAX is one of the most popular Java developer conferences in Germany (topped probably only by the JAX which is bigger and held in spring. The W- stands for Winter :) ). If you happen to visit this conference, I would be excited to meet you in my session Maven Magie für Muggels (Maven Magic for Muggels) on Thursday, November 18th (as you probably might have guessed, the session language will be German).

Sunday, October 10, 2010

Maven 3.0 final: First impressions





I was impatiently waiting for Maven 3.0 for while now, and was very happy to read that the final release is available now. I did some quick tests with the final using a pretty large Maven 2.x project. It contains of 60+ modules and uses all sorts of plugins (e.g. ant, buildnumber, xmlbeans, jaxb, assembly, weblogic, jar, ear, all sorts of reporting plugins and of course all the standard ones). After switching the build process from Maven 2.2.1 to Maven 3.0 the normal lifecycle ran without any problems. I noticed, as with the RCs before, that Maven 3 is much less noisy than 2.2.1. I like that. The build time was about the same a before (about 13 minutes on my machine). As soon as I activated the new parallel build feature (mvn -T4 clean install) the build time reduced to about 9:30min. Cool! However, Maven complains that some of the plugins I use are not yet thread safe. The build completed without error anyhow, but I probably will have to check for plugin updates during the next weeks.

I did not yet try to run the site lifecycle. The site generation in Maven 3 has been completely reworked and is not compatible with Maven 2.x. To make this work, I will have to rework my POMs and use the new versions of the site plugin.

Summary: Maven 3.0 looks good. The internals of Maven 3 have more or less been completely refactored, so the high degree of backward compatibility is quite impressive. Of course, one could argue that Maven 3 offers not enough new user-visible features to justify a new major release. But in my opinion the refactored architecture and code base is much more important than new features.

Saturday, October 2, 2010

Configuring M2Eclipse for large projects





The M2Eclipse plugin integrates Maven in the Eclipse development environment. This integration is inherently tricky, since both Eclipse JDT and Maven implement a separate build process. Basically, what most developers would like to have is the amazingly fast incremental builder of JDT combined with some of the magic of Maven (i.e., dependency management, some plugin features, building jars/wars/ears, ...).

In the default configuration, M2Eclipse integrates some steps of a typical Maven build in the Eclipse workspace build. Other steps, like the compilation of Java classes, are still executed by Eclipse itself. Details about this configuration process can be found here.

The default approach works well in my experience for small to medium-sized projects. However, once you start to extend the Maven build lifecycle with additional plugins and you have to handle large projects, the default M2Eclipse configuration considerably slows down the workspace builds in Eclipse. Personally, I had severe problems with speed and heap consumption in a project that heavily uses plugins for XMLBeans, web service and JAX-B-generation. I have bound these plugins to the Maven lifecycle phases in my POMs (for example, to the phase generate-sources). In consequence, all these plugins got executed during the Eclipse workspace build. Apparently this was the case, because the default M2Eclipse configuration decided not to exclude those plugins from an Eclipse workspace build.

This default behavior is OK for small projects. It guarantees that for example the XMLBeans plugin is executed during an Eclipse build. The classes generated by the plugin will then be available for the rest of the build. However, in a large project scenario, I prefer to manually execute the XMLBeans plugins by executing for example mvn generate-sources. If I forget this step, Eclipse will miss the generated classes and report compilation failures. But obmitting the plugin from the workspace build significantly improves performance and reduces the heap space required for Eclipse.

The following custom M2Eclipse configuration worked well for me in a Maven project with 60+ modules. I just added it to the root POM of the project. Now, M2Eclipse only manages the Eclipse build path and copies resources (I need this because of the resource filterung feature) during normal workspace builds. This is OK for most of the development work. If I want to generate sources, build jar/war/ear-files or perform some other "extraordinary" build steps, I simply start Maven manually and refresh the Eclipse workspace afterwards.

<profiles>
  <profile>
    <id>m2e</id>
    <activation>
      <property><name>m2e.version</name></property>
    </activation>
    <build>
    <plugins>
      <plugin>
        <groupId>org.maven.ide.eclipse</groupId>
        <artifactId>lifecycle-mapping</artifactId>
        <version>0.10.0</version>
        <configuration>
          <mappingId>customizable</mappingId>
          <configurators>
            <configurator id="org.maven.ide.eclipse.jdt.javaConfigurator" />              
          </configurators>
          <mojoExecutions>
             <mojoExecution>
               org.apache.maven.plugins:maven-resources-plugin::
             </mojoExecution>
          </mojoExecutions>
        </configuration>
      </plugin>
    </plugins>
  </build>
 </profile>
</profiles>