Admission: I was a bit rash to have declared Jihad on Maven back in December. (Is it ever wise to write “Jihad” on your blog?) Now 10 months later I’m still using Maven to build java and manage cross-java dependencies at build time. In the interest of peace and reconciliation let me say that Maven has really been performing amiably in its now reduced responsibility of invoking javac with a proper classpath, and packaging jars from the results. While this stalemate still seems less than ideal, I think I might continue to be able to get along with Maven, provided I don’t need to write any “plugins” for it, or wrestle with it for any less well trodden tasks.
Besides the war mongering, the original post does manage to outline the goals and associated set of issues around building gems for JRuby with java jars included. I’ve had good success with this strategy for releasing componentized systems to both dedicated colo and Amazon EC2 production environments in the last year. Enough so that investing some more time in build automation has become warranted. This comes in the form of a new Rake helper gem called TarPit, released as part of the RJack project. What was a very wet and copied around jars-in-gem rakefile recipe, can now be expressed in a short and declarative style. For example, the rjack-logback Rakefile:
require 'rjack-tarpit'
t = RJack::TarPit.new( 'rjack-logback', RJack::Logback::VERSION )
t.specify do |h|
h.developer( "David Kellum", "dek-oss@gravitext.com" )
h.extra_deps << [ 'rjack-slf4j', '~> 1.5.8' ]
h.rubyforge_name = "rjack"
h.remote_rdoc_dir = "logback"
end
t.jars = %w{ core classic access }.map do |n|
"logback-#{n}-#{ RJack::Logback::LOGBACK_VERSION }.jar"
end
file 'Manifest.txt' => [ "lib/#{t.name}/base.rb" ]
t.assembly_version = 1.0
t.define_tasks
The t.specify()
call wraps Hoe.spec()
(Hoe 2.x) where h
is the hoe object. All of the normal Hoe.spec options are still available, but TarPit importantly gains control of when in the Rake setup process Hoe.spec()
is actually called (hint: last in define_tasks, once any needed Manifest.txt update has already been performed.)
There are some strategy options on the initial TarPit.new
call, including: :jars_from_assembly
(where only Maven knows the versioned jars to be included) and :no_assembly
(when you are only including an internal jar built from source). In the :jars_from_assembly
case, given that Hoe still insists on a Manifest.txt complete on disk at start of Rake setup, you still need to manually run jrake manifest
as needed. If instead you can specify the jars, for example, as above from a ruby version number, then Manifest.txt will be built as needed and before any dependent hoe tasks.
In either case TarPit will setup Rake to run “mvn package” as a dependency whenever any java source files (src/**), pom.xml, or assembly.xml have been updated. The Maven produced jars, including “assembled” external jars are symlinked from the normal Maven target location to your lib/gemname/ directory.