Live data from Hacker News

Java 21: The Nice, the Meh, and the Momentous

horstmann.com

111–120 of 191 posts

Re: Java 21: The Nice, the Meh, and the Momentous

#111
post #84
post #48

Earlier quoted context omitted.

"Oh look, I need to upgrade mockito and Spring. Oh, now I upgraded Spring I need to update the spring JPA plugin. Oh now I upgraded that I need to upgrade Hibernate. Oh now I need to upgrade the library built on it that that team over there maintains. Oh, they're not interested." etc. etc.

Having a lot of experience with that stack... it is why i migrated to scala long ago

Tho Scala makes the upgrade problem even worse:)

Re: Java 21: The Nice, the Meh, and the Momentous

#112
post #42
post #7

Virtual threads are going to be great, but they're still limited (still starved the pool when used with 'synchronized' blocks), and they aren't the structured concurrency power houses like kotlin coroutines, but its an invaluable tool that will only continue to accelerate as the ecosystem moves to adopt them. Expect a lot of libraries to start release versions that are java 21 baseline because of this feature alone.…

> Expect a lot of libraries to start release versions that are java 21 baseline because of this feature alone. Java has had multi-version jars since 11 I think... that allows library authors to ship code that benefits from new features in newer versions of the JDK while still supporting older ones as well. Hopefully library authors can leverage that, though I'm aware something like Virtual Threads may be very difficu…

mrjars are a terrible idea, because libraries are very rarely a single jar, and require dependencies. Often that dependency set is different depending on the runtime version because of backports of newer Java APIs. So either you don't care and make your consumers use proguard to remove the unnecessary backports, or you create a Maven package with variants for each runtime version, which 99% of your downstream will end up using anyway.

Re: Java 21: The Nice, the Meh, and the Momentous

#113
post #44

Earlier quoted context omitted.

Why haven't places updated already? It's not that much work to update. Where I work we always go to the new LTS version as soon as it's supported by gradle. Doesn't cross anyone's mind to _not_ upgrade.

The bigger the project, the more painful the upgrade. Package systems are convenient to avoid reinventing the wheel, until you have to upgrade any piece of it. Then you're stuck trying to figure out which versions of each package go together. If Package A won't run on JDK 17 your entire project is stuck on JDK 11. If Package B is upgraded but has conflicts with Package A, you have to dig through old versions until yo…

Java isn't forward compatible?

Re: Java 21: The Nice, the Meh, and the Momentous

#114
post #109

Earlier quoted context omitted.

* for high performance stuff you can still wrap the medium speed/slower stuff in virtual threads.

Do you have a citation for that? Genuinely curious.

The stack for the VT requires a heap allocation [0], which ok, not huge deal for most scenarios, but something to consider. Reactive programming will avoid that. For example, for a service that doesn't do much IO (like an in memory pubsub thing or CDN) you would still want to use reactive programming if you care about performance, since likely the code will be simple anyway.

[0] https://openjdk.org/jeps/444

Re: Java 21: The Nice, the Meh, and the Momentous

#116
post #90

Earlier quoted context omitted.

I watched the video and thoroughly enjoyed it, thank you for sharing it! I have a question that is perhaps not entirely related to the video, but it touches the topic of context switches. I've read this post [1] by Chris Hegarty, which explains that when calling the traditionally blocking network I/O APIs in the Java stdlib from a virtual thread, it uses asynchronous/poll-based kernel syscalls (IOCP, kqueue, epoll on…

> That post was written in 2021, does it still hold true today in Java 21? Yes. > Does Java Virtual Threads do the same, or does disk I/O block the carrier threads? For curiosity, does Java file APIs use io_uring on Linux if it is available? We're working on using io_uring where available, especially for filesystem IO. For now, filesystem IO blocks OS threads but we temporarily compensate by increasing the size of th…

In late 2021 I compared OS threads to io_uring for filesystem I/O at random-access reads from fast, NVMe SSDs.

That measurement told me that it's not necessary to use io_uring for disk I/O performance for some workloads.

It found no improvement in performance from io_uring, compared with a dynamic thread pool which tries to maintain enough I/O-blocked threads to keep the various kernel and device queues busy enough.

