top | item 16742858

Why I Moved Back from Gradle to Maven

174 points| ognyankulev | 8 years ago |blog.philipphauer.de

168 comments

order
[+] bborud|8 years ago|reply
Flexibility is not something I want in a build system. I want predictability and simplicity. "Flexibility" just means that the dumbest guy on the project will find sufficient rope to hang the whole team sooner or later.

That being said, "flexibility" is not special to Gradle. As long as there have been build systems there have been people who are too lazy to learn them and get "bright ideas". For instance I have no idea how many shellscript-infested build setups I've seen for C programs that could easily have been built using entirely standard Makefiles. If the author had bothered learning to use Makefiles.

[+] kodablah|8 years ago|reply
> Flexibility is not something I want in a build system. [...] "Flexibility" just means that the dumbest guy on the project will find sufficient rope to hang the whole team sooner or later.

We're on opposite sides here. I can control my team wrt rope and what not. But it's very hard to wrangle a build system to perform some advanced task you need without flexibility. I'd way rather have problems with the build system users than the build system authors. One is more easily fixable.

[+] acdha|8 years ago|reply
> "Flexibility" just means that the dumbest guy on the project will find sufficient rope to hang the whole team sooner or later.

In my experience, it's not dumb but clever which you should worry about — those are the ones who'll spend two weeks making something completely unmaintainable after reading someone's post about how some esoteric mathematically pure style delivered a 7% performance increase on an edge case.

[+] lmilcin|8 years ago|reply
Lack of flexibility means that it will only work for xx% of projects (supply an arbitrary value for xx but other than 100, by definition).

Then what it means, is that 100-xx percent of projects are going to be screwed up.

Not everybody lives in a nice world when the project is a single web application with 4 microservices and a shared library maintanied by a team of 5.

[+] wendelinsky|8 years ago|reply
Yo, new Gradle developer experience lead here. I fully empathize that it's much too difficult to wrap one's head around Gradle, so I want to share some things you might find interesting:

* The Gradle Kotlin DSL, which is nearing production-readiness, substantially improves the assistance/docs one gets through the IDE.

* However, the Kotlin DSL does not help with the large API surface and understanding of Gradle concepts, so I have been working on improved docs and best practices for the past few months.

* However, most folks don't or won't read docs, so additional tools will help users opt-in to strictness and quality checks that enforce best practices through the tool.

Even with all that, one can think of build tools like languages: one tool will never be able to suit all needs or projects. However, I intend the broaden the audience for Gradle by making it more accessible to a wider audience.

I'd love your help. My Twitter DMs are open @eriwen. DM me the 1 specific thing you would change about Gradle if you could.

[EDIT]: Fixed the formatting of the bullet points.

[+] kodablah|8 years ago|reply
The key point that Gradle needs to make clearer is to delineate between task creation and task execution and which code is running where. It is very confusing for people to know whether their code is going to execute at gradle file load or at task execution. People get confused that they can't just use the result of one task when setting the opts for another.

Edit: Also, I personally do the opposite route wrt the paradigm of the wrapper and the daemon. I don't commit a wrapper script and have people use a downloaded Gradle themselves. I also run --no-daemon on every manual execution for smaller projects. But I may not be normal here.

[+] Boxxed|8 years ago|reply
Personally, I think Gradle (and a whole lot of other software) needs to stop the whole convention-over-configuration idea. It makes things way too difficult to debug and learn from, all to save some one-time typing. Making everything implicit for the sake of simplicity is really just the opposite.
[+] solatic|8 years ago|reply
If you want ideas, you should check out Ratpack (a web framework for Groovy or Java) and the way the Ratpack.groovy DSL looks.

* Convention over configuration: implicit defaults for everything so the hello world example is very simple. If you try to create a new Java project in Gradle, not by copying and pasting or having the IDE autogenerate something for you, you're going to have a bad time. * Whenever you do want to add something, there is a clear place within the structure of the root ratpack{} closure to add it. The port goes under serverConfig, routes go under handlers, etc. You don't set the port under the routing handlers, that would make no sense. Very different than build.gradle which feels like a flat list of unrelated tasks. * Support for both anonymous code and for code which has been factored out. Of course Gradle supports this (factoring out buildscript dependencies instead of a flat build.gradle) but the experience makes you feel like you're playing around with Frankenstein's monster so hardly anybody ever does so. * Documentation provides examples through tests, which clearly show both the code and the expected outcome, and which Ratpack prioritized being able to express in a concise manner precisely so that it could be used for documentation purposes.

