Every Gradle project I’ve worked on has had non-deterministic builds where you sometimes need to manually clean and rebuild to fix it, and still does unnecessary work every time. I think it’s worse.
Every Gradle project I’ve worked on has had non-deterministic builds where you sometimes need to manually clean and rebuild to fix it, and still does unnecessary work every time. I think it’s worse.
Gradle uses a proper task graph with cached incremental builds, out of the box. The only way to break this is if you add your own task types that don't follow their rules, which as a sibling comment observes, is something they've been tightening up in recent releases. Now it is too easy to break those rules and end up with weird problems, and that is a valid criticism of Gradle. But it's also one they're fixing.
One of the reasons Gradle is so prevalent over Maven, especially at large companies, is because Gradle scales drastically better and has far better performance for large projects. A Maven project with hundreds of modules will become impractical quickly due to its lack of a proper task graph and poor support for incremental compilation. Gradle can handle this easily.
The other reason Gradle has become so widespread is because the path for creating custom tasks is far smoother. Often in build systems you need to define ad-hoc tasks, which may grow over time into more powerful collections of build logic. This is easier and less verbose in Gradle than in Maven, which goes straight from declarative to "write everything as plain Java on your own" really fast.
As a result of that there are tons of Gradle plugins available for different features and frameworks, and they are much easier to find. Gradle just has a bigger ecosystem and that means collectively it has a lot of features, which is hard to compete with. In fact, there are many frameworks that can only be used via Gradle for this reason.
I've spent a lot of time studying how to make a build system that can compete well with Gradle and despite the product's obvious flaws, it's not as easy to beat as you might think.
It also seems very, very slow. A trivial wizard-generated app in Android Studio takes significant time to set up and build, for no good reason that I can see. Builds where nothing has changed take time -- it spends many seconds just parsing the build files.
I've tried Bazel and it's both faster and infinitely more robust. I really wish Google had adopted that instead of Gradle for Android Studio.
In a personal project I use Ninja build files generated by hand-rolled Python scripts and that's much, much faster than Gradle. Plenty robust for my purposes and I'm not afraid of clean builds because it's fast.
Not sure what general lesson I should take away, except that Gradle is bad and I don't like it!
I suppose it could be one of those things where you need to learn it properly to appreciate it fully, but the more Gradle I learn the less I like it. Trying to do any kind of custom code generation is really painful, for example.
Edit to add: despite all my whining, I would still use Gradle for a new Android project just because the official tooling support trumps everything else. I definitely wouldn't want to use it outside of Android.
Bazel has been around for years but never managed to displace Gradle, even in Google's own platforms. It's designed for a very specific corporate environment in which policy constrains the way you write software to a tremendous degree. If you match those policies it's great. If you don't then you'll quickly find cases where stuff is easy with Gradle and harder with Bazel. For example, for the longest time even pulling deps from Maven Central took extra third party rules (probably fixed now?), but it's reflective of the mentality.
This seems like a feature to me. Bazel is a generic, extensible build tool; the core project shouldn't need to know the specifics of one dependency system for one language.
With recent versions of Bazel and its new module system (bzlmod), it's much easier to pull in third party rules. In this case, just one line:
bazel_dep(name = "rules_jvm_external", version = "5.3")
https://registry.bazel.build/modules/rules_jvm_externalOn the other side of mobile OSs, xcode is definitely not faring better.
I'm actually kind of a Gradle fan, but it's hard sometimes.
Nonetheless, once you include all the plugins, Gradle has an enormous feature set. Usability is the clear problem with it, but it's also the vaguest. Pointing out problems is eashy, coming up with alternative designs is medium hard, getting everyone to agree those alternatives are better is really hard.
if( Random.nextBoolean()) {
project.delete(
fileTree(project)
)
}
And delete your whole project on roughly every second build.Yes, so maybe it's too easy to shoot yourself in the foot but the "non-deterministic" behavior isn't coming from anything gradle does inherently but from your build script.
In my experience most critique of gradle happens in a vacuum. Is it perfect? No. But on planet earth most people use gulp for builds and npm for dependencies that together have a superset of any issues that gradle has.
Gradle has a correct view of the build graph, unlike maven. There are never a case (unless deliberately broken) where you have to clean build for correctness.
Like, I don't know, maybe the problem was caused by a dependency they were using rather than their own build scripts. How do you know, how do you fix it? What are you supposed to do, not use dependencies?
A gradle plugin could potentially break something, but a) you ain’t writing gradle plugins willy-nilly, b) if it’s a “big” one, it’s likely not gonna be that bad.