Maven is broken by design
blog.ltgt.net
blog.ltgt.net
I have been using Gradle now for almost 3 years and I can't be happier. The support is great, they roll out new features at a regular pace, it's fast and incremental build WORKS.
If you work in Java and you are still stuck with Maven, please, take a look at Gradle.
or ivy? i really haven't spent a lot of time toying with the various build systems. i tend to use ant until manual dependency management becomes ... unmanageable, then maven because i've apparently been brainwashed (i.e. i heard that they use maven at a lot of not-so-bad companies like thoughtworks).
after the article, i do like the suggestion of ivy+buck, neither of which i'd paid attention to before below the clamor of gradle trampling upon maven. before starting considerations along the lines "this software does not do X" or "it does X wrong," what about asking "what's a reasonable task for a single tool?" or more specifically,
"do we really want dependency management and builds handled by the same program?" my impulse is always to go for things that are as modular as possible, but perhaps the reflex response of "no" isn't correct for some reason obscured by lack of experience with the particular problem domain.
Gradle is a very powerful engine: we use it not only to build Java/Scala/Groovy code but also to drive our continuous integration/deployment cycle.
Again, it obviously depends on your requirements, but if you have to deal with large and complex projects, with lots of submodules to build, do consider Gradle.
I'd heard about that...as a non-Gradle Ivy user, when they started this, I asked two of their devs if they were going to basically write an "Ivy v2", submit their improvements/patches back to Ivy, etc.
Their response was, paraphrased, "absolutely not, we're building our own thing that is way more awesome and are not interesting in sharing". Which I found disappointing.
I know a clean break is easier, and that the Ivy codebase likely needs it, but Ivy could really have used their focus, and I think it would have benefited the wider Java ecosystem (as many non-Maven builds use Ivy to talk to Maven repos) instead of just Gradle itself.
A reliable, flexible and built on sane principles build system is required when dealing with large enterprisey projects.
How do you deal with versioned dependencies with Makefiles?
I'm not sure I'd call those things Rube Goldberg, it's just about depending on small libraries and having a reproducible build if it gets checked out on a CI machine and run.
As always, all about choosing the right tool for the job. If you can solve it cleanly with something simpler then you probably should. Something like Maven should only be used if you're really sure you actually need it, because otherwise it'll be a pain in the arse.
Having said that, splitting up "building" and "dependency management" can make things much simpler. Pip (python dependency manager) is incredibly simple, with the same kind of interface as apt, and if you've got a file with a list of dependencies you just tell it to install all of those. Then you can use whatever you want for the build process itself.
that's all over the java ecosystem, though, not just build tools: android and (i think?) spring both use several types of xml files to build. not saying it's not whacky, but it's def. prevalent.
http://www.thoughtworks.com/radar
In the Tools category, Gradle is "Adobt", while Maven is on "Hold". You can read the full report but I'll exert the relevant section:
"Language-based build tools like Gradle and Rake continue to offer finer-grained abstractions and more flexibility long term than XML and plug-in based tools like Ant and Maven. This allows them to grow gracefully as projects become more complex."
They had a more elaborate explanation in previous editions.
Having said this, I am also an Ant guy for simple projects. Too many scars from an Ant -> Maven migration. All pom.xml files ended up more complex than the original build.xml files, as Maven did not have proper support for the way the build was working before.
Why Everyone (Eventually) Hates (or Leaves) Maven : http://nealford.com/memeagora/2013/01/22/why_everyone_eventu...
I hated Maven until I tried the alternatives.
Gradle's purpose is to muscle in on the consulting / conference market for Ant, just as Grails's purpose as wrapper around Spring and Hibernate was initially to muscle in on their consulting businesses. Now they've hooked in enough users, their bait and switch business strategy is now to screw them for as much money as they can.
So if you use Gradle now, you'll pay the cost later on after Gradleware is sold to some GE or VMWare or EDS or Oracle.
Advocating Maven over Gradle is just a joke. I routinely do things in Gradle scripts that would require writing an whole new plugin to do in Maven.
Also the plugin ecosystem is not as wide as Gradle and SBT lacks a daemon, which makes builds 3X/4X faster in Gradle.
For Java builds (especially multi-modules builds) I still prefer Gradle.
Please, explain incomprehensible (or show an example)
To be fair, I'm doing things that are actually bad and wrong. (At which point ant-contrib is your last friend.) Ant does its actual job - makefiles for Java - pretty well once you know it. It's fine, y'know, probably pretty much complete.
To my eyes, the build scripts are pretty clear. I like the way the scripts are nicely organized using 'apply'. Maybe the only script that may look complex to someone starting with gradle is 'convention.gradle', but again, nothing impossibly hard to grasp for a developer.
I am not able to maintain these build scripts. This is the problem with DSLs in general. Maven isn't great, but its strength is standardization. I can look at any Maven pom and know what it does and make changes to it.
So as of a few years ago I too moved on to Gradle and have loved it.
But...
Language based build systems offer more expressiveness, but that is also more rope to hang yourself with if you get someone that doesn't know Gradle well doing tinkering with your build. For example we had someone add a custom checkstyle report to an Android project using Gradle. After their edits it stopped working because of the way the Android plugin was designed, bringing the build down for several hours. I came in, rewrote the Gradle build file to workaround the issue and it worked. Then I documented to the person why it hadn't worked and what I did to fix it.
As with the adoption of anything that gives you more rope to hang yourself with, it's a necessary piece of Gradle adoption to document your practices and train your team well.
Yeah, I documented it to Jim. That's a documenting he won't forget in a hurry, make no mistake.
Speeds things up a tonne.
http://blog.jetbrains.com/teamcity/2012/03/incremental-build...
By default, not only are you downloading a truck load of jars from the internet and running them locally, you are fetching them over an insecure channel!
[1]: http://maven.apache.org/guides/mini/guide-repository-ssl.htm...
What is HTTPS supposed to protect against in this case?
1) If you are using it to protect against snooping (why?!) then you must realise that the logs of many Maven repositories are effectively public (eg, I believe Apache committers can access the repo.maven logs pretty easily). For protection against snooping, use a local repo.
2) If you are expecting it to protect you against tampering in transport, then you are better off using a local repo (again). It's much more likely artifacts are tampered with at the remote repository rather than during the transport phase.
MITMing the public wifi at some coffee store is much easier than breaking into the official Maven repositories. At least I hope so. That's why RPM and DPKG packages are signed.
https://docs.sonatype.org/display/Repository/Sonatype+OSS+Ma...
Checking the actual signatures is another story ;).
He said much more likely the repo is tampered with. Easy to see why. This coffee shop scenario, they'd have to be targeting you personally and know your habits and your build and code they need to target you. In which case, https is far from your biggest concern.
Suddenly it's a lot less targeted attack. Moreover, the "victims" should be of much higher profile than your regular student downloading an obscure library whose repo you managed to hack.
Not that I think it's a particularly important security concern. However, when you are dealing with security concerns, the fact that you can't make up a situation that sounds bad enough doesn't mean that nobody else can't.
Update: sorry for the wording of the last sentence (non-native speaker here). I'll be glad if someone can correct it, because I can't figure out how to construct it to sound well.
For example, if you're using dodgy public wifi.
I agree that this example demonstrates that the Maven model is broken, but why would you structure your project like this rather than using another module or a submodule?
Maybe it's just lack of experience, but I highly prefer the rigidity of Maven projects compared to some of the messes that more expressive build systems allow.
Fight the Maven way and you'll end up in a mess.
tl;dr Understand the tools you use.
And sometimes, expressing it withing Maven's structure can lead to very slow builds, at least within my experience.
But perhaps I'm prejudiced; I hate maven, and have since my first experience with the Mvn 2 betas. You know when you see a new technology and you say, "this is painful now, but it's going to be worth it in the end?" I got the "this is painful now, and is only going to get worse as plugins depend on crazy ass behavior" feeling.
From everything I've seen since, I was right.
Please substantiate this, as I've been using Maven for quite a while and while it isn't perfect, it's not remotely painful. And I'm not talking about just for "build this jar" projects; most of my Android apps use Maven, too, as do a number of projects of mine that have native dependencies.
(I have no problem with Gradle, either; I just generally find most of the Maven complaining to be overblown.)
This is actually pretty simple with Ant, but becomes a nightmare trying to fit into a Maven structure.
Try to make sample webapp using Maven 2:
http://cocoon.apache.org/2.2/1159_1_1.html
I bet you will fail thanks to some random maven quirk:)
Spring is just some Java library, XML/XSLT is too simple to break anything.
Build reproducibility, which the author mentions is another issue. When I scrub the local mirror, the outcome can be completely different. Previously builds where working fine, when I scrub, everything breaks. This is mainly due to non-local dependencies which had been cached locally, but not replaced by most recent versions.
Another suspicion I have is that most build scripts are slapped together by googling until it works. Which of course is prone to being fragile (not to mention legal issues because it is opaque from where all stuff is pulled).
(I think that was one really nice thing about Ant--you could scan their manual/list of tasks and understand it very quickly.)
It seems a little odd using Ruby to build Java projects, but ironically I actually prefer that over Groovy.
This is horrible for me to say, but I'd like Groovy to gracefully go away--it lost the Java.next race (they were stubborn about dynamic typing for way too long) and I feel the only reason it's still around are for the admittedly nice frameworks it sprouted: Grails and Gradle.
The language itself is "meh", IMO.
...although it bothers me to no end that a dynamic language like Groovy had compile-time AST translation way before other (similarly mainstream) static languages like Scala.
Anyway. Gradle's momentum is impressive. Perhaps I can unlearn my Groovy bias.
https://plus.google.com/113945685385052458154/posts/7LHoGXQd...
It might be, but it still has it's merits. It was one of the first, and many other improved tools can't work without it's repositories.
I still like the IDE support for MVN: e.g. IntelliJ draws a nice dependency diagram that I find useful, even if I don't use Maven for something else in a project.
Maybe it's biggest mistake was that dependencies are global by default, and not local (like Node's NPM). If the dependency structure would have been local to a project, than many of the pain points I encountered with MVN in the past wouldn't have even existed.
I don't understand the local vs global dependency thing. What does NPM do differently from Maven?
As others have pointed out, NPM as a default is using "local" dependencies, (something I couldn't achieve with Maven easily).
"Local" means that the dependencies are in a sub-directory of the project, and that the transient dependencies are in sub-sub-directories too if needed.
With NPM, for us some of the implications of this are the following:
- being "self contained" I can check in a VCS and tag it "completely" or just zip it and send somewhere else, where it can be built "as it is", even on CI machines or production machines that have no Internet connection, nor do require a company internal Maven server.
- bugs and issues with building are reproducible. The "it builds on my machine" doesn't happen anymore. (Just search the different Apache mailing lists of how often this happened even in those open source projects). We had this problem very very often - to the point where several projects were migrated to ANT again.
- the availability of public Maven Repos, their mirrors and their sync is just bad (sometimes it's the corporate firewall/proxy the problem), so builds just fail all to often. Many companies don't use internal Maven Repo Mirror
- none where I worked had one, nor could we convince the management to finance one.
- very often (even visible in open source projects that build with Maven), there are some dependencies (maybe not from the start of the project, or maybe only temporarily) that are not available in the official repos, so need to be manually added. Doing this in a sub-directory is much easier, and it needs to be done only once, so others will just use it.
These are just a few issues that NPM seems to have been solved nicely (or just not having them because of of the "local" defaults).
Of course, there are also disadvantages of this "local" approach (like the redundant disk space usage - where the global one is very efficient), but from my experience all these disadvantages pale compared to the problems and frustration Maven brought in many projects that adopted it.
NPM, by default, will store the artifacts into a directory local to your project.
The maven way sounds nice, but it's easy to possible to screw things up between different projects. (Especially if you have mvn 2 and mvn 3 projects, ugh).
With NPM, everything is nice and separated.
Ivy is like a mix of the two (a global local cache, but pulls down to the local project), which IMHO, has the benefit of neither while getting the drawbacks of both.
I'm not a Java developer but it sounds like Maven stores all its dependencies globally (like in /usr/share/java). I'm not sure why that would be a "pain point" except making it hard to do different versions of the same library.
~/.m2/repository/com/foo/bar/1.0/bar.jar
~/.m2/repository/com/foo/bar/1.1/bar.jar
etc., which prevents you from pulling in version 1.0 when you intend 1.1.I have learned the hard way to read some of the source code of any external library or tool, no matter how widely accepted, in case the person who wrote it didn't attend the class on not using global variables or depending on undocumented internals of the JVM (I'm looking at you Log4j 2). Or in case they were just plain bonkers, like everyone who was involved in writing Spring.
What other language hasn't had multiple build solutions that were each "the one solution" at some point in time, only to be supplanted later?
How many build solutions are there for C++, or Ruby?
I'm the only developer in my shop using IntelliJ. Everyone else uses NetBeans. Whenever someone asks me how to setup NetBeans to handle builds as easily as I do, I have to shrug. Simple things, like switching to offline mode or turning off tests is a chore for NetBeans, but it is just a simple button click for me. If I want to target a specific build profile, I check a check box.
As I'm the one who maintains the build, configuring pom.xml files and setting up modules, I can see how it can become difficult for someone who doesn't have the experience I do. OTOH, I've yet to find a problem that stumps me when I'm doing things the Maven way, and I rather enjoy the flexibility and power it provides me. Once I've got the basics in place, maintaining the system is almost trivial.