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>  

2 comments:

  1. Nice, but is it really necessary to have all 60+ modules openend in Eclipse? Wouldn't it be much better to just open the modules you are currently working on?

    ReplyDelete
  2. Yes, of course, most of the time only a small part of the 60+ modules are open in Eclipse. But from time to time I need to open all of them (for example to perform some refactorings). Without the custom M2Eclipse configuration the workspace became nearly unusable in these cases.

    ReplyDelete

Note: Only a member of this blog may post a comment.