> * Probably the best tooling and ides in software development.
Agreed on the IDEs, nothing can beat IntelliJ... but general tooling? Definitely not. Maven is a hot mess of XML where people tend to do horrible horrible hacks just to survive, and Gradle projects tend to be even messier because of Groovy's syntax allowing about five different ways of doing the same thing.
> Gradle projects tend to be even messier because of Groovy's syntax allowing about five different ways of doing the same thing.
Spoken like a true "I've never seen Gradle beyond copy pastes from Stackoverflow". Modern Gradle is all about plugins written in Kotlin. Your buildscripts shouldn't have anything beyond `implementation` block.
> Spoken like a true "I've never seen Gradle beyond copy pastes from Stackoverflow".
Which is what the majority of legacy, grown Gradle scripts are in my experience among multiple government and private companies' projects. The older the project, the worse state the build scripts tend to be. The worst I ever encountered was a project that was mainly done with Maven, but that called out to Gradle and Ant for weird manipulations to get the build artifact to the formats required... gives me nightmares to this day.
I'll give you gripes with maven/gradle (even though maven tends to just work for me), but look at all of the observability tools like Mission Control, Flight Recorder, and VisualVM. What other language has all of this?
There's nothing really wrong with it, but it's core design is pretty outdated in ways that are difficult to fix without putting together a totally new language. Couple of examples
- Support for nullable values. Swift and Kotlin have first class support for these, which are meant to minimize or reduce the number of null pointers in your code. You can mostly fix this with annotations, but those your team using them very consistently, and are not supported by most java libraries.
- It's approach to concurrency. Java built in synchronization primitive is based upon an older model of concurrency whose name I cant remember but it involves every object basically being able to maintain internal consistency with it's own state. No one still uses it like this, with most method creating an `Object lock` as a synchronization primitive.
- Serialization. Java has built in binary serialization support that ended up being a massive security hole. Most people are now forced to use some json serialization, but the old serialization format is still lurking in the background to ensnare less knowledgeable programmers.
- Generics. Smarter people than me can probably give you more detail on this, but generics were grafted on to the language long after it was introduced, and it shows. At runtime, there are no generic types kept, meaning it is technically possible to break the generic typing of an object.
None of these it should be noted are deal breakers or reasons why you shouldn't use the language. Almost every single one has some form of workaround for it. But if you're not aware of them (or stuck with an older legacy codebase like a lot of people are) they can be major headaches that can just be avoided by using a more modern language.