Could Ratpack have gotten rid of the root ratpack{} closure, the serverConfig and handlers and registry closures? Technically yes, they're not needed to namespace their children. But it would be so much less understandable.

[+] SureshG|8 years ago|reply
Using maven at work and Kotlin-DSL for my personal projects. One of the main pain points for using Kotlin DSL is the speed. It's order of magnitude slower than maven when used with IntelliJ IDE. Sometimes updating the `build.gradle.kts` file and reflecting the updates on IDE can take up to 5 mins. Apart from that really love the improvements made by Kotlin DSL. Finally, I can write the build script without going through the docs/stack overflow all the time.
[+] bsder|8 years ago|reply
Fix the documentation!

Focus on Android Studio because that's the only place people really use Gradle because they are forced to do so.

You need to create a LOT of Android Studio sample projects, and they need to be kept up to date for the various versions of Android Studio. If you did nothing but create "Hello World" in a zillion various flavors (Java, Kotlin, Scala, NDK, NDK with static library on different architectures, etc.) for people, that would be huge.

My specific beef is with NDK projects. Pulling in static libraries and compiling them with the NDK is a mix of magical keywords that sometimes materialize from some kind stranger via chat--generally because Gradle has to shove those keywords to something like CMake--which ALSO has an enormous learning curve.

[+] lmilcin|8 years ago|reply
I moved from Maven to Gradle about two years ago and I am not going to look back.

I understand the arguments made in article and I am the Gradle ninja in my project so I may have subjective view on the whole topic.

My points:

- Maven requires a lot of boilerplate for everything. Copy-paste. I need to instruct everybody on what to copy, where to paste, and how to edit and what they should not touch under any circumstances.

- Gradle... It's an environment for programmer! I just write a bunch of code in Kotlin so that all 100 projects have a bit of my custom DSL that suits the needs of our application. The code takes the DSL and does all the job behind the scenes and most developers don't need to understand it. They can, but they don't need to. This is how it is supposed to work -- in a large project people specialize and the application should be created in a way that will allow people to not have to understand everything.

- Maven is strictly declarative. If you can't find a plugin you either dig up Ant or you have to write your own plugin. Not nice.

- In Gradle I can have almost everything declarative but I have the freedom to drop this bit of logic where it is really needed.

- Don't try to make it too complex just because you start using Gradle. Great power comes with great responsibility.

If I wanted to change one thing in Gradle it would be for the Gradle project to focus on debugging. I really find it difficult to figure out why things fail even though I have almost 20 years of experience with various languages and a decade of very intimate experience with Java. Make it easier so that people are not put off.

[+] bitcharmer|8 years ago|reply
I'm neither Maven nor Gradle ninja. Just a senior software developer with 15+ years of experience...

> Maven requires a lot of boilerplate for everything. Copy-paste

I think you may be doing it wrong. Maven supports declaring project-wide or module-wide entities and their attributes at every level. Duplication or copy-paste is a sign of not understanding Maven

> Gradle... It's an environment for programmer

To me this is a counter-argument. When I need to understand project configuration I expect structure, not behaviour.

> If you can't find a plugin you either dig up Ant

Been doing Java software engineering for many different projects in various industries on all scales and I only had that problem once or twice.

[+] kovrik|8 years ago|reply
For me the main difference between Maven and Gradle is the way I read them.

