Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Why Move from Gradle to Maven (astradot.com)
31 points by foxgrover on Jan 6, 2021 | hide | past | favorite | 42 comments


This is an oddly unconvincing little write-up.

Firstly, learning gradle doesn't mean you are learning Maven simply because most dependencies use pom files for their metadata. I just means there's a little XML document embedded in your dependencies that 99% of developers never pay attention to, whether they're using Maven or ant or any other build tool. It's entirely irrelevant.

Secondly, Gradle does not require you to learn Groovy. Use Kotlin if that's your thing - I get the impression that's the preferred DSL nowadays anyways.

Sadly I think those are the only two reasons really presented. Neither is especially convincing. IDE support seems just fine for both platforms.

I actually _like_ Gradle and I think I could come up with a longer list of things about it that aggravate me. But either way, use whatever build system you want, and if, as stated, their projects have fairly humble requirements build-wise, I'm sure either system will get the job done.


Since I mentioned Gradle aggravations, I'll share a couple:

1. Bizarre and inscrutable syntax. They say things like "build scripts are just Groovy code", but some things, like how you define sourcesets or configurations, don't look like anything that should parse, much less compile, in any C-like language. They're doing some fancy meta-programming stuff behind the scenes to keep things light and simple, but it really isolates (and possibly alienates) developers from exactly what's happening under the covers. The Kotlin DSL seems to help make it more clear what's going on, but I haven't used it much yet.

Having used Gradle for years, it is strangely off-putting how unsure I often am about whether to put a colon in a particular place or a comma, or if something should be in parenthesis.

2. If you want to do anything beyond what's documented you can get into a bit of trouble, and if you find answers more than a couple of years old there's a good chance they often won't work. Making sense of the DSL documentation is sometimes a little tricky.

Beyond that, I would dare say it's the least awful option for building for the JVM. Their documentation is very comprehensive, it's fast, they are very fair about providing deprecation warnings before features are removed. It's rare I find a case where I'd like to use some external library that has a Maven plugin but no Gradle support.


It's regular Groovy. Look at this unrelated library that is doing the same thing. Toggle from Groovy to see what it is doing behind the scenes. https://spreadsheet.dsl.builders/#_outlines

The first parameter in a Groovy closure it will be treated as "this" and any function you call can applied to "this" first.

sourceSets is just a function that accepts a closure whose first parameter is sourceSets (this is implementation specific). If you call main inside the closure then groovy will call sourceSets.main and set that property.

What you are probably complaining about is that parenthesis are optional in two contexts. Your function fits on a single line or your last parameter is a closure (curly braces)

You're also confused by the fact that you can pass a map as a parameter by simply doing "function key1: name1, key2: name2".


I have used both and like maven better. I do not like the idea of using a turing complete language to define your builds. Every Gradle project I worked on eventually devolved into build code insanity.

Give me any maven project and I can figure out how to build it and modify dependencies and stuff within minutes.

With Gradle, it can be an hour of messing with code if the project maintainers got creative.

I've never had a project that maven, with it's mostly fixed build setup, couldn't handle. Having a turing complete build script is like turing complete cooking recipes. Pointless and definitely going to create more problems than it solves


For practical reasons, I have to admit gradle is better than maven. Gradle is least bad.

However, I do have to say turing completeness in a build system is an anti-goal for me. You shouldn't have to guess if your build will halt. I've seen terrible things done in builds, and most importantly, static analysis is the point of these systems... it's what makes IDEs able to work.

From what I understand the turing complete code in gradle merely builds the model, which the IDE (or gradle) can then use to run the build, but still...

Finally, if you do have to use a turing complete language, it sure would be nice to use one with static types. I know groovy syntax reasonably well, but without auto-complete on my build scripts (less my project), except at run time it's crazy hard to know what to type. And god forbid you have to debug it. I've added for loops to print out every variable, and for god sakes I've even had to attach a debugger to my build to figure out what it's doing. That's just nuts.

