Hacker News new | past | comments | ask | show | jobs | submit login
Maven builds are an infinite cycle of despair (spillner.org)
42 points by samstokes on Jan 1, 2010 | hide | past | favorite | 50 comments



I've had a go at Maven a few times, hoping to make it work but I always run into the same issues:

1. It is very difficult to configure a hermetic Maven build that doesn't rely on external resources. There are third-party repository managers, but none of them worked well enough to replace the 'dependencies in SVN' model.

2. Maven artifacts were often far out of date. RedHat has its own Hibernate-focused repository now, but this wasn't always the case. I'd find myself trying to get the latest version of dbcp or another commons project to get a bugfix and finding that it wasn't packaged.

3. Support for multiple source-based projects that depend on each other felt bolted on. I can't remember the details, but you couldn't build more than one project from source without specifying a link to a parent project from each child project, which then referenced each of its children.

I've written and rewritten countless build systems (from batch files last millenium to Ant/NAnt/MSBuild) and they always end up being simple wrappers over javac/junit that manage transitive dependencies and build cycle ordering. The tricky part is ensuring that your IDE's dependencies match those in your build system.

I recommend Ivy as an alternative to straight Ant or Maven that does dependencies and ordering well, but doesn't require you to buy in to any special build philosophy: http://ant.apache.org/ivy/

Quick addendum: Ivy has its own quirks and is far too complex under the hood for my taste, but does the job well if you stick to straight dependency management. If you can avoid using anything on top of pure Ant scripts to build your project it'll make your life way easier.


Maven sucks, yes. But, right now, Maven is the best solution for Java projects. This is why:

If you use it right you end up with 1 source of truth for your build. Most Java IDEs support maven as a project model, and therefore you don't have to maintain two separate builds: one for the IDE and one for the build system--something that always leads to integration pain.

Ant as a tool isn't capable of this, since it doesn't really represent an project object model. Certainly IDEs can invoke Ant targets, but their non-standard nature make tight integration with the IDE hard, if not impossible.

There are several things that Maven could do to make the experience better. I suspect many of them will be addressed in 3.0; however, Maven as an experience has always sucked and I suspect will always suck. The broad based acceptance of the tool will give it a certain inertia that is likely going to be hard to overcome.


Maven sucks and everyone hates it, but uses it anyway because tragically there is no better alternative for large projects.

For me, the M2 plugin for Eclipse seals the deal as it makes the build files double as the IDE project files. One place for dependencies, one build cycle, this is how things should be.

I hate Maven with a passion, and use Ant any chance I get, but for very large multi-module projects, the strong points outweigh the negatives (although by an uncomfortably slim margin).


buildr combines the advantages of maven with the advantages of being built on top of rake and scales to managing multiple projects. Groovy's Grails build system and Scala's sbt also both look good to me, although I have not yet taken the time to try them. The only reason I can think of why systems like buildr aren't more popular than maven is that most Java developers appear too unwilling to learn a separate programming language and would instead rather torture themselves coding in painful XML-based DSL's like Maven.


I'm sorry to disagree with you but some people would rather invest their time to learn how to use Maven more effectively than to learn another programming language _and_ a new build system altogether.

Breadth vs Depth I suppose.


Check out this page: http://buildr.apache.org/quick_start.html. I will paste the most relevant text below.

"No knowledge of Ruby is assumed. Buildr is designed to be a very intuitive, very easy-to-use tool. You can create buildfiles which describe incredibly intricate projects, write custom tasks which do things far beyond Ant, and still never need to pick up more than a smattering of Ruby syntax."

Also, learning a new programming language isn't exactly a waste of time. When I learned Ruby it made me a far better Java programmer, for instance.


I think it depends. Is learning a new programming language a waste of time compare to getting better with the current programming language that you knew already?

While I'm learning Ruby, it did not make me a better Java programmer. I still suck at Java programming.

Reading books like Code Complete, Pragmatic Programmer, Clean Code, and reading Zen of Python (import this) help me to become a better programmer; but learning Python does not help me to become a better developer. Reading better code (other people's or projects's) do make me know more.

I finally understand what does it mean with the phrase "no matter what they tell you, it's always a people problem.". Languages have nothing to do with it.


Ruby introduced me to the ideas of first class functions, closures, and higher order functions and the design patterns that can be easily implemented using them. These same patterns can be implemented in Java, albeit with a much more verbose syntax. Most Java programmers are unaware of even these basic functional concepts and it shows because they end up copy-pasting a lot of code they don't have to and writing silly functions that can be easily implemented in terms of functions like map, filter, and reduce.

