Hacker News new | ask | show | jobs
by matsemann 1547 days ago
The stack I've seen, used and liked at many clients is: Spring Boot, Kotlin, IntelliJ.

Which of course means all the old discussions: Jetty/Tomcat/JBoss/GlassFish, GSON/Jackson, Hikari/C3PO/etc, etc are now mostly moot, since most just use the Boot defaults until they need something else. Kinda nice, actually. Less bikeshedding, can get a project up and running without taking a stand on all these things.

Most clients use maven, a few gradle, some used gradle and moved back when no one could understand their config. Gradle might get a second chance now that it can be written using kotlin.

4 comments

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.

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.
This is it. The irony is that the modern Java stack uses the JVM & classlib, but a different language.

If you want to go full hipster, there is Micronaut (also Quarkus) and if you'd like to go a bit off-charts, there is Dropwizard. I don't think that they offer anything extra over SB though.

Or for hipsters there's https://www.jhipster.tech/
One of my first PRs ever was to that project, back in 2013. Then it was a nice starter project, showing how one could move away from the clunky server side rendering frameworks at the time, instead using AngularJS on the frontend and having a backend. And also included a nice simple Spring setup, before Spring Boot existed. So pretty hip, and very lean.

Since then it has.. evolved to something quite big, I feel, where one quickly end up with lots of unknown boilerplate in one's project. I mean, it's probably useful in its own way, almost like a Django alternative or something with batteries included. But not very hipster anymore.

Can confirm this is my stack at a fortune 500 web/entertainment company.
As someone who hasn't really touched the Java ecosystem since around the time of Java 7, where would you recommend starting?

Pick up Kotlin first, then Spring Boot? Or the reverse? And is the free version of IntelliJ good enough? I noticed on the features list that Spring support wasn't listed

Like with any language pick something you want to build and then build it and perhaps don't get too carried away with the level of ambition. Intellij Community edition is fine. It's what I use. Some of the spring support in the commercial edition is nice but I don't really miss it.

If you have some old Java code, a good way to get started is converting some of that to Kotlin in intellij. You'll get familiar with the syntax that way and you can figure out the language as you go. Mostly things are a bit different but not that much. Nicer too. I remember my first afternoon of converting a few tests and then really liking what I saw. That's five years ago.

If you are doing a greenfield project, I'd suggest starting with a simpler framework like ktor. Especially if you come from a node.js or go background. Ktor is very nice. No annotation magic, easy to understand, and you can write a simple http service in a few lines of code. There's nothing wrong with Spring Boot (I use it), but it's just a lot to wrap your head around and figure out. Even just deciding on which bits you should and shouldn't work involves a lot of decision making. It has a lot of legacy features at this point.