Wednesday, September 05, 2007

Is Maven too Complex and Bloated?

The set of features of maven seems cool, but maybe it is too complex to use in practise. Kind of ironic, when one of the goals was to make it dead-easy to setup builds of common Java artifacts.

Transitive dependencies not found
One common example is when transitive dependencies are not met. More often than I would like, I get into the problem of transitive dependencies of one of my dependencies cannot be found. Latest one was when using CXF, where it failed on finding some JAXB dependency in some specific version.

You could argue, that this is not mavens fault, but the fault of those deploying into the repository. But it appears to happen so often. Why is this? Maybe because it is too hard to do deployment correctly into it.

All the site/report generation crap
From the start, maven has taken on the role of building more than just our sources. With the reports and site plugin, it can generate documentation in html-format from various sources. It can also produce various reports and integrate them into the generated site.

Nice, but... It takes ages to process. It outputs a big load of crap when running, which hides actual problems it might notice on the way. The syntax to write the documentation sources in (xdocs, apt) are crap.

Why not just document on a wiki. Hey! People are already doing that all-over.

When dependencies clash
This can occur in many different forms. One example is what Jacob writes about in "A badly packaged project will break builds". The essence is, that transitive dependencies explodes in complexity. Some project might depend on spring-web-2.0.5 as a fine-grained dependency and another might depend upon a spring-2.0.4, which is a "all of spring" dependency. These are in different versions, and might clash and be incompatible. And maven cannot know what to do about it. It cannot even notice, as the artifactIds, "spring-web" and "spring", are different.

It is nice to be able to just depend on something declaratively, and automatically get a load of needed transitive dependencies with it. But, it is like pissing your pants. It warms right when you are doing it, but it quickly gets cold.

I think the whole dependencies problem is inherently complex. And very hard to put into a build tool for automatic management.

So, what to do?
Sadly, I have no really good advice on what to do then. I know for sure, that I cannot do better myself.

Sometimes, I wonder how far we could come, by doing our builds with:
What do you think?


Assaf Arkin said...

How about switching over to Buildr:

Mark said...

We use a pretty extensive maven deployment internally, and definitely worked through some of these pain points. However there are some ways to minimize the pain here.

1) on the transitive dependencies not being found, it's important to establish your own internal repository. Relying on the public ones is dangerous for the reasons you point out. If you want repeatable builds, you better control the inputs. That means your own repository.

2) On the generating all sorts of cruft... there's no reason you need to do that all the time. I usually run "mvn test install"... I rarely run mvn site. That said, if I want to see nice unit test output it's pretty simple to run "mvn surefire-report:report" which runs a pretty concise set of goals to just get me that report. I do agree that the formatting conventions around the customized doc are horrid.

3) On the dependency clashes, look at the convergence report. A lot. Also take a look at using dependency ranges.

On the whole, yes, maven is complicated. So are other build processes. What would you do with ant? Probably end up with a monolithic build. Not necessarily... you can componentize stuff with ant. However maven leads you (yanks you) towards componentization, whereas ant lets you build monolithic to your heart's content.

This is easier to maintain from a build/release perspective. But as build times creep up from a few seconds to a few minutes to hours you start killing your continuous integration processes. This in turn decreases productivity and quality. Eventually (in my experience) the maven overhead ends up being worth it.

Anonymous said...

sorry, can't switch to buildr because it sucks. Ruby is just the Perl of the 21 century.

Villane said...

Criticism about maven seems to pop up a lot every now and then, and it always baffles me because I have had very positive experiences with it, especially with Maven 2.

I must admit that it took A LOT of time and effort to move from Ant to Maven and then Maven 2, but it was worth it. Exactly because Maven nudges you towards structure and convention.

However, maybe the effects, especially emergent ones, are not seen in all environments: I work in an IT department that develops and manages many Java-based server applications. If all projects have similar structure, it makes things a hell of a lot easier: I can create a new IDE environment for any project in a couple of minutes with two commands:
cvs co project_name
mvn install eclipse:eclipse

We also use an internal repository, and frankly I don't know how we'd manage without that.

Peter said...

I've been using maven2 on large medium scale projects, about 8 modules in each project, for about 2 years now and I must say the conventions are really a bless comparing to all tastes of gigantic ant buildfiles I've seen. And indeed, make sure to have a in-house repository!

That said, maven2 has it's quirks. Main problem being the fact that documentations is both poor AND scattered.

mcwong said...

To Anonymous... ant and maven's bizarro XML/Java mishmash is better than Ruby for build definition how? Trying to use XML as a build programming language is awful. This is one of my big problems with Maven.

Take ant and maven. XML for basic project programming, but jump into Java for anything "custom". Writing plugins for every little thing sucks. Do I want to program every build? No, that's why I used maven in the first place. Do I want to jump through hoops when I need to program? No, that sucks too.