Yes, learning a new language can and does make you a better programmer if it introduces new concepts you can apply to other languages.


I'm interested if anyone at HN has good things to say about Maven. I've only scratched the surface of it, but my initial impressions have been:

* slow (even with -o to stop it downloading the internet every time)

* incredibly verbose, in both configuration and output during builds

* inflexible (but I've not really looked into plugins or advanced configuration)

* opaque and thinly documented even for basic needs

I did a fair amount with ant a few years ago and found it a much more pleasant experience. Maven seems to me stereotypical "enterprisey" software: a mediocre, moderately complex solution to an extremely complex problem.


Yes, Maven is a great tool in my opinion. With automatic dependency management and IDE integration it makes my life so much easier.

When I'm justifying including a third party (open source) library I ignore those that are not build with Maven and whose artifacts are not installed in the central repository.

* slow (even with -o to stop it downloading the internet every time)

At least you don't have to download everything manually, which is far, far more tedious. I'd rather let it to the tool to download dependencies.

* incredibly verbose, in both configuration and output during builds

I bet the simplest pom file will be shorter than the equal ant build script. And I personally don't care about output verbosity.

* inflexible (but I've not really looked into plugins or advanced configuration)

You can easily extend maven builds with ant scripts, which makes Maven as flexible as Ant.

*opaque and thinly documented even for basic needs

That may be the real issue.


Another maven user here.. and Ill tell you why its better than ant. Yes the convention over configuration is the reason. I can look at project structure, and know exactly where to find everything download dependencies and be up and productive in little time. Working at several different companies, with ant, you will find that different structures, trying to figure out where to get dependencies.. etc. Higher cost to start 2. The dependency issue the author is talking about( and seems like his main issue) is false. You should have a dedicated private repository like archiva, and you will never have issues. Just like large projects have a build manager, you should be managing dependencies yourself. 3. Very configurable, there are plenty of plugins, and you can write your own. 4. verbose ?? obviously you haven't see some major ant scripts. But yes it can get large in a single large project but the design convention would be to have a common pom, and break your project into modules.


Maven's main strength is standardization of the build combined with the dependency management that makes it easy to get a build going instantly without having to explicitly download libraries.

"slow" - can't say I've found that an issue when compared with Ant which I used to use.

"verbose" - in configuration I disagree - the more you put in your pom the less well you're using it. In output true, but I'm not sure why that's intrinsically a problem for you.

"inflexible" - absolutely not true. You can configure a plugin and Maven will go and download it for you - so as a user you can enhance the tool directly from the configuration file (e.g. I typically use a plugin to build database scripts from annotated classes).

"opaque" - yes, but there's method in that madness. It's programming by exception (how is my project different from the default?") as opposed to Ant's (mainly) explicit programming ("How exactly is this build bootstrapped?") Once you know the pro forma you can jump into any Maven project with an immediate understanding of its likely structure - very different from Ant where you basically need to read the build.xml files to know where everything lives.

"thinly documented" - Yep. The documentation is horrible and that's its biggest problem in my opinion.


I've found maven to be useful.

It standardizes the layout for the majority of java based projects.

It also lets me deal with dependencies in a decent manner. Maven should not be downloading dependencies on every build unless you are using SNAPSHOT versions.

There is a free book available: http://www.sonatype.com/products/maven/documentation/book-de...


Thanks very much for linking to the book - that will be very useful.

(I know Maven doesn't actually redownload everything each time, but it does seem to do something on the internet every time I build without -o; and even with -o, it still seems slow to get going. Might be project-specific / PEBCAK error though.)


+1 for maven for me. I've used it quite a bit. I've set up (fixed) a lot of really, really bad Ant builds. I have nothing against Ant, but it is easily abused, and can quickly degenerate into a complex mess.

Maven has a learning curve -- although it isn't huge. It can be frustrating sometimes, but if done right, it has so many advantages over other tools. There are free online books on the topic.

http://maven.apache.org/articles.html


The primary advantage of maven is that it gives a common structure to a project and it's dependencies. When working with multiple development teams, it gets very difficult to comprehend different projects when:

Project A has the source in /java/src Project B has the source in /main/src/java Project C has the source split in two different dirs: /src/test/java /src/main/java

worse yet, compile targets are called: project A -> compile project B -> build (note, the build target in project A will deploy the software to a stage server... good luck the first time you accidentally figure that out) project C -> go

and to maintain the version number of your package: Project A uses a file called /resources/projectA.properties with a key of "verno" Project B uses a file called /main/project.version Project C uses a property set in /build/build.properties

Maven, when used in a way to avoid the above mentioned problems, will typically have the source code structured the same way for every project.

Yes, it's java-centric yes, configuration can be a mess yes, documentation is redunkuluously poor

But it sure beats wracking your brain trying to figure out how to build a project when every new developer does it a different way.

PS. I've never experienced any of the performance/download problems other folks have mentioned. I think they might be doing something wrong.


Yes, Maven sucks, but for large projects the dependency management is rather nice. Java as a language is terribly dependency crazy, and being able to add three lines to your pom and get a new library in along with all its dependencies is a good thing. Though I'll now get flamed for not fully understanding every library dependency I'm importing in, which is fair, but hasn't been an issue for me for the three years I've been using Maven on various projects.

But that said, Maven has a build tool absolutely fucking sucks.. I much much prefer ant, and totally agree that mvn can be completely retarded and suck away a half day randomly.

If there was an ant alternative to deal with the library dependency problem then I'd be all for it. It seems that now that ibiblio exists, there should be ample opportunity to do this, basically rewrite mvn but use the existing repos.

But really, this single command makes mvn worth the trouble for me: % mvn -DdownloadSources=true -DdownloadJavadocs=true eclipse::eclipse

Give me another tool that does the same thing by me just specifying all my direct dependencies and version numbers and we can talk.

-Nic


There are at least two:

1) The Maven Ant tasks: http://maven.apache.org/ant-tasks/index.html 2) Ivy (now part of the Ant project): http://ant.apache.org/ivy/

We use Ant+Ivy, and although it has some quirks Ivy works well enough for dependencies.


Do either one of those actually pull down the appropriate sources and javadocs, and update my Eclipse classpath to include them with one command? I'm actually asking, not being snarky, as it doesn't look built in with Ivy and the few little projects claiming to do it don't look very active, what has been your experience?

As I said, that is the one big carrot still keeping me in mvn camp.


I've worked with ivy on a project a few years ago and the integration with eclipse worked fine for the classpath and sources. I didn't check about the javadocs.

Ivy is mainly a tool to work with ant, so it makes some sense that IDE integration is not in the same project, but as far as I could see, ivy and the eclipse plugin are written by the same people.

The eclipse plugin was actually one of the reasons for choosing ivy over maven, because at the time maven was moving to 2.0 and its eclipse plugin was not yet available or stable. The other reason was the documentation. At the time there seemed to be more documentation about ivy than about all functionalities of maven together.


As I mentioned elsewhere in the thread, buildr manages dependencies just like maven, including the ability to download sources and javadocs, and also has an ant integration library that works really well. Finally, buildr supports generating eclipse .classpath and .project files for eclipse, though the IDE integration obviously isn't as good because the project is younger and has less community support.


maven sucks ESPECIALLY on large, mission critical projects where repeatability and reliability are primary concerns



The java build world is perverse. Maven and Ant are imperative, highly limited, domain specific languages using XML for syntax.

If that doesn't set off just about every warning bell in your head, consider that Ant performs character set decoding and re-encoding when copying files. By default it will decode every file with your system's default character encoding and then re-encode it with the very same format. As far as I can tell all this can possibly do is introduce errors. When copying a binary file the best-case scenario is that your JVM throws a runtime error, but it's more likely that ant will silently corrupt the copy.

The Ant team's solution for this problem? You might reasonably expect that they would provide an option for binary files which does a byte by byte copy. Instead they suggest that you change an environment variable to an encoding which "does not seem to contain illegal character sequences."


The java build world is perverse. Maven and Ant are imperative, highly limited, domain specific languages using XML for syntax.

Maven is declarative, not imperative.

Ant is broken in many respects, but your provided example is not true. Ant only attempts re-encoding of a file if you specify text filters (aka variable/string replacement). It shouldn't be a surprise to anyone that string replacement breaks on binary files.


Interesting, thanks for setting me straight, it's good to know that the world is saner than it appeared. I recall some images being corrupted with the copy task in ant and that was the explanation that I received.


Seems like the typical reaction seen over and over. People love to hate maven. It always goes like this:

1) try maven but don't bother to RTFM 2) run away with your hair on fire and back to cave-man tools like Make, Rake & Ant 3) ignore dependency management 4) re-invent the build script for _EVERY_ project you start. 5) ??? 6) profit!!!

You only ever hear rants like this from people who don't spend the time to learn maven. It's not that hard. This is just rants.


Rant or not you hit the jackpot.

Most Maven users are "forced" to use it when they join a company or a project; they did not pick up Maven and learn it on their own time.


It sounds like the author has had quite a bit of experience with Maven and most likely has RTFM.


Sounds much more like a rant to me. The complaint about the war file size is a prime example. There are several quick / easy ways to analyze this and fix it / force it to generate exactly what you want. None of that is particularly advanced mvn black magic.

It sounds like he chose to just give up on the tool, spend a lot of time ranting about it on a blog, and go back to what he was familiar with.


I wish the author had been more specific about how Maven had failed him, especially regarding the "convoluted hackery" he mentions with the pom file...

So far, I haven't had much trouble with Maven. I've only done fairly straightforward web programming, with Spring, Struts 2, and Hibernate. It was a hassle to get it all set up, but I blame Spring for that, not Maven. The conventions seem to work very well, since you can just follow a standard directory structure.

I've found it particularly easy to use mvn war:war to create a war file, which is why I wish the author had elaborated a bit on why he needed to "reconfigure the conventions".

I have no argument with the author's preference for rake (and rails, for that matter), which is a far more pleasant environment than maven, spring, struts 2 (or something else), and hibernate, but of all this, Maven (I'm talking about Maven 2 here) was by far the most pleasant part of the stack for me.

One last thing - I promise I'm not being glib, feigning misunderstanding where I actually disagree. I'm pretty sure the author is a good programmer who has a legitimate gripe, and all I've done is basic CRUD programming with the stack I mentioned... but I definitely would like to hear some details.


Sure it not perfect

- very handy when starting new projects - easy to generate project files for Idea, Eclipse etc.

I used ant in the past, maybe it is more flexible, but also requires more work to set up initial build file. I find Maven just easier to use.

What I liked the most is consistency across project files, project structure.


> Automatically downloading unresolved dependencies makes your build process nondeterministic!

This. You need to be able to check in your build tools, and use them as they were to precisely repeat any build you've ever done, or you're risking bit rot. Ant is sort of painful but it works for this.

And if I want my dependencies to be preinstalled rather than checked in and bundled, I'd rather use yum so the rest of the world can reuse them too. Does Maven even support dependencies upon native (non-JVM) apps and libraries which are available for a given platform?


This. You need to be able to check in your build tools, and use them as they were to precisely repeat any build you've ever done, or you're risking bit rot.

It's not non-deterministic if your dependencies include an explicit version. You should not be using unversioned -SNAPSHOT dependencies for release builds.

And if I want my dependencies to be preinstalled rather than checked in and bundled, I'd rather use yum so the rest of the world can reuse them too. Does Maven even support dependencies upon native (non-JVM) apps and libraries which are available for a given platform?

No. Maven is intended to support easy-to-use bundled code dependencies, not to operate as a complete replacement UNIX packaging system.


I think you're right that in principle one can make a maven build deterministic, but in practice I have yet to see it done. Of course, that could just be a statement about the crowd I hang out with, but I think there are more fundamental problems. Wouldn't you have to specify explicit version numbers for not only your immediate dependencies, but also all transitive dependencies? Not that that's necessarily a bad thing in itself--regardless of what build system you use, if you want a reproducible build, one way or another you have to specify particular versions of all dependencies. But if you have to provide a configuration file that explicitly lists all direct and indirect dependencies, then what's the point of all the sophisticated transitive dependency management functionality we hear so much about?

Also, you didn't address the gp's complaint that the build tool will spontaneously update not only the project dependencies, but also itself. Some maven plugin developer out there can release a new version, and a project that compiled fine yesterday suddenly won't compile anymore. I'm sure there's a way to force it to use particular versions of the plugins as well, but by the time you explicitly list every transitive dependency and every plugin used in every phase of the lifecycle, you've got a really big configuration file, especially for a tool whose motto is "convention over configuration." Not to mention that if you accidentally forget to specify a version number for one of these potentially dozens of packages, maven will happily default to using the latest version, which makes your build secretly nondeterministic.


What you're missing here is sort of described in the RTFM. There are a couple very good, free books on maven that describe this, but in essence:

1) You absolutely should have your own local repository (e.g. Archiva). 2) You should use <dependencyManagement> and <pluginManagement> tags to force all projects to have the same versions o all deps and plugins. 3) Don't even try using snapshots unless you know what you are doing.


A local repository doesn't address the problems I mentioned above, it addresses a separate problem, namely the nondeterminism that comes from relying on external repositories that might not always be available. As for the <dependencyManagement> and <pluginManagement> tags, you didn't address my complaints: (1) if you have to explicitly list every dependency, including indirect ones, doesn't that negate the benefit of maven's transitive dependency management? [Edit: ok, not entirely, because it takes care of downloading the dependencies automatically. But one of the supposed arguments for maven is this: if your project depends on foo, and foo depends on bar and baz, you can just specify foo in the pom, and bar and baz will be pulled in automatically. But that's disingenuous: if you want your build to be deterministic, and of course you do, you still have to specify bar and baz explicitly.] And (2) if you forget to specify a version number for one of the dependencies, doesn't maven just default to the latest version at build time, thus becoming nondeterministic?


Yes it does. A good local repo will cache it. They act as mirrors. Once its cached, and your build is working fine, you can force all your developers to use only your local repo. This solves all non-determinism problems by allowing you to have complete control over all version of all deps and plugins.

Take a look at how to configure settings.xml to force your users to use only your local repo.

As far as <dependencyManagement> tags -- the point of that is to hard-code the version of foo in one spot, like this:

<dependencyManagement> <dependency> <groupId>com.example</groupId> <artifactId>foo</artifacatId> <version>1.1</version> <dependency> </dependencyManagement>

In child pom, you then have this if you need foo:

<dependency> <groupId>com.example</groupId> <artifactId>foo</artifactId> </depdendency>

And if you use something like Archiva, and force your users through it via settings.xml, then the first time someone downloads foo, Archiva gets it from the web, caches it, all other requests for foo go to Archiva. If foo has a transitive dependency, it will also get fetched from the web one time and cached in Archiva. Thus, guaranteeing that your build is deterministic -- unless you explicitly change foo/bar in Archiva yourself.


... if you forget to specify a version number for one of the dependencies, doesn't maven just default to the latest version at build time, thus becoming nondeterministic?

No.

... if you want your build to be deterministic, and of course you do, you still have to specify bar and baz explicitly

If you declare a dependency on non-snapshot foo, then it will also declare a dependency on non-snapshot bar, ergo, reproducible build.

Your comments seem to be the standard "I don't understand Maven, but I hear that it's broken."


The original complaint was

> the far more likely scenario is your project depends on a specific version of some other project which in turn depends on the LATEST version of some other project, so you still get hosed even when downstream providers do remember to bump versions!

so are you saying this is impossible (non-snapshot artifacts are somehow forbidden from depending on snapshot artifacts, which is not what was claimed), or that every author has to understand this and package their artifacts perfectly to prevent this from becoming an actual problem?


If there's no built-in interoperability, does it become my job to translate my maven dependency on foo:foo:jar:1.2.3 into a spec file dependency on foo-1.2pl3-4.noarch.rpm, and that my maven and rpm repositories each have a package which was built from the same code, and that all foo's dependencies match up in both places (recursively)? How do people actually use this stuff, short of just slopping jars around with rsync and abandoning all automatic management?



I am doing solo part time development (1 day/week) on a very large orphaned enterprise system. The builds are done using maven. The build takes about 15 minutes because maven is going off to various sites looking for no longer supported versions. I removed the dependencies; not much improvement. I tried mvn -o and the build dropped to 3 minutes. But war file was broken in mysterious ways. The currently irreducible step is 6 minutes to make a war out of a half-dozen project wars. So tossing maven is an urgent item on my plate.

The attractive part of maven is that it manages all the version dependencies for a large development team. For a solo developer it is way too much pain.


You don't need to toss out maven, you need to spend the effort learning a system with which you're unfamiliar to actually understand why your build is misconfigured and failing.


I am doing solo part time development on a medium size personal project which uses Maven as it's build system. It works just well for me, I have nothing bad to say about it.


I'm about to do a hobby project and Maven seems to be a good choice for me. In fact, I'm about to learn how to generate project related websites using Maven.


If the author doesn't want me to use it, why does he have 50 links to it in the text of his article?


To show that he is familiar with it and isn't just shooting from the hip.


.. and the maven logo also looks horrible.


Maven mixes many programming tools in one program: project building (make), dependency management(apt/yum), project management, etc.

I replaced maven by ant+RPM+yum+Hudson in one large project, and everybody is happy.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: