Wednesday, April 9, 2008

The Flaw with Maven's Transitive Dependencies

One of the key features in Maven2 is the support for transitive dependencies. While this is great and also necessary for running any code that depends on a jar that in turn depends on other jars, it has one serious flaw:

While transitive dependencies should be included in the classpath at runtime, those dependencies should not be included at compile time.

To illustrate why this is wrong, let's take an example:

We are developing module A, which depends on a third party jar, called "vacation-calculator", which in turn depends on Joda Time. Now, suppose that the developer of module A wants to use Joda Time. Happily he imports the Joda Time classes and everything works like a charm.

What happened here is that the developer introduced a new dependency, which will remain undocumented. There are two major problems with this:
  1. The day when the module A upgrades to a new version of the "vacation-calculator", which has replaced Joda Time with Schmoda Time, module A will no longer compile. Most likely, the developer will think that the new version of "vacation-calculator" broke backwards compatibility and confusion will ensue.
  2. If the developers decide that the "vacation-module" jar-file should be provided at runtime and thus change the scope to "provided", the code will no longer compile.
I think it would be fair to say that this is a major flaw in Maven's way of handling transitive dependencies. The argument that the developers should avoid using classes from transitive dependencies in their code is not convincing to me, since I have seen this happen too many times "by accident". A good build system should protect the developer from such accidents.

Having searched around quite a bit I have not found anyone else who points this out. Am I missing something or are people not seeing the forest for the trees?

Monday, October 8, 2007

Get Ugly Code Automatically with Maven2

The easiest way to piss me off on a Monday is to show me poorly formatted code. Maven2 did this for me "automagically", as the witty people call it. Look at this mess, that you can get by running the simple command mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app:

/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}

What resolution does Maven assume that the average developer is running? Must be about 320x200 to break the line after 20 characters.

Here are the three violations to Sun's code conventions that Maven managed to produce in these few lines:

1. The opening curly brace should go on the same line as the method.
2. A keyword followed by a parenthesis should be separated by a space.
3. A blank space should not be used between a method name and its opening parenthesis.

Thank you for Maven for ruining my Monday.

(Gotcha, super should actually not be followed by a white space, but it looks better with three violations than two, doesn't it.)