The black magic inside Maven

It’s always interesting to see what your work looks from the outside, from the view of that people that you don’t know, not biased from your relationship.

I was reading  Sylvain Wallez Spring switching to Maven entry, where he exposes that Maven is too much black magic for him and prefers Ant. I think there’s a common basic mistake in his explanation, and I have already seen it in other places. If you are already an Ant user, of course it will look crystal clear after the years you have spent learning it, your opinion is also biased (not that I’m saying my opinion is not biased, that of course it is).

When talking about Ant you should also think about that first time user, that junior developer that haven’t left the IDE, and tell him that it’s easier to use Ant than Maven.

8 thoughts on “The black magic inside Maven

  1. I do tell those junior developers exactly that. Of course, make is easier than Ant. And shell scripts are easier than make. And I tell them to leave their IDE before I start talking about build systems. Good engineers look pop up the hood and inspect the engine before they drive off. Even if they’re quite junior.

    Sylvain’s build is easy because you can do

    svn co https://…/foo foo-trunk
    cd foo-trunk
    ant -projecthelp
    ant

    and then it works. Every. Time. It is also easy to find out how it works.

    find . -type f -name ‘*build*xml’ | xargs less

    And of course, there’s eclipse-based equivalent actions for the above.

    I’ve used and cursed ant, maven, gnu autotools, (GNU m|BSD m|p|n|r|c)ake, APT, RPM, emerge, and many more ‘software configuration management’ tools. Of all those tools, I’ll easily defend the assertion that Maven has “the most” magic in it; as much as your average IDE or more. It certainly has the most code in it.

    “Magic” in the sense that I tried to define long ago…

    http://dev.jicarilla.org/oldwiki/TooMuchMagic

    This is one of maven’s basic promises — the amount of stuff it can do for you “automagically” and “out of the box”. I don’t want automagically or out of the box, I want safe, controlled, consistent, predictable, repeatable, documented, with no surprises. Build systems should not make me go “wow” — they should make me yawn. `./configure && make && make install`. Yawn.

    Another core principle (in maven 2), that is used internally, is “inversion of control”. In this case, it has actually done that twice — once to keep plugins limited in scope, and the second time to make it real hard for the average developer to make maven do what he wants, instead of the other way around (for a valid use case where this is a big pain, see the maven2/gump integration woes).

    If I want to see under the covers of a make-based build, I type `less configure && less Makefile`. Yawn. If I want to see under the covers of a maven-based build, I have to circumvent the most non-standard classssloading mechanism on the planet (really, jboss is easier), sandbox the thing inside a jail that monitors and constrains HTTP traffic, attach a debugger, step through huge call-chains, and understand *several* XML-based inheritance mechanisms.

    Maven has various pros and various cons, but if I were you I would definitely not deny that it has a lot of black magic.

    I think the spring people will like maven 2. Spring is also not built for looking under the covers.

  2. It’s curious how do you state that all the commands you typed are “obvious” and “simple”, but for somebody that didn’t have contact with the tools it’s not different than using Maven.

  3. This is really strange why Maven’s people tend to discard other people comments and feedback saying “it was the same thing before, this is just because you know the other tool -ant- that make you more confortable with it”.

    Sory, Carlos, but this is definitively *not* a good attitude. Just face the facts : maven is far from being perfect and – IMHO – simply usable when it come sto complex projects.

    I have had at least three experiences with huge projects. The first one was a gigantic one (200 developpers, more than 300 sub-projects, something like 250 external dependencies). I built the complete build system with another guy, using ant for the first time, and without IVY, in three weeks, and it went smooth enough. Not a single problem we didn’t found a workaround for in more than 30 minutes. The person who maintained the build was able to handle it in half a day. Nobody complained about it. ANd trust me on that, 1) I’m not a genious and 2) it was the first time I wrote a ant built system.

    I’m a PMC on Apache Directory Server, and I’m working on this project for more than a year and a half. It’s a big project, but not that big. We witched from M1 to M2, and it was a real relief, because M1 was, hmmm, ok, I won’t tell what I think it was. M2 was completely different, in a sense it can be used. Let say than M2 should have been M1 (or may be M-0.8). So we switched back in december, AFAIR, and since then, even if things are less worse, it’s still incredibly hard to make it work on a daily basis. Today, I try to make it work, and, bang, as usual, problems. Not the kind of problems you can fix easily, no the kind of problems you can’t work out without stepping through the code. Who on earth can think that such a message :
    “Reason: Cannot find parent: org.apache.directory.server:build for project: null”
    can help ??? I don’t have a project named “null”, sorry for that.

    Ok, if I try the -X (X for debug, this is simply OBVIOUS!!!), I get another message (out of hundreds of lines of useless DEBUG things) :
    “org.apache.maven.lifecycle.LifecycleExecutionException: Unable to get dependency information: Unable to read the metadata file for artifact ‘org.apache.directory.server:apacheds-core-shared:jar’: Cannot find parent: org.apache.directory.server:build for project: null:apacheds-core-shared:jar:1.0.0

    Needless to say, this artifact is present on my local repo. And I’m trying to workaround one of the worst ‘feature’ of M, I’m trying to build offline. No way.

    I also experienced the same pain than Sylvain and Leo, on the very same project. It was simply unmanageable, when ant was set up and worked just fine in a couple of days.

    Ok, now, let’s face the reality. Maven may become a candidate for a build system, but it needs to fix some of the following problems :
    1) documentation as to be written. Not improved, just written. There is nothing we can seriously call documentation about maven.

    2) Maven must be able to work with local repos, without having to setup a HTTP server. I want to be able to svnup all the project, mvn install it offline, and ‘wham’, the project is built.

    3) Logs must be user friendly.

    Sory, but I’m really pissed off. I’m now using maven for more than one year, which is more than 20 times more than the time I spent working with ant, and I’m still thinking that ant is far beyond maven in term of usability. Just accept that. I’m an idiot. And idiots needs simple tools, not extraordinary tools for extraordinary people.

    “Write code for the average programmer”…

  4. Maven 2 is great because it makes the things that needs to be transparent, transparent. For example: what version of spring am I using? Are jasperreports sources being generated? etc etc.

    Maven 1… well, the idea was good, the implementation bad. To many have judged maven based on maven 1, do try m2…

    1) Documentation: in my opinion the problem is not the amount of documentation, but how it is structured:
    – the guides page isn’t structured, it’s just a unsorted list of guides. It’s hard to find anything in there.
    – the mergere m2 book, which is very good in my opinion, should be available as html, like the manual of spring is. It would be great if it’s in stores too, a paper copy can be handy.

    2) I agree: not a dumb-jar-override feature like in m1, but the ability to set your remote-and-local repo as a relative directory in the (parent) project. This way true “source assemblies” can be made that build offline directly.

    3) I agree: the logs are to verbose by default

  5. 4) “Error transferring file” should trigger 3 re-tries. If you have 10 developers coming from ant, have over 30 (direct and transitive) dependencies, and let them use m2, about 50% of them will get a failed build due to this error.
    Telling them to try the same command again to fix it, makes them distrust m2.

  6. Hey I’ve never said that Maven is perfect. It’s far from perfect and I have eyes to see the 600+ issues in jira.

    I think one of the problems is like OO vs procedural, you have to be aware that there is some magic behind.

    Some of the problems are related to plugins, and the fact that they are automatically used doesn’t make clear to the user that it’s not a maven problem, but the plugin. In Firefox you have to explicitly install plugins and users that see something failing don’t blame Firefox for the problems.

    It’s also not fair to blame maven for the problems with the repository. Linux has a good number of mirrors. We don’t. And ibiblio and maven.org have been forced to add protections to avoid people sucking up bandwith. That’s why if you try do download many files consecutively from the server the connection is blocked for some seconds. We need a network of mirrors and distribute the settings with those mirrors by default.

  7. If I want to see under the covers of a make-based build, I type `less configure && less Makefile`. Yawn. If I want to see under the covers of a maven-based build, I have to circumvent the most non-standard classssloading mechanism on the planet (really, jboss is easier), sandbox the thing inside a jail that monitors and constrains HTTP traffic, attach a debugger, step through huge call-chains, and understand *several* XML-based inheritance mechanisms.
    I agree: the logs are to verbose by default ………….

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s