* Perform incremental build a magnitude faster than Maven, zero changes build finishes immediately.
* Can have global caches for all builds across organization, so that a workstation build can automatically build incrementally upon a standard build, massively reduces build speed for big monorepo.
* Very fast, incremental tests execution: test results are cached, so only tests affected by the changed code are run. Test executions are parallel by default.
Some other things:
* Pull in dependencies directly from a git repository, without having to publishing it first like in maven, this can be a plus or a minus.
* Cross-languages build: you can have each of your module programmed in a different language, declare dependencies between them and use Bazel to perform incrementally build quickly and reliably.
That said, maintaining a Bazel build system is also a magnitude more complex than a Maven one, especially if you're not using one of Google main language: Java/C++. Plugins for other languages are of varying quality.
Fun fact, it seems like Maven was also meant to service a variety of languages. There's even some support for polyglot POM files. Aside from the niche C++ or JavaScript ("frontend") plugin, that never did much.
I see benefits of that in projects that build hours, but in every one of my maven projects (non-hobby) I always do clean before package/verify just to make sure the project builds.
``` mvn clean verify ```
And I'm certain it will work in CI also.
However, Bazel cache is a lot more robust, so you almost never do clean build. The only time I had to perform a clean build was when I accidentally upgraded my C++ compiler and broke the cache.
How does it enforce that? Does it sandbox the compiler or something? Java compiler annotation processors can perform arbitrary IO.
There's also (I believe experimental) support for using Docker as a sandbox backend. That ends up being useful if you're using the remote build execution support: you can run a build locally in exactly the same environment it will run on a build farm.
(I once accidentally baked a time and random number into a binary myself - and the random number thing would have been a serious security bug if we had not found it with test coverage. Would have been better if the build system disallowed it.)
They already have support for build times and labels, but you can add arbitrary stuff like got hashes too
You can of course define these as variables, but that'll just drop all your caches on each build which eliminates the main selling point of Bazel.
Bazel can use sandbox as an additional layer to prevent you from accessing undeclared inputs, but the sandbox is optional and can be turned off.
The Java ecosystem has much of that available also though - even a large Java-only project is somewhat tough to justify moving away from the tools almost every developer will arrive already knowing.
This is how I feel about most of Googles Java libs (guice, guava, gson). They used to be better, but now they're just tech debt.
Guice -> If you need to support the jakarta.* namespace the only real answer is Weld or another CDI compliant implementation. Otherwise guice is probably still fine.
GSON -> Jackson as always.
JetBrains and it seems basically every library has support for Gradle and sometimes Maven, but not Bazel. Gradle is verbose and has a really steep learning curve, but it's battle-tested and does its job really well. I don't really see why anyone would use Bazel instead.
One thing that Bazel has that I wish gradle did was remote compilation and remote test execution rather than just remote caching of artifacts.
A gradle build can be very complicated and very long.
Bazel is relatively easy to learn and relatively concise (again that's relative to Gradle which for a Java dev basically requires you to learn 1-2 new languages if you want to understand the build file syntax), and IMO is MUCH better if you are working with multiple languages.
However I haven't tried to use Bazel with things like native libs in the JVM... so it's possible that my Gradle opinion is biased because I used it with more complicated use cases.
Gradle: Just slap any kind of code into our build files and we'll run it. Everything is code, everything is customizable and you can muck around with everything.
Bazel: Here are a few of build rules. All compilation needs to be deterministic, all tasks need clear deterministic outputs and all task generate clear deterministic outputs. It's very rigid and it uses that to get significant performance wins, especially when using a build farm.
For anything more complex, you should write plugins.
Nonetheless, I would be interested in seeing a detailed comparison of the two. As far as I know, gradle is quite capable once someone understands what he/she does.
https://melix.github.io/blog/2021/01/the-problem-with-gradle...
* SNAPSHOT maven artifact are not hermetic and not reliable for caching: Maven only re-fetch SNAPSHOT once a day by defaults, so you will miss changes if you do not explicitly update it. In Bazel, any changes in a BUILD target's input are detected immediately and will trigger a rebuild.
For builds there are a few options to check out: https://github.com/jin/awesome-bazel#remote-caching-and-exec...