Using Ruby as an integrated build definition and programming language hardly seems like a step backwards. Maybe it's a worse build definition language than XML, but Ruby does a very decent job of looking like a DSL when it has to. And the direct integration of the programming language is gold. If you haven't looked at Rake I'd highly suggest checking it out

Scott said...

I'd have to agree with mark here. Dependency ranges are good. A local repository is a must.

I implemented maven2 for our company shortly after it came out of beta. I've since moved on to a shop dominated by monolithic ant builds. I miss maven! That said, I was a little surprised and disappointed by how many OSS projects made very little attempt to have real POMs in place when it was clear that many of them had switched to maven2 for the project builds.

Rob Di Marco said...

Once you get over the steep learning curve, Maven (and I mean Maven 2.x) is a boon for developers. This is especially true the more complex you dependencies are.

I agree with the recommendations of having a local repository, both for control of libraries, speed on update checks, and for the ability to add your own libraries (necessary if you have dependencies between projects).

To mcwong, in Maven 2, you basically just specify your project model in XML and no longer write any Ant like code. If you do need to do some odd manipulations, you can write it in a variety of languages, including writing build plugins in Ruby

mcwong said...

rob, the ruby plugins are interesting, but the development workflow is still complex. Unless I'm missing something (and I'll admit I'm not as up to date on Maven stuff as I could be), if I want to do something outside the norm, I still have to write a plugin (language isn't so relevant here), install it, deploy it, version it, add it to poms, etc. etc. etc.

Using buildr I write ruby code right in my project. If it's a one off, this is as easy as it gets. I haven't explored the inheritance/re-use facets of buildr, bet the one-off use case is much simpler.

Villane said...

mcwong, Rake/buildr sounds interesting. I agree that writing plug-ins/custom build tweaks is one of the things a Maven-like tool should make easier (but not so easy that it becomes too easy to ignore the conventions!). Currently I run ant targets from maven for this. I also have written one Maven plugin, but indeed the process is too complex to do that often.

ronen said...

Buildr is actually very cool see
my post
, using compact Ruby code is the way to go and not XML!
But then again its easier sometimes to be a sheep among the crowd instead of thinking originally by yourself.

Marcus Breese said...

I know that with Ant you end up with monolithic blobs of XML... but honestly I have always found that easier to deal with than Maven. Simply because I'm a control freak. I hated the idea of automatic dependency resolution just because of the problems that you mentioned. The solution is to run an in-house repository, but for me that just eliminated a good chunk of the features that would make me switch.

With Maven, you pretty much always do thing Maven's way. My problem was that I like things slightly different, and the task of customizing your project's config was always much higher of a price than I was willing to pay.

So for me, I've just stuck with Ant... occasionally I've used Ivy to retrieve depenencies, which is probably Maven's greatest contribution to the Java build process.

Per Olesen said...

Thanks for all the valuable input. Here are my collected comments on them:

I've thaught about having my own repo before, and actually we already have one. So far, it has only been used as a repo for dependencies that was in no public repo, typically due to licensing issues or to our own internal libs. Maybe it can be somewhat optimized by the use of a maven proxy (is anyone using that on m2!?).

I am not confident that the dependency convergence report will allow me anything but maybe detect, by manual thorough reading, if both spring-all-2.0.4 and spring-web-2.0.5 has entered the build. On dependency ranges, thats cool. I did not know, that they had this feature.

With respect to Buildr and Ruby, yes, I have considered it. But, I fear it doesn't solve the problems I am having with maven. Buildr is using the maven repo extensively too. If the problem is, that the dependency issue is an inherently complex problem, then Buildr wont solve my problems. I do like ruby, as a language, but it is still just a tool in the toolbox, that needs to match the problem. Buildr looks like a DSL for building. So is the POM. The pom xml is okay, as a DSL for me, actually. Having the ability to very easily jump into code for the building is a two-egged sword, I think. But okay, it is kind of cool :)

Eric said...

Pre: I would avoid maven-proxy like the plague. There is only one decent repository manager out there right now - and that is Proximity. Followed by Artifactory.

I have been frustrated by Maven's complexity since day one around writing plugins (in Java)... which is why I wrote the Ruby plugin to being with. But if you want to shove ruby code directly into the POM, you can (run goal).

Also, I dislike XML - and ther are quick ways around that. I'd love to be able to extend the POM reader to use other formats, but that's currently not possible.

Per Olesen said...

Thanks for the tip on "Proximity" and "Artifactory". I might try them some day.

mcwong said...

It's funny that you mention the horrid state of proxies... I've actually toyed around with writing a quick rails app that does it for us. It just doesn't seem hard, but we haven't found anything good. Thanks for the pointers on some potentially decent ones.