Personally, I'd say that either Kotlin or Java are okay language choices (and the JVM runtime is good too), not unlike something like modern .NET. The performance is good, the type system is passable, you have bits of FP and OOP to use at your leisure, there's a rich ecosystem of a variety of libraries out there.<p>== ARCHITECTURE<p>As for the architecture, I'm still a proponent of separate back end and front end components, say, using Java for your REST/GraphQL API, and something like Vue/React/Angular for your front end (with the latter packaged in a web server of your choice, like Caddy/Nginx/Apache). In my experience, it's just simpler that way, though YMMV.<p>== BACK END FRAMEWORKS / LIBRARIES<p>As for Java itself, I'd say that Spring Boot is the boring and dependable choice, it does basically everything you might need and is not too hard to configure. Admittedly, it feels inherently enterprisey and a bit cumbersome, even though it's leaps and bounds easier than regular Spring. This is probably a good starting point: <a href="https://start.spring.io/" rel="nofollow">https://start.spring.io/</a><p>It will generate starter projects that you can download and open in your IDE, maybe look at the getting started guides on the offical site: <a href="https://spring.io/quickstart" rel="nofollow">https://spring.io/quickstart</a><p>Personally, I'd also look at Dropwizard, which is smaller, simpler and still good enough for many use cases, because it combines a variety of "standard" (popular) packages for Java webdev: <a href="https://www.dropwizard.io/en/latest/" rel="nofollow">https://www.dropwizard.io/en/latest/</a><p>It won't be as smooth as Spring Boot, but I used recently for a small side project of mine: <a href="https://blog.kronis.dev/tutorials/2-4-pidgeot-a-system-for-millions-of-documents-the-application" rel="nofollow">https://blog.kronis.dev/tutorials/2-4-pidgeot-a-system-for-m...</a><p>Some folks might also enjoy Quarkus, which got some hype in the recent years: <a href="https://quarkus.io/" rel="nofollow">https://quarkus.io/</a><p>Those who like reactive programming, might look into Vert.X: <a href="https://vertx.io/" rel="nofollow">https://vertx.io/</a> (it doesn't quite feel like idiomatic Java, but is interesting nonetheless)<p>There's also Jakarta EE (formerly Java EE, formerly J2EE), which can be okay, but personally I'd avoid it in favor of one of the more popular options.<p>== FRONT END FRAMEWORKS / LIBRARIES (if you want to use Java for these)<p>For some basic templating, Thymeleaf should be okay: <a href="https://www.thymeleaf.org/" rel="nofollow">https://www.thymeleaf.org/</a><p>There's also Apache FreeMarker, Apache Velocity, JSP and JSF (I've seen it used with PrimeFaces). Those might also be viable, but I've had issues, especially with the latter ones. Regardless, here's an article about some of them (for Spring): <a href="https://www.baeldung.com/spring-template-engines" rel="nofollow">https://www.baeldung.com/spring-template-engines</a><p>If you <i>really</i> want to do something more interactive but still in Java, you could use something like Vaadin: <a href="https://vaadin.com/" rel="nofollow">https://vaadin.com/</a><p>It's okay, but in my eyes still probably more suitable for internal admin panels, rather than that many client facing applications.<p>Personally I'd avoid GWT, my experiences with it were only negative.<p>== SUMMARY<p>I'd say that Java is an okay fit for a back end language - if you can get JetBrains tools (IntelliJ), you're going to have a really good time with writing code, thanks to code completion, refactoring and so on. The frameworks that are out there are reasonably stable, widely used and documented. You can also get whatever JDK distributions you want, like Eclipse Temurin. Oh, also JMX for debugging and instrumentation is great, you can see every single DB query that the app does, as well as aggregate that data, maybe get flame graphs, or just look at how GC works. Integration with things like Sentry or Apache Skywalking is also great.<p>Using it for anything regarding front end is more risky and might be a bit more problematic. Not saying it will, just that it might - serving packaged assets for a Vue/React/Angular app from a web server directly (or maybe through a container) would probably be more simple, especially with a reverse proxy configuration.