Tuesday, January 13, 2009

Maven and TweetPublisher

One of my recent clients used Maven for builds, dependency management, and packaging so I figured I would give it real try and build something with it. Over the years I have hear numerous good things about Maven (really nice dependency management, consistent builds that don't require a huge ant file to work, simplicity) along with many bad things (complex when you try to do anything that is not standard, annoyance with the dictated conventions, difficulties managing the things managing your dependencies, etc). After trying it out on a couple very small and simple projects, I very much like the good points and am not convinced that the bad ones won't happen on a larger project.

For small stuff though, it is very nice.

If you follow the conventions, you can easily get a small project structure built out along with the ability to easily compile, test, and package/install without having to tell the build too anything about HOW to do it, just where/when.

One issue I did run into was related to packaging my app. My first test app was a simple CruiseControl plugin called TweetPublisher. A coworker wanted his Cruise server to tweet the status of each build ... so I set to work. After googling a while about how to write a publisher plugin for CruiseControl and finding a suitable Twitter API (Twitter4J) I was pretty much done.

** The latest versions have a much nicer interface and a very simple configuration than what I remember. :-)

The most basic maven project type produces a simple project which builds to a single jar. Perfect. With Eclipse's maven support it was dead simple to search for the cruise control api and twitter4j libraries, add them as dependencies, hack together some code and I was done. A short "mvn package" later and I had a jar with my code.

Only 1 problem.

Maven knows about my dependencies. It keeps them up to date (depending on how you configure them), downloads them when needed, uses them at compile and/or test time, etc. However, it does nothing out of the box to give them to you when you package. More simply, after a package goal is executed I have a jar with my code, which was compiled against my dependencies, but I have no clue what version it was compiled against or know where they are. This does not leave me in the situation I wanted: package should leave you with everything packaged so you could go use it in production. Not so.

After much googling and asking of coworkers no one could show me how to work with maven and dependencies short of writing my own archetype to do what I wanted.

Finally, I stumbed upon the assemble plugin bywhich I could define an "assembly" which would move my code around and copy all of its dependencies flattened into my code's .jar file. "mvn assembly:assembly" Viola! Done.

The very simplistic and untested code for tweetpublisher can be found here on github.

** The maven integration with NetBeans is also very nice.

No comments: