Sunday, May 10, 2009

The maven dependency plugin

The maven dependency plugin is amongst the most useful maven plugin. Every developer using maven2 should know the basics of this plugins.

What most developers like about this plugin is its very helpful goals to understand project dependencies. I am obviously talking about the dependency:resolve, dependency:tree and the various dependency:analyze goals. But this is not what I want to talk about in this post. I want to talk about the dependency:copy, the dependency:unpack goals and their counterpart the dependency:copy-dependencies and dependency:unpack-dependencies goals.

I often get asked at work what the difference is between those goals apart from the configuration syntax of course.

The major difference is that with one set of goals you specify which dependencies of the current module the plugin will act on while with the other set of goals you specify a collection of arbitrary artifacts. I know that doesn't sound like much of a difference until you understand about what maven calls the reactor.

To put it simply the reactor is the list of modules that maven is currently building. Maven for example uses the reactor to resolve in which order those modules should be built according to the dependencies they have on each other.

By now you probably understand better how those goals differ from each other. If you use the dependency:copy goal maven will not look in the reactor for the artifacts you want to copy. Therefore if you want to copy a module that is in the reactor you won't get the most up to date version (the one you are building right now) but a possibly completely out dated version coming from a repository somewhere. Another drawback is that the build will fail until the artifact exists in a repository somewhere (including the local repository). That is especially annoying if this artifact is the output of a module in the reactor of your current build and you're trying to build it for the first time.

On the contrary if you use the dependency:copy-dependencies goal you have to declare the artifact you want copied as a dependency. It means that you will get the artifact as you just built it - if it is part of the current maven reactor.

There is a definite advantage using the -dependencies version of those goals as then you make the most of maven strength in managing builds with inter-dependent modules. My rule is: whenever you can you should depend explicitly on a library using maven's dependency mechanism. This makes your build stronger and easier to understand.
Implicit dependencies on libraries through plugins makes things less obvious and harder to debug when a problem arises.