I think there are a lot of "JVM Lifers" who are so deep in the ecosystem they are unaware how much better things can be.
Anecdote: I wanted to publish a ~100LoC multiplatform Kotlin library -- just some bindings. I publish these sorts of things for Go with just a "git push".
Steps were:
1. Spend a few hours trying to understand Maven Central/Sonotype, register and get "verified". They're in the middle of some kind of transition so everything is deprecated or unstable.
2. Figure out signing, because of course published packages must be signed. Now I have a secret to keep track of too, great.
3. Discover that there is no stable Gradle plugin for publishing to the "new" Maven Central, it's coming soon... Choose one of the handful of community plugins with a handful of stars on GitHub.
4. Spend a few hours troubleshooting a "Gradle build failed to end" error, which ended up being due to signing not finding a signing key. 3rd party plugin didn't handle errors properly, and a bug in Gradle meant that my secret wasn't picked up from local.properties.
4. Eventually discover that because Kotlin Multiplatform can't be cross-compiled, there is no way to actually publish a multiplatform library without spinning up a bunch of CI runners. And you can't just publish code -- JVM packages have to contain compiled artifacts.
5. Realise this now involves maintaining GitHub Actions and Gradle, which is an ongoing cost.
6. Give up.
The harm that this kind of complexity must be causing to the ecosystem is immeasurable.
Although a lot of it is generic badness, Kotlin Multiplatform isn't the JVM ecosystem. You don't need CI runners to publish a JVM library. The reason it comes up with Multiplatform is because Kotlin defines "Multiplatform" to mean platforms like JavaScript, or their own LLVM based compiler toolchain that bypasses JVMs entirely.
I’d just like to add, NPM gets a lot of flak (mostly deservedly) but it too is still vastly easier than anything in the JVM ecosystem.
Even with all the headaches around modules versus CJS, and JS versus TypeScript, NPM is a lot easier than Gradle. Notably, you have a choice of alternate tools (eg pnpm, yarn, bun) that interoperate pretty well.
I guess my point is, Gradle and Maven are specifically and outstandingly bad.
If you think gradle and maven are bad, you should try Mill! There is more to build tooling than gradle or maven, the field has evolved significantly since those tools launched 15-20 years ago, and Mill tries to do things better
I must be missing something here. Don't the tools you mentioned do a lot less than Gradle? Gradle knows test depends on compile, which depends on code generation (say protobuf) - with caching and change detection. Compare that to chaining up the commands in the `scripts` section of `package.json`.
I could be convinced if those features of Gradle actually worked well, or even worked properly, like dependency management does in e.g. Bazel.
In practice, Gradle really seems to fall down on the basic task of just being able to build stuff in the first place. It feels like you’re constantly fighting version hell just to find a Gradle version and plugins that work together, let alone your actual code dependencies.
And if you actually do need to do something slightly more complicated, like code generation, it’s very difficult to work with and the docs are really bad.
I have no complaints for the well trodden path (e.g. https://github.com/google/protobuf-gradle-plugin). I have also written some custom build steps, and indeed the docs aren't very helpful - but the final implementation is quite simple.
Npm also gets a lot of flak for the low bar it sets for introducing malicious code by impersonating an idling maintainer or presenting yourself as a successor. The friction, the secrets to keep, they are there for a reason.
Half are ignorant. Other half are like me and just stuck with no options.
But the tooling ecosystem on the JVM truly is horrific.