Maven is declarative. Yes, it has some boilerplate, it may not look nice (I'm not a big fan of XML), but the main advantage for me is that I can read it easily and understand what it does. Because it just declares tasks. Similar to any other XML file or JSON or .properties. You just read it.

Reading Gradle, on the other hand, is more like reading a program. You can't just read it, you have to interpret it, you need to put effort in order to understand what this program does.

Yes, Gradle may be more flexible and less boilerplate, but personally I don't want to have another program (in another language) to just build my project.

[+] chapill|8 years ago|reply
>Gradle... It's an environment for programmer!

>Maven...you have to write your own plugin. Not nice.

>If I wanted to change one thing in Gradle it would be for the Gradle project to focus on debugging

You've just explained why I have no interest in Gradle. You're writing one off, undocumented, anonymous plugins, in a weird domain specific language, with debugging tools that aren't very good.

Worse, when the Gradle guru decides to leave the company for greener pastures, everyone else is left with a mess trying to figure out WTH that person was doing in all the build files.

[+] moocowtruck|8 years ago|reply
Honestly I can't believe people are arguing for maven over gradle... switched an entire very large org, all our java projects to gradle from various things over the last few years...everyone could not be happier. So much simpler, I only hear happiness from teams. Still run by a maven dumpster fire here and there though for the holdouts
[+] chvid|8 years ago|reply
I have been a user of make, Ant, Maven and Gradle. And Grunt, Gulp and now npm + webpack in the JavaScript-world. And of all these Maven is by far the better build tool.

To the creator of these tools: Try to remember that what you are creating is a support tool. A second act to the main development language. It is better if it is not general purpose, it is better if it is not turing complete, it is better if it is less powerful.

[+] andrewmcwatters|8 years ago|reply
I don't spend a whole lot of time in the Java world, just enough to take care of small requests. So, I've only experienced maybe half of those. Could you explain a few killer reasons why Maven is the better build tool?
[+] rhacker|8 years ago|reply
I spent a good 18 years in the Java coding stack. I adopted Maven when they just released version 2 and watched one of its evangelists talk at a JavaOne. Obviously now it's insane to think about a programming language that doesn't have a dependency manager (even C/C++ has Conan!).

After a long time fighting between what I liked best between Maven or Gradle I realized that the only thing I really needed was the parts to build the Java code. Things like Docker, Java code generation and a variety of other tasks you often do for releases, I finally figured out what I needed to do:

Make sure everyone on the team can run Bash. From there I could stop worrying about Windows users - Git Bash or Babun or some flavor of Cygwin. And things are even better with Linux Subsystem for Windows.

Now we simply have bash scripts that do all our one-offs that often were nightmares to accomplish in Gradle or Maven. Whether it is JAXB or Docker integration every maven/gradle plugin I ever used was 10 times harder than just bash.

When you start taking out all the other stuff it started to become clear that Gradle was winning out. With gradle I can build my code and get a variable that represents every JAR I need for a deployment into a Dockerfile containing folder. So that's where I personally ended up liking Gradle more - because I stopped depending on Maven and Gradle to do the other kitchen sink tasks.

[+] kovrik|8 years ago|reply
Honestly, I have the opposite opinion. I really don't like it when there are custom bash build scripts. And you have to figure out how they work and what they do. And how to pass additional parameters etc.

If you use Maven for your project, then I expect that if I run `mvn clean install` then it will build the project.

I think that is the whole point of standard build tools: that you can switch projects easily, run the same command and get the same result, and not waste time learning custom scripts for each project.

[+] lmm|8 years ago|reply
> Now we simply have bash scripts that do all our one-offs that often were nightmares to accomplish in Gradle or Maven. Whether it is JAXB or Docker integration every maven/gradle plugin I ever used was 10 times harder than just bash.

This is the opposite of my experience. Trying to get consistent behaviour out of bash scripts is a nightmare (every nontrivial bash script has an undocumented dependency on a particular version of some system tool, every time you try to build on a new machine you're rolling the dice). Maven plugins are versioned and (usually) tested, have sane defaults, and will Just Work (provided you're willing to roll with their defaults rather than fighting it).

[+] koolba|8 years ago|reply
I do something similar but with a Makefile as the top level. Every project I work on has a top level default that will fetch dependencies and build the project.

Lower level recipes are either one liners that invoke a project specific builder (ex: mvn package) or they invoke a separate bash script.

For complicated polyglot projects it works great as each component can use its own native tooling yet the top level is consistent.

[+] commandlinefan|8 years ago|reply
> Now we simply have bash scripts

Hm - I don't know about that. The biggest issue I found with Gradle was that it offered unlimited flexibility, and inevitably, somebody would mickey mouse sorcerer's apprentice the thing and stick something into the build script that didn't belong there. Although with enough effort you can do that in Maven, too, by the time you get to the point where you understand how to do that, you know better. I can't even imagine what sort of nightmares somebody with the even-more unlimited flexibility of a bash script could conjure up.

[+] derriz|8 years ago|reply
I can see the attraction in a build system based on a proper full featured programming language but I've never been tempted to try gradle because I believe the approach has a fundamental flaw. I.e. that it's impossible for IDEs to reliably extract useful project structure from the build description.

Even as a 25 year vi/vim user, I've succumbed to depending on IDEs more and more and I believe that any proposed build system has to easily support deep/rich integration with IDEs. This is theoretically impossible if the build system is effectively a general Turing-complete programming language. At best you will be able to provide brittle integration or else the IDE will have to dumbly treat the entire build process as a black box.

[+] dljsjr|8 years ago|reply
The integration with IDEA and Eclipse for Gradle is actually quite good, the only downside is that it's "one-way". That is to say that you can't use the IDE's GUI to configure your build.

Gradle enables this as a first-class citizen by providing a "Tooling API": https://docs.gradle.org/current/userguide/embedding.html

I know that Buildship, the Eclipse plugin that integrates Gradle, is actually worked on pretty heavily by Gradle contributors. I don't know about IDEA but that's the IDE that I use for Java development and the Gradle integration is very, very good.

[+] flukus|8 years ago|reply
I think that's a fundamental flaw of IDE's, they don't integrate with your development environment ;)

Something I just thought of but have yet to try, could we have a build script generate the project structure that an IDE can use and get the best of both worlds? Looking through my VS project files, 50% of it is stuff the make file would be doing, the other 50% is just a list of files and dependencies.

So let's say we generated these project files from a makefile, the IDE could still treat the build process as a black box but as part of executing that black box it gets all the information it needs for intellisense and debugging.

[+] tsvetkov|8 years ago|reply
I think it's not correct to say that Turing-completeness somehow prevents extracting project structure. If a build tool can extract that information, why IDE could not do that? In fact this is how Gradle projects are imported into Intellij and Eclipse: Gradle builds project model by running Groovy or Kotlin scripts, and then IDEs are working with declarative model. The real problem is working with scripts themselves: changing them automatically (applying refactorings), providing good completion, navigation, etc. The dynamic nature of Groovy makes it much harder for IDEs to provide good tooling, but even with statically typed Kotlin it is hard because Gradle APIs are very dynamic in nature (lots of string typed APIs). That does not mean that Turing-completeness prevents good tooling completely, it just requires more efforts and has some limits depending on a build tool`s software model.
[+] vbezhenar|8 years ago|reply
Idea works fine with non-trivial Gradle builds. It might be theoretically impossible, but on practice it works.
[+] hodgesrm|8 years ago|reply
This pretty much matches my experience. I resisted maven and the obscure pom.xml structure for a long time but eventually came around due to its excellent dependency management. Now that I understand maven it's hard to see how Gradle really improves on maven for basic Java projects.
[+] oftenwrong|8 years ago|reply
Seems "obscure", but it has a schema.
[+] eecc|8 years ago|reply
Well, excellent... their versioning is so broken that it had to become a de-facto standard to become accepted
[+] rb808|8 years ago|reply
> "Great Flexibility. Highly customizable build. You can easily create your own task and do whatever you want."

Usually this is a red flag for me. People's apps really aren't that different, if you're doing some weird customization its going to be a nightmare for the next guy to maintain.

[+] blktiger|8 years ago|reply
To me the beauty of Gradle is the complexity is hidden behind plugins so that the majority of builds are simple. I’d say a basic java build in gradle is simpler than the equivalent maven xml. The power is there for when you need it, but the basic plugins are easily configured for the basic stuff.
[+] vbezhenar|8 years ago|reply
If someone wants customization, he'll do it. If build tool will be on his way, he'll write PowerShell script, generating Perl script using M4 and you'll live in a some special level of a nightmare. Gradle has a lot of plugins, so typical builds are possible just like Maven (there might be exceptions, of course), but if you need to customize something, I think that being able to write an ad-hoc task with Gradle is better than not being able to do so.
[+] evanspa|8 years ago|reply
I delivered a session at JavaOne (2001?) on Ant (I was a whiz at it). Then, I had to learn Maven as it gained traction. I'm currently doing Android development, but I'm a little embarrassed to say that I don't really grok Gradle the way I do with Ant and Maven. I don't have anything against Gradle. I just don't want to spend another minute of my life learning another Java build tool. So, I stick to the Gradle defaults when creating a new project in Android Studio, and rely on SO and whatnot whenever I need to customize. Haven't been burned yet.
[+] ailideex|8 years ago|reply
The biggest challenge for me when I started using gradle was understanding groovy. Once you get groovy, you get gradle. And I really like groovy now that I get it.
[+] zmmmmm|8 years ago|reply
The whole article could be written about moving to maven. I still have no idea about how to do even trivial modifications to maven builds without googling them.

Fwiw, the need to learn groovy is a bit of a red herring because it doesn't help that much: I know groovy very well but I still find gradle confusing and have to google everything. My favourite build system of all time was gant, also based on groovy but a simple wrapper for ant. It had zero magic, was just a systematic wrapping of the ant API which itself was just a bunch of well documented useful build utilities. I found it very easy to use. The contrast between two build systems both based on the same dynamic language was very stark to me.

[+] ynezz|8 years ago|reply
> Gradle features: Great Performance

Did I missed the sarcasm tone? I've never experienced slower build systems then those used in Java world, like Gradle for example.

[+] vbezhenar|8 years ago|reply
Are you talking about Android? I'm using Gradle for traditional Java projects (standalone and web) and its performance was good, similar to Maven. I agree that Android plugin is very slow, but I think that it's not a Gradle to blame.
[+] sidlls|8 years ago|reply
People complain about C and C++ compile times but they don't hold a candle to that in Android-Java-land in my experience.
[+] dcposch|8 years ago|reply
I’m surprised nobody has mentioned buck or bazel in this thread.

At Addepar a few years ago, I transitioned a several-100-k LOC Java codebase from Gradle to buck. It was a fairly complex build including Jooq code gen.

Build times became much faster and flaky CI issues went away.

Today, I’d try Bazel— Buck only exists because ex-Google FB engineers had to recreate Googles amazing Blaze build system. Google has since released much of the original as open source, renaming to Bazel.

Maven and Gradle are both flaky, slow, and annoying to configure, in my experience.

[+] oftenwrong|8 years ago|reply
I went back to maven. I had trouble finding solutions to gradle issues when I got stuck. Maven solutions are easier to find. This will probably change as gradle becomes more popular.

I should add that I am no Java guru, so for me this is an important consideration. Still, the real Java gurus at my company are split on the issue. We have projects on both build systems.

[+] tunesmith|8 years ago|reply
One thing I haven't figured out in Gradle is that (in IntelliJ) in a maven pom, I can command-B to find the pom definition of a parent pom or a dependency. command-B in gradle doesn't do anything there. Anyone know the magic command?
[+] sytse|8 years ago|reply
We're planning to add a Maven compatible artifact repository to GitLab. I assume that will automatically also work with Gradle, or is there more to it?
[+] franzwong|8 years ago|reply
Recently I need to maintain a gradle script written by others. He created a Copy task, but he deleted some files inside. Every time I execute other tasks (not his task), those files are deleted. Finally I found that I need to create another Delete task and make a dependency to his task. I still don't understand those "doLast" thing very well.
[+] Traubenfuchs|8 years ago|reply
When I think of Gradle I think of the countless software development shacks where no one can understand or extend the Gradle configuration because someone, years ago, thought it would be cool to be hip and use Gradle instead of Maven, left the company and now nobody is interested in learning it.
[+] kodeninja|8 years ago|reply
Probably unrelated, but Java really needs to fix its Classpath Hell issues. On so many sufficiently large Java projects, you end up descending into the inclusion/exclusion madness with your build files because your app is inheriting `log4j` from 50 different libraries. Or the infamous xerces hell[1]. And fixing that in maven is not pretty :(.

[1] https://stackoverflow.com/questions/11677572/dealing-with-xe...

[+] dmix|8 years ago|reply
The advantages/drawbacks section could easily apply to Java as a language itself as much as to Gradle. Flexibility and performance traded for unending complexity, all-encompassing scope (creep), and the subsequent unpredictable behaviour/side-effects which the latter creates.

Which makes this backlash entirely unsurprising because the mainstream foundational tools will eventually end up reflecting the culture of the programming language, given enough development time and an unconstrained mandate seeking to keep the wider community happy.