20080128 Monday January 28, 2008

Don Brown Makes Maven 2 Not Suck Don Brown spent some time over the weekend Making Maven 2 not suck:

While there are a few (very important, I might add) things Maven 2 gets right, there are a bunch that just suck, yet I use it at my day job (Atlassian) and in Open Source work, so in true Open Source tradition, rather than continue bitching, I'm doing something about it. I'm embarking on a quest to fix all the bits of Maven 2 that really annoy me and waste my time. I hope to get most, if not all, of the changes back into the codebase, but my personal deliverable is a build of Maven 2 that doesn't suck.

On his blog, Don lists a number of improvements he hopes to make. This weekend, he implemented the first three, which concentrates on speeding up remote repository access and downloading of artifacts.

First up, tasks #1-3. I implemented these changes in a bored Sunday afternoon and saw a example build (Struts 2 core) go from 3 minutes, 26 seconds to 2 minutes even, so a little over 40% performance improvement.

Interested, I decided to try Don's improvements on AppFuse. Since it fetches seemingly hundreds of artifacts from Maven's central repository, it seemed like a good testing ground. With a clean repository (rm -r ~/.m2/repository), a 8 MB/sec internet connection and "mvn -Dmaven.test.skip", I achieved the following results with the stock version of Maven 2.0.8:

[INFO] Total time: 7 minutes 40 seconds
[INFO] Finished at: Mon Jan 28 09:02:11 MST 2008
[INFO] Final Memory: 55M/508M

With Don's improved uber-jar, I received the following results:

[INFO] Total time: 5 minutes 17 seconds
[INFO] Finished at: Mon Jan 28 09:10:56 MST 2008
[INFO] Final Memory: 56M/508M

460 vs. 317 seconds = a 31.1% improvement -- Nice work Don!

When he implements #4 (Should support artifacts checked into the SCM in the lib/ directory so no external repository needed), I'll be a much happier Maven consumer. I've always wanted the ability to bundle all of AppFuse's dependencies for offline use like we did in 1.9.x.

Don - I'll buy you numerous beverages in Vegas if you add the ability to run a Maven command to put all a project's dependencies in its lib directory too. ;-) Posted in Java at Jan 28 2008, 09:28:09 AM MST 7 Comments

Comments:

Matt,

How is your last request different from dependency:copy-dependencies?

Or do you mean a command that setup a local dependency library, so that option 4 above could work from that, and then refresh it periodically?

Posted by Yuri Schimke on January 28, 2008 at 11:01 AM MST #

Matt,

I've always wanted the ability to bundle all of AppFuse's dependencies for offline use like we did in 1.9.x.

If you do go that route for AppFuse, it would be nice if it was still an option to build with libraries that are in a local M2 repo.

As someone who often checks out source for projects I depend on, it has always been a pet peeve of mine when I have several copies of the same library floating around on disk because that library is committed along with source code or downloaded (e.g. via Ivy) into the project's directory hierarchy.

After all, how many copies of junit does one person need?

$ slocate junit.*jar | wc -l
68

...and it seems silly to have (and have to download a second time) megabytes of JARs that are already in my M2 repo:

du -sh projects/spring/2.0.6/lib
53M     projects/spring/2.0.6/lib

Anyhow, just my two cents.

--Brad

BTW, AppFuse is really nice...thank you for all the time you have put into it.

Posted by Brad Fritz on January 28, 2008 at 04:55 PM MST #

Yeah, dependency:copy-dependencies does the trick. I have been doing this for a while, specifically for bundling libs for executable jars.

Posted by 24.180.16.172 on January 29, 2008 at 12:36 AM MST #

Regarding your wish to bundle AppFuse, have you looked at the appassembler plugin ?

It will create a repo dir with all your dependencies for you, and also give you a possibility to create wrapper scripts for running examples and such.

http://mojo.codehaus.org/appassembler/appassembler-maven-plugin

/Kaare

Posted by Kaare Nilsen on January 29, 2008 at 02:24 AM MST #

I think Don Brown's implementation screws up my Jetty plugin. When running with his .jar jetty no loader start my app and blows up with a commons logging/log4j issue. That does not happen when using the .jar included with maven2.0.8

Posted by Matthew Payne on January 30, 2008 at 09:21 AM MST #

Matthew - this was reported by a few folks. You might try Don's updated version.

Posted by Matt Raible on January 30, 2008 at 11:08 AM MST #

This is quite timely. My biggest complaint about Maven dependency management is how it handles 3rd party jars that aren't in central (like mail.jar). I hack together a way to bundle 3rd-party jars into a maven sub-module, and used maven-antrun-plugin to install them. This way people can get a full installation of my code that relies on jars that aren't in central without needing to host my own public repository (contrary to how AppFuse handles it).

Here's a sample pom.xml that does this:
https://f8api.svn.sourceforge.net/svnroot/f8api/lib/pom.xml

This pom installs BrowserLauncher2 in the test phase from:
https://f8api.svn.sourceforge.net/svnroot/f8api/lib/src/test/resources/

This might not work for all open source projects due to license issues. IANAL and hosting a private repository seems to be the only other solution... which has much more overhead cost.

Posted by Jason Thrasher on February 09, 2008 at 01:18 PM MST #

Post a Comment:
  • HTML Syntax: Allowed