Awhile ago, I finally decided to bring the build process for one of my open source Java projects into the 21st century. Since I find Maven irritating, I converted the project to use Buildr, a Rake-based build tool that contains, among other things, Maven-style dependency management.
Life was good. I had a nice, simple build, with all the power of Ruby at my disposal, and without any need to edit XML, which sucks.
Then, someone reported a bug: The Buildr-generated POM did not contain dependencies. As the author of the bug report wrote:
Maybe they should be added to the POM, so my build system (I use Gradle) will be able to download all the required jars?
That, of course, is a perfectly reasonable request. As it happens, it was easier requested than accomplished.
After digging through numerous search results, as well as the Buildr source code, I finally came up with a solution. It’s a hack, requiring some local metaprogramming of Buildr’s Ruby code–a solution that is subject to breakage, when subsequent versions of Buildr are released.
But, for now, it gets the job done.
The first step was to install the
buildr-resolver gem. I chose to do that via
Bundler. That way, the
Gemfile becomes a manifest of all the third-party
gems my build requires.
1 2 3
The next step was to define some simple constants, at the top of my Buildr
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
Next, I created a small utility method that uses
buildr-resolver to write
1 2 3 4 5 6
With those constants in place, it was time for some monkey patching. I
tossed this hackery, as well as
make_pom, at the bottom of my
where it’s out of the way. Someday, I might get ambitious and put it in a gem.
The first patch, to
Buildr::Package, replaces the stock
Buildr::Package.package method to rebuild the POM after the regular Buildr
package function is run.
The second patch replaces Buildr’s
ActsAsArtifact.pom_xml method, which is
responsible for creating the XML for the POM. Ideally, I’d build the XML in-
memory, as the real
pom_xml does, instead of building my POM file and reading
its contents into memory; as it happens, Buildr will take that in-memory
XML I give it and overwrite the POM I just created. However,
buildr-resolver, and the
naether gem it uses under the covers, want a file
path, so I can’t substitute something like
So, a double-write of the file, it is. I can live with that, since this solution has the advantage of actually getting the job done.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
Buildfile for the project is
If there’s a cleaner, more reasonable way to get Buildr to produce a POM that contains dependencies, I’d love to hear about it. In the meantime, at least I was able to close the bug.