JDK 28(openjdk.org) |
The last few years of server-side has been on Kotlin for me, however, modern Java is looking more and more like anything I'd need in a language.
I love Java and I’m so glad it’s kept improving so much despite all the turmoil in its ownership.
Pretty much the opposite. Those who disliked it usually cited having to type too much due to class verbosity and variable verbosity (the former has merit, the latter was purely a choice).
If you no longer need to type in any of the code, what better than a language with a blazing fast and scalable runtime, with excellent debugging and monitoring support.
$ echo 'class Hello { public static void main(String[] args) { System.out.println("Hello, world"); } }' >Hello.java
$ javac Hello.java
$ java --version
openjdk 21.0.7 2025-04-15 LTS
OpenJDK Runtime Environment Zulu21.42+21-CRaC-CA (build 21.0.7+6-LTS)
OpenJDK 64-Bit Server VM Zulu21.42+21-CRaC-CA (build 21.0.7+6-LTS, mixed mode, sharing)
$ time java -cp . Hello
Hello, world
real 0m0.026s
user 0m0.010s
sys 0m0.018s
For some reason this machine is still on 21. Anyway, the overhead of the JVM itself is pretty low.For small tools it's fine:
$ echo 'class Dig { public static void main(String[] args) throws Exception { var addr = java.net.InetAddress.getByName(args[0]); System.out.println(addr); } }' >Dig.java
$ javac Dig.java
$ time java -cp . Dig news.ycombinator.com
news.ycombinator.com/209.216.230.207
real 0m0.047s
user 0m0.026s
sys 0m0.021s
$ time host news.ycombinator.com
news.ycombinator.com has address 209.216.230.207
news.ycombinator.com has IPv6 address 2606:7100:1:67::26
real 0m0.052s
user 0m0.005s
sys 0m0.004s
Java startup gets slow when you use some massive framework like Spring. If you need a program to start fast, don't use one!- AOT compilation: https://openjdk.org/jeps/544 - ~100ms startup for ZGC: https://openjdk.org/jeps/545
Almost all Java benchmarks are for the "steady state" after half an hour of warm up time.
There are other solutions that give you MUCH faster startup with lower memory e.g.: https://foojay.io/today/java-server-work-before-startup/
Edit: it seems I missed that 28 added the actual native code compilation phase so it will probably be closer to the GraalVM numbers in the link above.
There is also JavaFX, but that is no longer bundled with the JDK.
* React replacement: Flavour ( https://frequal.com/Flavour/book.html )
* Vanilla JS equivalent: TeaVM ( https://www.teavm.org/ )
> trailing commas and comments are not supported
Be strict in what you produce, be lenient in what you accept.
Grr.In that case they made the right choice, as machines won't be inserting trailing commas or comments in the first place, and the risk of having consuming apps inadvertently accept invalid data would be high otherwise.
One is „accept a wide array of syntactically malformed input, ill defined, substantially complicating the parser“, the other „accept two trivial extensions to the standard that are widely used and don’t affect the resulting data in any way.“
- junit parallelisation - how are shards handled? how do you balance the tasks across forked processes? What is the bottleneck? Options are 1) pay someone for better tooling or 2) write your own
- long pauses in garbage collection - how do you know which objects are causing the pauses? the options; 1) profiling 2) analysing heap dumps that you periodically capture 3) add metrics or gc logging
- what is the performance bottleneck? options 1) profiling
Sure AI can do this stuff, but it's painful and time consuming
Contrast it to Elixir on the BEAM;
- exunit parallelization - basically free and because you don't have coupling due to OOP. mocks are basically an antipattern
- long pauses due to gc? They just don't happen - everything is isolated and can be cleaned up in parallel.
- performance bottleneck? Open inspector and see what is doing all the reductions, and if any of the inbox queues are backlogged. You don't have to profile, you can just look in production - memory? Open inspector and sort processes by size descending. Again no profiling needed
> Contrast it to Elixir on the BEAM;
Java is in the same performance class as C++. BEAM is wonderful in its own way, but it's not even in the same performance class as Go.
BEAM was designed for some interesting resilience in distributed systems. The JVM was designed to address the performance issues that programs in C++ and other low-level languages suffer from when they get large and/or are maintained/evolved for a long time.
> long pauses due to gc? They just don't happen - everything is isolated and can be cleaned up in parallel.
GC pauses in the JVM have been optional for a few years now. ZGC doesn't have GC pauses.
The parent was saying these new features don't matter as much post-AI and i think I agree with them. The AI can just write in rust if you need to optimise a hot loop, but if you need observability, you could do worse than the BEAM.
> GC pauses in the JVM have been optional for a few years now. ZGC doesn't have GC pauses.
yeah that's a fair comment, zgc is a lot better for pauses. I'd still say that it pulls along a fair bit of incidental complexity - it encourages you to allocate a fair amount of memory to your heap, which isn't ideal in this world of kubernetes and microservices. If you leave on uncommit (returning memory to he OS periodically) you get extra latency penalties which are just as painful as garbage collection stalls IMHO.
Comments were explicitly disallowed from JSON since the beginning, because they could be used as a side-channel for vendor-specific extension mechanisms and harm interoperability.
That's always how it starts. If they're truly trivial the reasoning also cuts the other way. Remove them upstream.