This was a little surprising, because the read-syscall overhead when using threads was measurable. preadv2() was surprisingly much slower than pread(), so I used the latter. I used CLONE_IO and very small stacks for the I/O threads (less than a page; about 1kiB IIRC), but the performance was pretty good using only pthreads without those thread optimisations. Probably I had a good thread pool and queue logic, as it surprised me that the result was much faster than "fio" banchmark results had led me to expect.

In principle, io_uring should be a little more robust to different scenarios with competing processes, compared with blocking I/O threads, because it has access to kernel scheduling in a way that userspace does not. I also expect io_uring to get a little faster with time, compared with the kernel I tested on.

However, on Linux, OS threads* have been the fastest way to do filesystem and block-device I/O for a long time. (* except for CLONE_IO not being set by default, but that flag is ignored in most configurations in current kernels),

Re: Java 21: The Nice, the Meh, and the Momentous

#117
post #31

Earlier quoted context omitted.

In Python you can terminate a for loop with else, which will be run whenever the loop runs to the end without breaking

Neat. Will check it out. I recently spotted a (new to me) foreach / else construct in a templating language (sorry, forget which one); else is invoked if the list is empty. Nice sugar for common outputs like "no items found". I appreciate modest syntactic sugar. For instance, my #1 sugar wish is for Java's foreach is to do nothing when the list reference is null. Versus tossing a NPE. Eliminates an unnecessary null c…

> else is invoked if the list is empty.

for / else should do that too …

Re: Java 21: The Nice, the Meh, and the Momentous

#118
post #46

Earlier quoted context omitted.

> We recently added pattern matching to Dart [1] I've been using that and I love it, in general... but can I ask you why do we need to name a variable in a pattern like this: switch (p) { Person(name: var name) => ... } That's the only thing that feels a bit annoying as you have to rename the variable... In Java, this would be something like: Person(var name) -> ... EDIT: I guess it's to support `Person(name: 'litera…

We require "var" before variable patterns because we also allow named constants in patterns (which match if the value is equal to the constant's value): const pi = 3.14; // Close enough. switch (value) { (pi, var pi) => ... } This case matches a record whose first field is equal to 3.14 and binds the second field to a new variable named "pi". Of course, in practice, you wouldn't actually shadow a constant like this,…

I don't find symbols to be pointless. They are useful as "interned strings" and that's exactly what I need sometimes. I could use `const myThing = "my thing";` for that purpose (but with symbols I don't need to declare it anywhere, just use it... for better or worse!), I suppose, but before `const` existed, I believe symbols were the only way to do that?

Re: Java 21: The Nice, the Meh, and the Momentous

#119
post #67
post #43

Earlier quoted context omitted.

That's pretty disingenuous. Groovy has always run on newer JDK versions before they even get released. One year ago, Gpars already supported Virtual Threads: https://groovy.apache.org/blog/gpars-meets-virtual-threads As a heavy user of Groovy/Spock, though, I agree that upgrading Groovy itself can be challenging, unfortunately. Really depends though on how many edgy Groovy features you relied on :).

Not always for sure. We started JDK upgrades with 9 and went +1 every half year and Groovy was lacking with one of 10, 11, 12 or 13. It got so tiring that we had to let it go. Fortunately our tests were mostly JUnit 5, so it wasn't much of work. We only used it for Spock AFAIR.

If you're upgrading every minor Java version, then yeah, I agree Groovy and most other dependencies that may not work on Java version changes off the bat (Lambok, probably Spring and other heavy frameworks like Micronaut and Quarkus, build tools like Gradle... many more) are going to slow you down. You end up with a very simple project if you remove all of that, which is actually a good thing if you can afford doing it.

Re: Java 21: The Nice, the Meh, and the Momentous

#120
post #114

Earlier quoted context omitted.

Do you have a citation for that? Genuinely curious.

The stack for the VT requires a heap allocation [0], which ok, not huge deal for most scenarios, but something to consider. Reactive programming will avoid that. For example, for a service that doesn't do much IO (like an in memory pubsub thing or CDN) you would still want to use reactive programming if you care about performance, since likely the code will be simple anyway. [0] https://openjdk.org/jeps/444

Bullshit - reactive frameworks allocate a shit ton of helper classes.
Post reply on HN