Saturday, June 01, 2013

Maven wrapper project - from Jar library to Maven plugin

Last month, the maven-wrapper project caught my attention on Github.

This morning, I had time to kill and I decided to take a closer look at it. I eventually played with it, forked it and added a quick and dirty feature "basic Maven plugin support".

The maven-wrapper project is a port of the Gradle wrapper to Maven.
It will download a Maven distribution automatically for you and set it up. Currently the project is just a library, more or less a work in progress at this time.

Again, I can't emphasize enough on the importance of build tools wrappers, especially on build machines. The release management folks doesn't need to follow any detailed setup guide, nor do they need to worry about managing multiple versions of the same build tools.

"Plugin-ifying" the maven-wrapper project
I did a very quick and dirty implementation of a Maven plugin, so that the code could be reused as a plugin in new or existing Maven project.

It was just a matter of adding few dependencies and writing a simple Mojo.
I eventually renamed the artifactId to have auto-mapping enabled in terms of namespace and goals.

Nowadays, it's possible to write Mojo descriptors with Java annotations instead of xdoclet-like comments.

I opened a pull request to merge the code in the original project few hours ago.

Maven wrapper plugin usage
Checkout the maven-wrapper forked project and run the Maven install goal.
mvn install

In another Maven project, add the following to your build->plugins section

    <build>
 ..
 
         <plugins>
   ..
      <plugin>
        <groupId>org.apache.maven</groupId>
        <artifactId>wrapper-maven-plugin</artifactId>
        <version>0.0.1-SNAPSHOT</version>
      </plugin>
   ..
    </plugins>
 ...
    </build>
    
Maven version compatibility
In terms of compilation, it should work with Maven 3.0.2 dependencies and above. The default distribution URL contains some maven versions from 2.0.9 to 3.0.5.
The distribution URL is not customizable automatically at this point (when generating the wrapper supporting files).


What would be nice to have in terms of configuration

  • POM driven customization of the default settings (launcher names and location, distribution URL). It's currently possible to do it manually though.
  • Token substitution inside the plugin when generating wrapper artifacts.


2 comments:

Endre Stølsvik said...

This seems really. One thing: With the Gradle wrapper, you can specify which version that will be downloaded in the task definition.

With this wrapper, it seems like to upgrade, I need to upgrade my actual local installation to get a new version? This seems .. not ideal: When I go over to using the wrapper, I would really like to delete my local installation, ideally forever (e.g. by bootstrapping a project using some other project I had laying around..!)

Yves Zoundi said...

While I understand what you mean in general, I'd personally not want to have older versions of the wrapper or Grails removed automatically.

Let's say that you have that legacy application running Grails 2.0.x versus a new project using Grails 2.3.x. You'd likely want to be able to run both projects with specific Grails versions.

The behaviour that you want is fine, when you're 'in control'. Well to generate a wrapper, it seems natural to me that some bootstrapping is needed.

I do delete all wrapper installations when I'm done migrating old projects, being able to control that behaviour is handy..

Again, build wrappers are mostly useful for build machines, even though you can run them yourself.

I know for example that modern versions of IntelliJ can build Gradle projects using the generated wrapper, which is neat, but also a bit unusual in terms of IDE support.