[edit] And finally, let's not ignore that fact that groovy tries very hard with it's closure syntax to look like JSON, so many developers paste in code from stack overflow and think it's actually configuration. (I actually kind of like that for other uses of groovy).

[edit2] apparently they know it's so bad gradle (the "gr" comes from "groovy") now uses kotlin for it's own build scripts (like on their github repo). If anyone's done gradle with kotlin I'd love to know if it actually helps.


Yes. The Kotlin DSL helps immensely- probably mostly because the IDE can actually autocomplete the various closures and attributes.

A few things get a bit more verbose/ugly but mostly it’s similar.


Thanks! If the build model is statically analyzable I can see how that would help a lot.

I'll generate my next project with gradle/kotlin and report back :)


You can download the source build of Gradle and get autocomplete for the Groovy DSL as well. Just change `distributionUrl` to the `-all` build of Gradle in your project's gradle-wrapper.properties.


Before Maven, there was Ant. Ant is a fancy Makefile written in XML that makes it very very easy to write build scripts that are not reproducible and rely on a particular structure and set of tools on the computer of the person that wrote the build file. At some point people realized the madness and wrote a new build tool that would only use declarative syntax, and would provide reproducible, contained build bliss. And lo and behold Maven came to be.

Later XML came into disfavor, as things do, and thus by association Maven as it uses XML. So they created Gradle, a tool deemed superior by the mere virtue of using a Groovy DSL instead of XML.

Here's my opinion about Gradle :

1 - the syntax is poor. Merely not using XML does not imply that it is fun to write Gradle build files. XML is verbose but very well specified so when you need to write some configuration it is a bit tedious but all in all very easy. On the other end Gradle uses a custom DSL that is poorly documented. Usually the best documentation there is are example files, so it can be very hard to figure out what to do in uncommon cases.

2 - plugins can extend the DSL. That means there is no single document to learn to know how to write Gradle build files, you also need to learn the DSL for the plugins you use. Maven developers went as far as specifying a standard plugin documentation format so that when you need to look for the syntax for a particular plugin you can do so fairly easily. Not so with Gradle, documentation quality is inconsistent and hard to find. The Android plugin seems especially bad in that regard.

3 - it killed the dream of declarative builds. Gradle allows to run Ant files directly and is simply Groovy under the hood so build scripts can quickly become ad hoc messes. Not what I call progress.


I like XML. It tells me when I've forgotten a value, like 'version'. I still don't get why people rail against a machine-and-human-readable format that isn't space-sensitive, can be easily validated, and can be processed by virtually any language. Sure it's verbose, but it's also robust.


super short post, on a topic that seems not super relevant to many.

but i dig it. i dig it a lot.

languages are a pain in the butt. you can do anything with languages. so can everyone else using the language.

it's actually quite nice having constraints. having a uniform model, having dead inert data. everyone using the same machine, the same mechanisms. maven's lifecycle[1], the steps of a build, being well defined, in order, serving as a backbone for plugins to extend, is powerful in it's ordered simplicity, in it's learnability, in it's familiarity.

i have barely touched jvm in the last decade, but even a decade ago, i think the lessons here are really killer, really key, really insightful. it's not apparent exactly how this applies to a broader scope of computing, but i think there are some really important lessons we still need to grapple with. that languages offer too much freedom. that being able to do anything ends up with everyone doing something different, a proliferation of hell as other people's code, other people's endless variegated opinions, all unlike, all foreign.

that said, maven leaves extreme power in the hands of it's plugins. plugins do a lot. i spent years combing through docs, & looking at different project builds, & maven retained a vast aura of mystery, left endless questions abound. i resisted going further, understanding what plugins really were, looking at what they were doing. once i started reading their sources, i was quite surprised to find many of the plugins i thought powerful & special were actually quite short, often rather simple manipulators of a couple of files. it took diving in to see how elegant & simple maven & it's vast sea of plugins really (often) were.

