The HN crowd is not very fond of the magic in popular Java frameworks but to me that magic is what makes those frameworks so good, although with a bit of a learning curve at first.

Kotlin/Java with a framework like Spring is the sweet spot for web/api development. Fast enough for most use cases, great tooling, huge ecosystem, just the right level of abstraction, easy to deploy, easy to debug, very expressive code using annotations. An API backed by an ORM can be written in 10 minutes with less than 50 lines of Kotlin.

The cons are mostly compile time and startup time. Startup time isn't very relevant for backend services. Compile times aren't great but not horrible either.

The pain point with Java as mentioned in other comments in this thread is the presence of null, which among some other things make it a little verbose. That's where Kotlin comes in. Usually my projects will use framework libraries in Java and my own code is all Kotlin. The nulls go away once code exits from Java land into Kotlin land.

While admittedly not as nice as having it built into the type system from day one, there are a number of tools one can integrate into their build to add various degrees of null safety to Java.

Disclaimer: I am one of the maintainers of one such tool, namely https://github.com/uber/NullAway

It certainly won't help with verbosity (in fact, it does the opposite to at least a small degree :)), but it can dramatically reduce the number of actual NPEs when running your Java code.

Obviously I am not saying this is a reason to not use Kotlin. But, when, e.g. based on the things mentioned elsewhere in this comment section, you are deciding to stick with Java for a particular codebase, it doesn't mean static null checking is not an orthogonal option to consider.