Gradle 7.0
docs.gradle.org
docs.gradle.org
To provide a counter-point I love Gradle.
Yes it's complex, yes the learning curve is basically a cliff (you either understand Gradle or you don't) and yes it can be slow.
But on the positive side:
I use the Kotlin DSL and the majority of my new projects are Kotlin also. As a result I now have a single language in use and no need to switch contexts. Type safe, null safe DSL for build configuration that also happens to be the same language I want to write my project in anyway? Yes please. It's basically Ruby Rake but better in this regard.
Potentially contentious point but I love being able to extend Gradle on a per-project basis with buildSrc plugins. This allows me to handle more complex tasks in a way that abstracts that complexity from the members of my team that don't necessarily have the same level of time invested in Gradle.
I like that it downloads itself via wrapper script. My projects only have one local dependency, a recent JDK. The build system downloads itself, then downloads all the project dependencies. This makes it easy for non-JVM members of my company to check the project out, make a small change and build the project without learning 5 other tools. cough Javascript cough.
I like that it's versioned per project when using the wrapper. I don't need to worry about some sort of runtime or package manager switcher like you would in Python/Ruby/Javascript land.
Don't get me wrong, Gradle is a long lived project with lots of skeletons in the closet but overall I think it's a very pragmatic tool for small projects all the way up to mid-sized monorepos. There does come a point when you will want to look at Buck or Bazel but most teams will never reach this point.
While I also use and enjoy Gradle, this is IMO its biggest weakness. We've all seen the recent supply-chain attacks, and ~everyone's infra is at risk here. There isn't even anything similar to Javascript's subresource integrity!
I'm sure that the people hosting Gradle are very cautious, but it only takes one slip-up...
Gradle can be impressively fast (i’d hate to use a gradle build without the distributed build cache feature these days, what a difference), it can be reasonably easy to identify slow parts of a build (digging through build scans isn’t too hard). When it comes to extending it, groovy is actually pretty comfortable for making little doo-dads to assemble some shell scripts from templates, or populate an h2 with some build metrics, or whatever you need, but all in all i think i’m over gradle.
The speed is hard to keep on point, requires constant babysitting in a medium or large team and the learning curve really requires a reasonable working knowledge of groovy first (or kotlin - i haven't used the kts facilities) and a lot of java developers just aren’t interested in learning properly so they hack something in which leads to band aids that get hairy easily.
You are correct that the biggest problem is that many people treat it as a distraction/unimportant part of their workflow and then wonder why things go badly.
As the most senior member on most teams I am on I take it on myself to take charge of the builds, CI and other tooling to ensure this doesn't happen and all engineers are productive. Unfortunately that isn't a solution for everyone but IMO it's how it should be, you make yourself a 10x engineer by magnifying the performance of your other team members.
As someone who has regrettable know about Gradle long enough to remember when someone actually thought Groovy might be "the future", the idea that they might support a different off-the-shelf syntax had never occurred to me... OMG you have made me so excited to try escaping.
One of the skeletons I wish they would fix - i was hoping this would happen in 7.0 - is isolated classloaders for plugins, or something like that.
At the moment, all the plugins can see any other plugins dependencies, like guava. Bringing in your own version of guava can break other plugins.
Maybe this has changed, but I don't think so.
https://docs.gradle.org/current/userguide/worker_api.html#ch...
* "Gradle update? Performance babyyyy"
* "Oh, <obscure feature that needed to be hacked around> no longer works. It's okay, let's fix it.
* "Oh, no, it's actually not backwards compatible and I have to figure out what kind of awkward cast as an <AndroidPluginInterface> I have to do because gradle still doesn't expose proper types in half their kotlin DSL"
* "Right, entire build cache gone. It's okay, 15 minutes."
* "right! Now let's get an incremental change and see the perfo... Right, kapt still isn't incremental"
Just look at some of these breaking changes reported for 7.0:
[#16652] - Trouble using centralized dependency versions in buildSrc plugins and buildscript classpath
[#16620] - FileNotFoundException in TestKit tests: lib-android/build/20210320_1519030999411730848.compiler.options
[#16541] - Impossible to run modular program with 7.0-milestone-2. Working with 6.8
[#16532] - Build failure when including a plugin build in settings & applying a settings plugin
[#16163] - Using included builds for local settings plugins don't seem to work
[#16028] - Change in behaviour when resolving custom project dependencies
I without going into details, two of these would affect the project I talked above... These breaking changes should be enough to block release of 7.0 before 100s of developers are hit by these time-wasting issues.XML, yaml, toml, json, something else standard and well known would have been nice.
I do think that one of the big problems with Gradle is they try to operate under a pretense that you don't need to learn any Groovy to use it. The reality is you can get just far enough to get yourself in trouble and then suddenly you are mired in inexplicable problems, and just start hating the tool.
You get IDE completion, script debugging support, it is fast and best of all, it doesn't change in every release.
That being said, when I switched over to Gradle almost ten years ago, it was still only a marginal improvement, but an improvement nonetheless. Unfortunately, things only seem to have gone downhill from there.
But that doesn't change the fact that overwhelming majority of professional java devs avoid Gradle like the plague.
And no, we don't have a dedicated maven guy in every project. Maven is just too simple and well understood for that.
So it was possible to support building Java 16 projects while running Gradle on a supported Java version before Gradle 7 was released.
Exactly. But you could run Gradle on Java 8-15 and use the new toolchains support to build with Java 16.
I'm not saying setting up toolchains is frictionless or even reliable yet (given the feature is so new) but it's there.
Do you think Scala, Rust or C++ build times are bad? Wait until trying a medium sized Android project with Gradle, without using a gaming rig.
I did the same, Android now only via mobile Web or NDK.
Has that changed over the years? Has it gotten better or worse?
The "new" publishing system is still a thorn in my side. It doesn't play well with existing Gradle paradigms(like configurations) and seems to force most people into giving up on it when they have some variation of the use case "Publish a dynamic list of files(aka unknown list) produced by task/subproject and not the stock Java tasks." There's a trail of frustration going back nearly a decade; unanswered questions, answers that don't address the use cases, and a general lack of acknowledgement that the "new" system isn't getting the job done for people in a friendly, flexible way.
Parsing XML on the other hand and adding some semantic to well-defined tags or even plugins: That's much simpler and more robust.
(Yes, you can do scripting inside some maven plugins, but if you do that, I'll come over and sit on your keyboard until you can convince me that there was no other way)
Avoid gradle like the plague.
PS: thank you Gradle maintainers for offering a download of all versions at a click's distance
Gradle is really a huge burden for me to get the app up and running and for someone who was only lightly interested into doing small changes one the fly, gradle was totally upsetting.
I think it kinda fits into tools that suit much large scale projects, while they fall short to address small scale projects.
And this small thing called Spring, maybe you heard about it? But yeah, other than that it is almost irrelevant, if you count Netflix, Adyen and thousands of other companies irrelevant.
Netflix and Adyen are indeed irrelevant in the context of Java consulting.
When Fuchsia finally happens, not even that.
What do you mean "usable with Maven"? They've migrated to Gradle because Maven wasn't cut for the task anymore.
> Netflix and Adyen are indeed irrelevant in the context of Java consulting.
Sorry, but products are far more credible to me than sweatshops that exist to milk other businesses.
Pivotal is always chasing the latest fad in Java community as means to attract developers, almost every JVM guest language and build system has at a given time had Spring first class support, then it was removed when it stopped being cool.
Sorry, but Netflix could be using Brainfuck and it wouldn't affect anything outside their building, without any relevant meanint to the actual quality of their product.
If anything it just proves that Netflix is able to deliver despite the tooling they happen to choose.
I've been thinking of taking a peek into Java, which I've never really written[1]. Is the general thinking that, for something like a Spring Boot application, it's much better to just start with Maven? I'll admit I am, aesthetically, displeased with the mountains of XML config I've seen in some tutorial articles, but I imagine it's a lot simpler to maintain over time than any DSL would be.
[1] slightly off-topic, but if anyone's curious why: I haven't been very impressed by any of the "Kotlin-first" JVM libraries I've seen (like ktor or exposed), I think coroutines are neat but much more suitable for main-thread-focused situations like Android apps than something more easily threaded like web servers (and with Project Loom hopefully upcoming in the next couple years this might be a moot point soon), and I don't like the JetBrains tooling lock-in (e.g there's no well-supported language server for Kotlin, unlike what Red Hat's been building for Java)
If you're using Spring Boot then you might as well also use Gradle, since they're the same kind of write-only incomprehensible system (I wouldn't be surprised if they were made by the same people). But yes if you want to be able to maintain your build definition for the long term and actually understand how it works rather than cargo-cult copy/pasting snippets and praying then Maven is a much better tool.
After I finished that and from my later experience with Maven, I really don’t find maven all that scary: writing all the XML isn’t my favorite thing to do, but it’s surprisingly straightforward to get a minimal pom.xml that works for 80% of the projects you work on.
It seems someone has recently created something similar for Maven: https://github.com/mvndaemon/mvnd
Too bad most CI/CD pipelines are effectively stateless, spinning up a new vm, docker image, or whatever for every run. Gradle's cold startup time is awful now that they've pushed more and more into the deamon, make it a major bottleneck in build times.
And incremental builds when one develops does boost performance significantly.
The IDE doesn't invoke the build tool, it extracts the project structure from it. If the build tools has a sane model (i.e. maven or a gradle build that's maintained with discipline) then it will get an accurate picture of which sources should be built depending on which other ones, and can use that combined with its own knowledge of which files have been edited to do incremental compilation and even e.g. re-run affected unit tests but not others.
> Also, NOT building with the project’s build tool is a giant red flag of doing something bad. That way you are testing different things then what will run after deploy.
Using incremental compilation for release artifacts is a huge red flag IMO - how will you reproduce that same build in the future? So using it for local builds is a tradeoff: you get to iterate faster, but you have a divergence between your release build and the one you're iterating with. IME it's usually worthwhile (provided you're still running your full test suite as part of your release build).
So given that there's going to be a different code path running, is it important to be using the same build tool in those two cases? IMO no - the difference between maven building my code for release and my IDE building my code incrementally based on my maven project model isn't really any bigger than the difference between gradle building my code for release vs gradle building my code incrementally. If anything the fact that maven exposes the project model in a stable form (such that my IDE is able to use it) is an argument that those builds will be more consistent.
Not true in my experience. For a gradle project intellij offers me the choice of building with intellij (incorrect) or gradle (slow - the actual compilation may be fast and incremental, but it takes a couple of minutes to start up, build the project definition, and so on. I'm sure this is because me and my colleagues are using it wrong and some theoretical gradle wizard wouldn't have this problem, but it's been the behaviour of every gradle build I've had to use in actual real life).
> correctly and fastly (as opposed to maven where you should be doing clean install)
Not my experience at all. Maven may be less incremental but miscompilation is a lot more common with gradle. And more to the point, IDE-based build is a lot more reliable with maven than with gradle, to the point that any slowness of the maven-based build is irrelevant.
But I do apologize, in my prev-prev reply I was way too cocky and wrong; actually building with the IDE is much more common (but depending on the project it can introduce subtle bugs, so do try out the build tool built version as well from time to time)
And build speed on large projects do matter, so there is a point where I think gradle is worth using over maven, because it can mean an order of magnitude reduction in build time.
For example with Maven if you run any task from the sub-project which depends on adjacent sub-project, maven will look for it in ~/.m2/repository. So you have to mvn install every time you're doing any change in any sub-project which is PITA when you're changing many sub-projects simultaneously (and if you did not mvn install, you'll have old version in repository and new sources in IDE and things go wrong way in a completely non-obvious manner). But if you're running maven commands from root pom, sub-projects will properly reference each other. So the proper way is to run all commands from root repository and specify -pl. But then you'll run into other issues, as not all plugins will work correctly this way (for example mvn exec:java).
With gradle it just works. You're running command for any sub-project and gradle will properly find any dependant sub-projects, build them, put them into classpath, etc.
My main gripe is that it changed so quickly. All my notes quickly became useless. And it was slow. Gradle daemon promised to help. And it did help. (And became even more of a resource hog) But it was still bad. Show me the build tool - I'll show you the bad.
Maven wasn't bad either. It tried to enforce convention over configuration, while also introducing a native dependency management mechanism.
Gradle was/is bad and serves no real purpose.
build.sh
Then again, I don't want to be like certain others: the above is just observations from my very limited point of view. Maybe in a year I love Gradle the same way I love Java today after initially finding it almost insane.
After all there are some seriously smart people using Gradle and thinking I'm smarter than all of them would be some serious hubris from me.
Even better, geological layers :-))
Basically, as I remember it, every time Android studio updated Gradle, my project broke. No exceptions, even though this was a stock Android Studio project.
Seemingly things are still that terrible? If so, why do you people keep using it?
What problems does Gradle solve which other build-systems don’t solve better
I'm yet to see a good explanation for how Gradle should be used. Is knowing Groovy a prerequisite?
I don't know Groovy and I was able to write complicated enough multi-project builds with some custom build steps by copy-pasting snippets from the Internet and applying some common sense. I guess, Groovy knowledge is required if you need to write build plugins.
Everone "learns" Gradle by copy-pasting snippets from the Internet and then having to fix them when they break. And what little I have learned of Gradle over the years was certainly not thanks to their documentation, but other people explaining the concepts in blog posts and tutorials. The Gradle documentation always assumes that you will want to learn the whole build system from ground up. There is no simple documentation for people who see Gradle just as a tool secondary to their actual product that is just built with it.
It is in many ways similar to git. You can't really learn git unless you learn it from the ground up. But git is actually really simple when compared to Gradle, and most people do learn git eventually through using it. But I am yet to encounter a developer who actually learned Gradle inside out just from using it and reading the documentation.
Oh, and at least git's interface and structure has remained mostly static ever since the original concept by Linus in 2005. Same can not be said of Gradle - I feel like the developer interface is like a sand castle that is washed away every second release, and I assume the internals keep shifting as well. What a nightmare to work with.
> But I am yet to encounter a developer who actually learned Gradle inside out just from using it and reading the documentation.
You just met him! ;)
For example, the following document has been largely useless to me even though I’ve spent whole days trying to make the examples work for me: https://docs.gradle.org/current/userguide/cross_project_publ...
> You are probably doing a bit simpler stuff, if that basic tutorial suffices you.
I've written a couple Gradle plugins, one of them was to build and test programs in our custom DSL. This exposed me to all facets of Gradle, because whatever Gradle offers to compile Java, Kotlin, ... you will most likely use for another language as well. I could not have written these plugins without the Gradle documentation. But again, it's totally unrelated to Android development.
Aside from the performance implications, Gradle excels when used with more complex builds with many steps. If Maven works for your use case, your build scripts aren't unmanageably long, and your team doesn't mind XML, there isn't much of a reason to switch.
I would say that they should not stop the development of all new features, but rather they should spend more time designing those features, so they don't have to change them in the future (making old variants obsolete and broken in the end). But modern software development is agile, move fast and break things and all that.
Maybe its just how android is and nothing to do with graddle but still...
EDIT: right, Jetifier too, because that's always a lot of fun.
Maven is great when all you want to do is build a simple Java project and publish it, when you step outside of that it becomes much more painful.
For example, here's an old plugin I put together to allow easy publishing of a third-party artefact to a repository that didn't have a web interface for such things: https://github.com/andrewaylett/prepackaged
It's old enough that the infrastructure I set up around it has bit-rotted -- I've just pushed a clone to GitHub to share here :). I'd hope using modern language features would make it easier still.
Doing such prototyping in Maven is quite arduous in comparison.
Gradle _almost_ does the same, but it allows execution of arbitrary code in too many places -- like with parsing Perl, we can't discover the model without also executing it. Hence the trap.
[1] https://melix.github.io/blog/2021/01/the-problem-with-gradle...
What are the pro's of me switching to Gradle? What would Gradle replace for me?
I have avoided that road because it's one more thing that is a snowflake in the very area where I don't want to blazing trails. But I have personally tried their approach before and can confirm it does work as advertised. I can't recall if IJ lost its mind over pulling a stunt like that, but arguably if it did, then filing a YouTrack is an appropriate next step
https://phauer.com/2018/moving-back-from-gradle-to-maven/#tl...
In effect we are unable to move versions forward on Gradle projects, and legacy projects are stuck on legacy Gradle.