Hacker News new | ask | show | jobs
by jillesvangurp 1547 days ago
Yes. Perhaps to add to this, use a modern asynchronous IO framework. If you use Spring Boot, ignore some of the legacy stuff that still comes with it and make sure you use webflux with Kotlin co-routines. Also use Asynchronous IO for talking to your database, queues, etc. Kotlin makes all of this easy. Hibernate is something I tend to avoid for various reasons but apparently recent versions of that now also support asynchronous IO. And it is still very popular.

If you feel more adventurous. Ktor is also quite nice and a lot more lightweight than spring. They have a pretty big 2.0 release coming up for that with a lot of nice improvements. Ktor is also a nice alternative for doing http clients. Kotlinx serialization is the way to for serialization; especially if you are interested in multiplatform. Spring supports that as well since a few releases.

If you use Kotlin, stick with Gradle and use the kotlin scripting variety. Maven is very much a second class citizen in that ecosystem. It's supported (grudgingly) but not that actually that widely used. A lot of older Spring projects might still use it because they started out as maven/java projects and only later added Kotlin. However, if you start from scratch, just use gradle and take the path of the least amount of resistance. You'll have an easier time and essentially all of the Kotlin documentation assumes you use gradle. For things like kotlin multi-platform, maven is an afterthought. I'd be surprised it works at all actually for that.

4 comments

I really wouldn’t go the async way unless it was deemed absolutely necessary for maximal performance — it makes reasoning/debugging much harder with often not much gain.

Also, if one can just wait a few years, loom will make many part of it obsolete - when blocking code will magically get non-blocking while it retains the readibility.

I've had very few issues with that. Mostly the async code looks almost identical to the synchronous variant with Kotlin. There's a bit of a learning curve and it helps if you understand parallel and asynchronous programming a little. There is no magic with blocking vs. non blocking. Your IDE will tell you if you are doing it wrong. The fix is usually to have a co-routine context backed by a thread pool and schedule co-routines that block there.

Loom won't make any of this obsolete. If anything, co-routines will probably be the most user friendly API to use Loom when it comes available. Loom is a pretty low level API and you probably should not use it directly and instead use something that uses that. Like Kotlin co-routines, which is designed as a high level API that can be backed by all sorts of asynchronous and parallel computing implementations/

Extension functions exist for webflux, rx-java, vert.x, thread pools and much more. Basically, it sits on top of these things. It also works on kotlin native, kotlin-js (in a browser and node-js) and in the JVM where the underlying platform of course provides very different implementations. For the end user, it works pretty much in the same way across these platforms.

Loom will just be another low level backend for the co-routine API. It will likely give you some performance benefits if it's available and that's about it. Update the co-routine library, maybe fiddle a bit with your co-routine scope's and you'll be using Loom. I'd expect very little code changes would be needed when the time comes. Perhaps none at all actually (aside from bumping a version number).

I find the big problem with async is the libraries, not necessarily the async piece itself. I looked at Webflux (Project Reactor)/RxJava/etc. years ago and discovered that the composable async components unexpectedly maintain state, and that's really the piece that makes it hard to reason about.

I've since switched over to Scala + cats-effect. I found that to be a huge learning curve, but the payoff for me has been library support for easy-to-use and easy-to-understand concurrent and asynchronous programming. I cannot recommend it enough.

I tried to keep my post very little opinionated, and just write what I've seen the last couple of years. While you have some good points in yours, it's not necessarily the best idea to go straight for these "hipper" things if one's trying to break into java dev. Then it's easier to start with the boring stuff everyone use, as that is what one most likely will encounter.

As for Hibernate, I've seen a trend of using ORMs less and less. And if it's used, it's in a simple dao layer so that the rest of the application doesn't have to deal with how data is fetched.

I don't consider synchronous programming as being legacy.

For many projects synchronous programming can work just fine, and it lowers complexity.

I wouldn't bother with async unless there's a solid reason. Most Java libraries assume a standard, synchronous model and Java threads are relatively cheap these days. There's no point in going against the grain.