Sunday, September 12, 2010

gem-wrappers for maven artifacts: maven-gems

install maven3 on your system http://maven.apache.org/download.html

please add the following 'plugingroup' to your $HOME/.m2/settings.xml
<settings>
  <plugingroups>
    <plugingroup>de.saumya.mojo</plugingroup>
  </plugingroups>
  . . .
</settings>
otherwise just replace "gemify:xyz" with "de.saumya.mojo:gemify-maven-plugin:xyz" to use the examples below.

generating gems from maven artifacts

to get an idea what the plugin provides have a look at
$ mvn gemify:help -Ddetail

the simplest usecase is
$ mvn gemify:gemify -Dgemify.gemname=org.yaml.snakeyaml

where the groupId is 'org.yaml' and the artifactId is 'snakeyaml'. this produces target/org.yaml.snakeyaml-1.7.0-java.gem.
to generate the development dependencies as well execute:
$ mvn gemify:gemify -Dgemify.gemname=org.yaml.snakeyaml -Dgemify.development

to see what versions there are use:
$ mvn gemify:versions -Dgemify.gemname=org.yaml.snakeyaml
and pick the version you need:
$ mvn gemify:gemify -Dgemify.gemname=org.yaml.snakeyaml -Dgemify.version=1.6

generating gems from relocated maven artifacts

the artifact servletapi:servletapi does not exist anymore and the pom from maven central tells maven that the artifact has a new coordinate. per default the gemify goal just follows the relocation and creates the relocated artifact instead
$ gemify:gemify -Dgemify.gemname=servletapi.servletapi -Dgemify.version=2.3

but in case you need the original artifact you can force to generate it with the 'force' flag
$ gemify:gemify -Dgemify.gemname=servletapi.servletapi -Dgemify.version=2.3 -Dgemify.force

with this you get the relocated jar file wrapped into a gem with the given name.

using the maven-gems

first you need jruby ! let's look at the snakeyaml example from above. after having generated them you need to install them
$ gem install --ignore-dependencies target/*gem
to verify that installation you can do this with
$ gem install target/*gem
now you use the maven-gem like this:
require 'rubygems'
require 'java'
require 'maven/org.yaml/snakeyaml'
or if you need the development jars as well
require 'rubygems'
require 'java'
require 'maven/org.yaml/snakeyaml-dev'
this require will also require all the deep dependencies as well but leaving out the excluded dependencies from the original pom. i.e. it will create the same "classpath" as maven would do.

limitations
  • with the snakeyaml example the plugin took quite some time to generate the development gems. maybe it is a bug.
  • the transitive dependency hull is bigger than what maven uses, since maven has the notion of excluding certain children from a dependency. rubygem does not have such a features and takes all child dependencies from each dependency. this bigger hull can lead to version conflicts for rubygems which are not present in maven.
  • maven and rubygem have different ways of resolving the version of a dependency. a dependency resolution done by maven can work just fine when rubygems just can not resolve it. the following example produces 57 gem but when you install them you find 7 which rubygems can not install due to version conflicts:
    $ gemify:gemify -Dgemify.gemname=de.saumya.mojo.jruby-maven-plugins -Dgemify.version=0.12.0 -Dgemify.developement
even so there are quite some testcases for the plugin it is just a very small portion of the maven central which has over 100000 artifacts. if you came across an artifact which does not work please report at http://github.com/mkristian/jruby-maven-plugins/issues. the more feedback the better the plugin becomes !

thanx + enjoy