Ask HN: Using Java for a web application in 2023 Hi HN, Does anybody have experience launching a web application with Java recently as compared to more modern framework and does anyone have any feedback? Thank you! |
Ask HN: Using Java for a web application in 2023 Hi HN, Does anybody have experience launching a web application with Java recently as compared to more modern framework and does anyone have any feedback? Thank you! |
It has a better syntax, more up to date tools and is officially supported by JetBrains too. It also has the Ktor framework which is really fun to work with.
The two challenges I’ve encountered basically come back to there being two distinct communities: “Java that doesn’t suck” and “Enterprise Java™”. It is very easy to get people who learned enough Java 6 to get a CRUD job at a bank or government contractor, and they’ll give you an app with a ton of snarled, fragile code and a dependency stack deep enough to make a Node developer wince. It’s harder to find good developers since on paper both of them will look the same to HR — IT or CS degree, 10-15 years of experience, AWS experience, etc. — so you’ll have more work filtering than you would with non-default languages.
JavaScript/NodeJS certainly has a similar version of the problem but a couple decades earlier in the process, and not being the choice of enterprise it’s less common to see people who’ve been doing the same thing for a decade.
Again, as in my previous comment, this isn’t a problem with Java the language but rather a sampling problem with the massive community.
Grails has GSP templates, while Spring Boot and Micronaut supports several, but I prefer either Thymeleaf or JTE templates.
Grails and Spring uses Hibernate, which is fantastic to work with. Micronaut has its own orm, which is really fast. In Grails Hibernate is abstracted into something named GORM, Spring Boot's Hibernate abstraction is named Spring Data. Spring Data is more polished than GORM. They're both very well documented and easy to use.
They are all very easy to use with other excellent Java tools/libraries, Kafka, Pulsar, Neo4j and so on.
If time to market is your thing, pick Grails. (This is what I care most about)
If performance (web scale) is your thing, pick Micronaut.
If best documented is most important, pick Spring Boot.
Grails is an abstraction of Spring Boot, basically you can do everything Spring Boot can. But Grails makes Spring Boot a lot easier, especially for inexperienced developers.
My personal impression is that Grails lost much of the momentum it had years ago.
As such I can safely say that anyone that thinks Java is good to use for anything these days, especially with things like Log4Shell, simply doesn't know enough about computer science. Java is a poorly designed language with corporate bullshit throughout, and while it may have been an option in the past given alternatives, is no longer the case.
Python, Rust, C/C++, Golang, and Javascript (and derivatives) cover pretty much every application category in terms of applicability.
It decent for applications, web services. Prefer C++ for embedded programming. Python for scripts and data wrangling and ML.
Sorry but what do I not know about computer science?
What a general purpose programming language choice have to do with knowing computer science?
That being said, I think that there is a great ecosystem of great software and tools written for Java. I like learning new languages and techniques, but I find Java is suitable for many things today.
Depending on your scale/budget they’re a bit more expensive to host due to JVM memory requirements but performance is good. Not a Java issue but a issue if you choose a language other than JavaScript for the frontend is you need to up skill frontend devs with the Java build tools/templating libraries and most frontend devs will have a bias against Java as it’s been bashed by lots of people who haven’t used it, it’s not sexy and they think of Java aplets from the 2000s.
The deeper question is how often you actually benefit from code reuse. There are certainly some areas where you can share things but you also run into a lot of coordination concerns because the environment for JS in a browser is not the same as in Node, which increases the friction of sharing, and a large chunk of the benefits are things like data validation which can also be substantially eased with things like JSON Schema. Simplifying those test matrices and formalizing your boundaries has more value than I tend to assume at first.
With more people working on it, like typical companies, it doesn't hold a ton of water. Every language has its place to where it's best suited. You can get a more performant, better structured, and safer backend in other languages.
Many of the applications you use day to day, are backed by a Java backend. Netflix/Much of AWS/Zillow/LinkedIn/Indeed/Much of Google
The main advantage of Java in my mind is how old, mature, and stable the ecosystem is. Everything has a library for it.
Also, if you later decide to use a cooler/more expressive language, you can actually keep your Java code and use one of the other popular JVM languages with interop. (Scala, Kotlin, Clojure)
One challenge here though is that many of those libraries are no longer maintained because the original developers moved away or retired years ago. I have a couple of relatively recent projects which require significant maintenance work dealing with unfixable CVEs or forced major updates which require non-trivial migration. That meant that even using an active project like Solr or Keycloak requires a surprising amount of maintenance developer time.
I don’t think we’ve fully gotten used to the changing supply chain trust situation in open source, and that’s going to hit all of the old ecosystems the hardest.
Second point, while the frameworks can be helpful (Spring, VertX, Micronaut, Quarkus, etc) you don't actually need one. Ktor or http4k as your http/routing engine (& client), jooQ for DB access, H2 as a caching database if necessary -- these will take you a long way.
The only downside I experience is fewer deployment options -- can't natively deploy to Fly.io, Railway, etc except via Docker. With that said, setting up a simple VPS with Adoptium JVM is pretty easy. Hope this helps -- good luck!
That said, I'd honestly start by ignoring the common frameworks and just use something like Jetty embedded to create some API endpoints.
There's a lot of learning required for the common frameworks like Spring Boot. Browse the documentation and you'll see there's a lot there. Plus, they tend to be a debugging challenge for new people due to use of reflection and the like.
What's your web front end going to be? Do you have something in mind which can make clean calls to a Java backend?
If so then Java remains a safe, trustworthy choice, and is relatively productive once you know it reasonably well. As per other commentors, Spring Boot is a good framework.
They transpile java code to JavaScript, HTML, and css. They are tightly coupled to their RPC apis.
That said, I wouldn't recommend it for new projects.
== ARCHITECTURE
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.
== BACK END FRAMEWORKS / LIBRARIES
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: https://start.spring.io/
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: https://spring.io/quickstart
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: https://www.dropwizard.io/en/latest/
It won't be as smooth as Spring Boot, but I used recently for a small side project of mine: https://blog.kronis.dev/tutorials/2-4-pidgeot-a-system-for-m...
Some folks might also enjoy Quarkus, which got some hype in the recent years: https://quarkus.io/
Those who like reactive programming, might look into Vert.X: https://vertx.io/ (it doesn't quite feel like idiomatic Java, but is interesting nonetheless)
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.
== FRONT END FRAMEWORKS / LIBRARIES (if you want to use Java for these)
For some basic templating, Thymeleaf should be okay: https://www.thymeleaf.org/
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): https://www.baeldung.com/spring-template-engines
If you really want to do something more interactive but still in Java, you could use something like Vaadin: https://vaadin.com/
It's okay, but in my eyes still probably more suitable for internal admin panels, rather than that many client facing applications.
Personally I'd avoid GWT, my experiences with it were only negative.
== SUMMARY
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.
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.
Use what you are comfortable with and get the app out there. Way more important than what stack you are using. Now excuse me while I go and look at all the shiny things on HN.
check that out if you want to be single lang but not use js/ts.
There is formatting support via Gradle and Maven. You can even run prettier via prettier-java.
Boilerplate more exists in frameworks especially the older the 1s. You don't have to use it.
For formatting, the only compelling truly framework agnostic option I know is the google formatter (unconfigurable). The other options are either editor specific (IntelliJ and Eclipse configurations are incompatible go figure), cost money or are half-baked (prettier). Now I believe there's a way to use spotless (tied to gradle/maven) to use one of the IDE specific formatters across IDEs at the build tool level, as you point out, but that's kind of a different thing, heavy weight and working around the underlying problem. Compare this to gofmt, rustfmt, scalafmt, black, prettier/eslint, etc. that are fast, framework agnostic and require no boilerplate. Formatting is a solvable problem in Javaland to a degree, but wow is it unnecessarily complicated and fraught with decision points that can end up in bikeshedding committees.
As for boiler plate, I'm talking about language level stuff, like having to make a class and separate file for every simple data structure, then having to implement hashcode/equals for all those classes, etc. Where in other languages, you can just return a tuple or a result or what have you and get on with your life. Again, IntelliJ will just do most of this for you, but supervising my IDE in boilerplate creation is not a joyful experience. And if you skip supervision, you are basically saying the IDE is now a dependency and the correctness of your program depends on the correctness of your IDE. Not super great.
Anyway, IntelliJ is certainly an amazing piece of software that makes Java development more productive, but learning it, configuring it, etc is a whole thing. Other modern languages provide much better QoL features out of the box and have a much less incidental complexity that don't require an IDE to get around. That said Java has the best library ecosystem, the biggest pool of developers and solid performance.
Not sure I agree here. One needs to know a good amount about how Spring works before they can start configuring Spring app. Methods annotated with @Bean would look strange to any newcomer, or how about trying to figure out how messaging libs set up works (let's say Kafka) would be very confusing.
using random lib sound poor or inexperienced developer problem not java problem. same issue can happen in other language.
but this all beside point.
let say java terrible choice.
tell us more about how using java mean we dont know computer science. still want to understand how language choice a “computer science” problem. teach us.
Worked, and Yes. But thats due to legacy more than anything else, and because the builder tools team built a pretty sizeable ecosystem around dependencies/builds with Java, with a lot of templates out of the box.
>tell us more about how using java mean we dont know computer science. still want to understand how language choice a “computer science” problem. teach us.
Early on at Google, there was an engineering decision to use “Python where we can, C++ where we must.” There is a reason for that.
In terms of performance, a VM language is really good when you are dealing with multiple architectures. Java was a good choice back in the day to support application development across multiple environments.
As such Java was the natural choice for Android for quick application development. But lets look at how that evolved over time
- Most performance heavy applications are written heavily with NDK. Google provided this specifically because the jvm layer doesn't suit things like games very well.
- Java isn't even the official SDK language, Kotlin is preferred, which essentially "fixes" a lot of Java things. BTW there was guidance at Amazon to use Kotlin over Java going forward because it results in a better maintainable codebase.
- Google is heavily investing into Fuschia, with Flutter/Dart, as the next gen mobile/home device OS. In general a lot of web app application style apps are written with React Native, which is structured very similarly to Flutter/Dart (as the code can be compiled to a JS web app as well)
So it seems like Google, the company responsible for putting a JVM on majority of the worlds smartphones, doesn't even believe it it anymore. Python or Golang is all you really need these days for any backend - you develop faster, code runs just as fast (especially with Python 3.11, or previously with PyPy), taking account that most of the time the latency driver is going to be network requests, and you have a much better tooling with those language.
As for vulnerable software you are correct though , vulnerabilities can happen in other languages. Golang seems to have quite a few. Python had one back in 2007 with tarfiles. Meanwhile, your favorite Java now has Spring4Shell circulating around, and I hopefully don't have to explain how in the case of Log4j, a developer willingly writing the network request/execute code as part of logging something is much, much worse than finding some bug that can make a program crash in very specific conditions.
And this is because of the core issue of Java of having so few core libraries compared to Go and Python - so instead you have random projects with questionable people working on them, and then these projects get all hodgepodged together into the modern day Java best practices. So you have things like big dependency injection frameworks that eat startup time, or things like Lombok that essentially hack the AST. There is no central authority controlling what Java is, so you get these Log4Shell, Spring4Shell and others.
But lets ignore all that, and focus on the fact that Java still runs fast, for whatever weird reason you need speed. So what exactly does Java give you over Golang or Python? OOP semantics? Strong typing?
Lets look at how that works in practice. Every professional Java codebase will have unit tests. Everything that you can possibly ever catch compile time you absolutely can catch with unit tests, and there will never be an argument against writing less unit tests for anything because "compiling hypothetically catches all the errors for you". Now take your standard java project, where you have a build system like Gradle. You run your compile process, which is groovy being compiled to JVM that gets executed to run additional commands that do things like annotation processing, after which all of your code gets compiled into a jar file, then ran, where the dependency injection frameworks have to load, and then your unit tests get ran. At Amazon, every time you wanted to either run unit tests or start up the service, it took at least 10 seconds for everything to run before your code gets executed. In comparison, launching Python interpreter to run your additional unit test that you wrote is quite fast. Look at AWS Lambda start times between Java and Python if you don't believe me.
The only thing strong typing does is that it makes it harder for, lets say "entry level" devs to shoot themselves in the foot, since they are essentially using an API. But Java does provide ways to shoot yourself in the foot, which is why code reviews are a thing. And if you have code reviews, then you can collaborative drive a certain structure even in dynamically typed languages like Python towards minimizing mistakes, even more so because development happens faster so you have an easier time putting in everything that needs to be put in.
So in the end, if you didn't realize all of this, then you don't fully understand computer science. If you do realize this, and still think Java is ok to use today, then you either are delusional, or are privy to some great wisdom that nobody else knows.
amazon move fast in this space. if something have expensive or hurt innovation they move quickly off. sometimes company wide campaign to block "X" going to production. tell an amazon principal or sr. principal they only have java for legacy reason and they will ask you what company you work at.
>>> - Most performance heavy applications are written heavily with NDK. Google provided this specifically because the jvm layer doesn't suit things like games very well.
nobody here talk about writing super performance optimized thing. we not talking about games. dont know anyone using java for games and you writing strawman argument.
>>> BTW there was guidance at Amazon to use Kotlin over Java going forward because it results in a better maintainable codebase.
this not true. maybe you team has its own preference for kotlin. no company wide guidance on this. how i know? you not only person worked at amazon.
> Google is heavily investing into Fuschia, with Flutter/Dart, as the next gen mobile/home device OS. In general a lot of web app application style apps are written with React Native, which is structured very similarly to Flutter/Dart (as the code can be compiled to a JS web app as well)
yeah even amazon using react native for some apps. what this have to do with java? and what specifically it have to do with your assertion about using java mean not knowing computer science?
>>> Meanwhile, your favorite Java now has Spring4Shell circulating around, and I hopefully don't have to explain how in the case of Log4j, a developer willingly writing the network request/execute code as part of logging something is much, much worse than finding some bug that can make a program crash in very specific conditions.
bugs happen in any software. make no sense how this is indictment of java as language. you picking logging issues. even go has many logging frameworks. c++ std lib not include logging as first class afaik. again this argument have no merit.
>>> So you have things like big dependency injection frameworks that eat startup time, or things like Lombok that essentially hack the AST. There is no central authority controlling what Java is, so you get these Log4Shell, Spring4Shell and others.
nobody force you use big dependency injection framework or use Lombok. it your choice.
>>> At Amazon, every time you wanted to either run unit tests or start up the service, it took at least 10 seconds for everything to run before your code gets executed.
amazon has own flavor of build system. Brazil and it many variations for different languages very old..slow..some combination of both. if you work at amazon you should know about amazon tax.
>>> The only thing strong typing does is that it makes it harder for, lets say "entry level" devs to shoot themselves in the foot, since they are essentially using an API.
are you complaining on java or strong typing?
>>> The only thing strong typing does is that it makes it harder for, lets say "entry level" devs to shoot themselves in the foot, since they are essentially using an API
^ This comment make no sense. strong typing is like using an api? LOL
>>> But Java does provide ways to shoot yourself in the foot, which is why code reviews are a thing.
So move off java and we can stop doing code reviews?
>>> So in the end, if you didn't realize all of this, then you don't fully understand computer science.
language choice has nothing to do with knowing or not knowing computer science. this is one of most absurd comment seen. LOL :)
computer science not focus on any particular language. cs program may have course on programming languages..cover history of languages.. regular grammars.. what it means have abstractions. concepts critical to design of a language. it care nothing at all if you have fetish for python or go or angry tears about some java logging framework.
>>> If you do realize this, and still think Java is ok to use today, then you either are delusional, or are privy to some great wisdom that nobody else knows.
if java not okay to use then amazon distinguished engineer, sr. principal, and principal community would deprecate or ban language entirely. you wrote lengthy post. maybe you found yourself clever asserting point about java being slow for games. can assure you if you write this as amazon doc.. senior leaders not take you seriously.
calling people "delusional" for not agreeing with your opinion strong indication you presenting weak argument. and thats me very generous. this more like infantile "hissy fit" behavior. you confuse HN with reddit maybe.
you never answered question how language choice related to knowing or not knowing computer science.
1. Nobody is forcing you to use Java
2. Appealing to authority as justification for Java use.
Neither of which go to contrary of anything I said, so this is a pointless discussion because it basically means you agree to every drawback of Java I stated.
Never said this. Said no one forced you to use lombok or what library you complaining about. not only do you make false statement but you dishonest in debate.
>>> 2. Appealing to authority as justification for Java use.
you use google as example of company not believing in java, that amazon encouraging not using Java (which not true)… you opening statements in you angry rant all about appealing to authority. now you projecting.
it pointless discussion because you make angry rant on java..appeal to authority..and most importantly..you make claim about use of java mean one not know computer science.
you yourself not understand computer science. it have nothing to do with any language choice.
entire premise of you argument completely flawed and embarrassingly wrong. poor essay attempt. maybe you were amazon SDE 1 at best.