[1] https://maven.apache.org/guides/introduction/introduction-to...


Yeah, I'm a big fan of Groovy (and Kotlin, though I know it less), but what bugs me about Gradle is, at least when I last used it which to be fair is some years, is that it solves 50% out of the box. Maven was closer to 85%. The Gradle manual started with, "here's how you write your own tasks!"

I don't want to write my own; I want to know how if I need to, but you're saying I need to right off the bat. Maybe that was an issue with the manual vs. the tool, but if the build tool needs documentation to tell me how to build a build tool on chapter one...


To make it worse, every Gradle project I've come across has different solutions for the same common tasks. With Maven it's more-or-less standardised, because custom plugins are rare (I've come across just one in 20 years, and I wrote it for a special purpose). Embedded Ant was more common, but thankfully rare now. Everyone just uses the same handful of plugins in my experience.

Agree that Groovy is awesome.... as a compliment to Java. I'd learn to dislike it quickly though if I had to write an entire project with it.


You make it sound as if writing a task was like writing a plugin. That might sound very close to the truth if you look at it through maven goggles, but if you take a step back to the structured shell scripting of makefiles it's hardly surprising they start with that.

For me, my main gripes with gradle are that freshness determination is quite difficult to analyze (and quite easy to break when you start doing nontrivial things, and if it breaks it is far too easy to just live with the additional build duration), that learning curves can progress way too far without real understanding of the central principle of configuration time vs task execution time (stronger syntactic separation might help, teaching "build your own task" early surely is an attempt to help as well) and, most of all, that all those "superconvenient" DSL syntax shortcuts are almost but not quite universal. "You can use DSL simplification xy everywhere, except where you can't" and there are far too many different xy. Maybe I should give the .kt syntax another chance, last time I tried I was in a phase of the learning curve where having a different syntax than in all the Google results was definitely a showstopper (trivial things are surely well-documented for kt, but when you reach xkcd 979 corner cases you'd better be firm enough in the groovy syntax to do the language transfer in your head without any uncertainties)


> You make it sound as if writing a task was like writing a plugin.

In that you have to write something, it is. Which is my point. I had a very vanilla product; I couldn't do it with vanilla Gradle. I also couldn't find in the documentation how to do "normal stuff"; or at least it wasn't early. It started RIGHT OFF with "here's how you customize it!"

No, start with the 80%, deep dive into deeper stuff, later.


Strange, gradle is just way faster in my use cases. Maven has always been a pain with regards to speed with handling dependencies.


If Gradle is fast in comparison to Maven, then I cannot begin to imagine how slow Maven is. A build system that has to spawn a daemon to speed up the process is a pretty shitty one. It takes about 2-3 minutes to do that for me, and still it takes 30 seconds to build my program which is not even that huge.


Something is wrong with your setup methinks. Gradle daemon starts in a second or so for me on the two Java projects on this machine (around 20koc each) and like one second build times...


What could possibly be wrong with the setup though that would cause it? I have a couple of dependencies, including libGDX, artemis-odb, and kotlin-stdlib-jdk8.

I posted it in another comment, but I am willing to record it when my time allows. It is quite baffling. I never encountered such slow compilation times even though I compiled some C++ projects before.


Nit: you don't need to specify kotlin stdlib since Kotlin 1.4


Thank you!


One of my projects mentioned also uses libgdx. Have you tried the libgdx discord? The community is pretty helpful.


It is not my codebase, I had to clean it up. I managed to do it though and it basically looks like every other libGDX project. I can even create a single JAR file that works! I am pretty happy about that. Everything is up to date, and I am converting the codebase from Java to Kotlin. Still a long way to go, but we (my partner and I) will get there. :)

By the way: I also use `googleJavaFormat` and `ktlint` to format both Java and Kotlin files. I also pack textures before running the game.

In any case, my old hardware may be at fault here, or the fact that I also run multiple things in the background, or that I run a couple of Gradle tasks, or a combination of these things.


We have a 100k LoC project that builds in 15 seconds in maven and that includes packaging everything into an Uber jar.

Do you have a fast SSD? It makes an enormous difference in build times


I have an old Western Digital Blue hard drive. My setup is really old. It is about >5 years old.


That's why your builds are slow I guarantee it. Our build times dropped from ~4 minutes to ~20 seconds when they got everyone machines with SSD


Are you saying that it takes 2-3 minutes to start the grade daemon? That sounds weird.


Yeah, it does. I have 8 GB memory, and an Intel G3xxx CPU. I am baffled by how slow it is. For people who do not believe me, I am willing to record it, but I have to go to sleep now. :/


That's been my experience of Gradle too. It's always been slower than Maven for me. In any case, 90% of build time is unit tests for the projects I've worked on, so switching tools offer minimal benefit in that regard.


Yeah, this article is really not convincing. I've used both gradle and maven and IMO gradle is better in practically every way.


Is there a benefit to using either over MSBuild?


I assume if you are using MSBuild you're building .net or otherwise using visual studio. If you want to build these projects with gradle or maven you still have to invoke MSBuild in my experience. It's not strictly necessary AFAIK, but you'd be giving up a lot of what visual studio offers you for little in return.

In general, if you aren't already using a JVM language, there is not a whole lot of reason to use maven or gradle. Pretty much every language has equivalent native build tooling that you should be using instead.

If you are using a JVM language, even for part of your build process, then both can be used as the primary build tool and invoke the build tooling of the other ecosystems as needed. This is most useful when you have a native component that you are using from the JVM.

I have in the past used gradle to build the native C++ components for apps, but in general it reached out to msbuild on windows, and make files on linux.

I've used gradle it to invoke npm commands to build the frontend component of a WAR java webapp.


Or Make? CMake?


There's a maven daemon project now that closes most of the speed gap for my projects


I love the simplicity of Maven and declarative build tools vs imperative.

The problem is Maven has a huge legacy code base and sees very little improvement.

Its ability to concurrently build modules is flawed and it doesn't have incremental compilation support.

There is an opportunity to build a new Maven (Maven 4) from scratch with some newer principles but adhering to most of the XML format.

Btw Maven can now read POM file in other languages than XML like Groovy & Kotlin


Gradle: Inexcusable API churn and arguably worse spaghetti builds than Ant ever had, with loads of undocumented "magic".

Maven: BACK TO XML? Awful. Maven's common directory structure is about the only positive it brought, and I still wince at "src/main". They should have flattened more. Also the pedantic "coordinates" or "artifacts". These are jar names and versions, people, not some cyber virtual reality.

Maven, while it did push forward on pulling dependencies from repositories, didn't separate the dependency download from the code build, so build reproducibility became dependent on the repository access/status/completeness.


There are some claims that Gradle builds way faster than maven. I personally witnessed at my last job (usual Spring Boot, Hibernate stack), that the builds were indeed way faster after migrating to Gradle, but then the Maven configuration had quite some years behind it, so it could also be possible that it was not setup optimal.

Anyone has some experience with that?


Is it denotive that nobody has mentioned Bazel so far? It supports building Java applications as well:

https://docs.bazel.build/versions/master/tutorial/java.html



Has Gradle finally got an equivalent to parent pom? It's such a vital feature, to be able to set dependency versions and plugins up to use on all child projects and publish into a repo. Last time I looked, Gradle couldn't do this.


What I don't get is the exception: this could be handled with a custom maven plugin (as an extreme way) or a wedge of inline script in the pom.xml (sloppy and maybe not so portable). Or the Assembly plugin. There's countless ways to build custom jars.


> First off, you cannot not learn Maven

I can think of a way to make that happen.




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

Search: