
Maven builds are an infinite cycle of despair - samstokes
http://kent.spillner.org/blog/work/2009/11/14/java-build-tools.html
======
mmastrac
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.

------
lrm242
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.

------
johnyzee
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).

~~~
sreque
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.

~~~
hello_moto
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.

~~~
sreque
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.

~~~
hello_moto
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.

~~~
sreque
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.

------
samstokes
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.

~~~
mthomas
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...](http://www.sonatype.com/products/maven/documentation/book-defguide)

~~~
samstokes
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.)

------
mainguy
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.

------
nicpottier
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

~~~
jsankey
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.

~~~
nicpottier
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.

~~~
zupatol
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.

------
rictic
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."

~~~
tentonova
_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.

~~~
rictic
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.

------
dysinger
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.

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

~~~
zenocon
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.

------
geebee
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.

------
trusko
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.

------
prodigal_erik
> 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?

~~~
tentonova
_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.

~~~
aaronkaplan
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.

~~~
zenocon
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.

~~~
aaronkaplan
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?

~~~
tentonova
_... 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."

~~~
prodigal_erik
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?

------
moe
Obligatory, the maven adoption curve:

<http://tech.puredanger.com/2009/01/28/maven-adoption-curve>

------
russell
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.

~~~
tentonova
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.

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

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

------
oliveoil
.. and the maven logo also looks horrible.

------
vlisivka
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.

