SecurityManager dies not with a bang, but a whimper. The professor who taught a generally-misguided Java elective extolled the benefits of the security manager whenever he could. I was tremendously skeptical at the time. I'm inappropriately smug to have been proven right now, several decades later.
I really want structured concurrency out of preview!! I think it helps close one of the last gaps golang has over Java in the ease-of-concurrent-programming side of things. Go makes channels and waitgroups pretty easy. I think structured concurrency is a great side-step of those primitives by actually making the higher-level tasks you use those tools to accomplish easier to write and reason about. Continuing a trend I see where go tends to have somewhat better primitives, but then obstinately does nothing with them to actually make the higher-level tasks easier to accomplish.
No pinning virtual threads is huge. Finally you can virtual thread with near-wild abandon, as God intended.
Love seeing Streams still getting love. I do a lot of fizzbuzz-esque interviews (the "can you code your way out of a paper bag" type screens) for my company and I think it says a lot that, in general, people who pick Java and use streams pass but people who don't use streams often get tripped up in their loop logic and fail (or, even if they don't fail per se, don't pass). It says a lot about ergonomics and intuitiveness, and also the power of the abstraction to tersely and compactly solve real problems, when a language is a big ally in interviews. And the cool thing about Java streams is that they're as powerful as Ruby's functional-style operation chaining (arr.map{}.reduce(:+) etc) but they're actually performant. I feel it also bears mentioning that people who use Ruby in these interviews, few as they are, almost always pass and do so while writing very few LOC :)
Go is the poster child for not having structured concurrency, the article that started this movement was an explicit take down of go’s concurrency primitive “go func” being dangerous.
I think Kotlin still leads here, and even the Java changes don’t have the same nice ergonomics you get with Kotlin’s DSL. Would love to see more tenseness from Kotlin leak into Java.
Yet, like most Go design decisions, they will end up retrofiting what should have been there.
Kotlin has the issue of being a guest language, and wanting to play in many playgrounds, eventually it will diverge as it always happens.
As it is already happening, like now how will Kotlin async deal with virtual threads expectations, including writing portable code that doesn't suffer from runtime semantics, depending on the target platform.
Something better than making everyone take context as the first arg in every function? It’s go’s own brute force way of function coloring, except you have to write it yourself and drag this arbitrary bag of data through every function, what a horrible stapled-on mess.
I stopped at "go statements are a form of goto statement."
This is simply not correct. They have some diagrams and squinted and said "hey, that looks the same as a goto statement", but unfortunatley they have their diagrams wrong. "go func" will run at scheduler's pleasure, not immediately after the statement "go func..". A goto statement is a deterministic flow control directive. It will goto where you tell it.
you should have read the rest of it then, because in the context of Dijkstra's famous paper [0] (that this is written in the style of) the argument here is being able to understand program flow in the programmers' mind. Your description of the go func actually makes it WORSE, because the program doesn't just go there, it goes there later.
That may be true, but regardless, it is most definitely nothing like a goto and it is misleading. & Yes I have read Dijkstra and as it happens have my own critical views regarding Go's goroutines (which are really inspired by CSP), but just don't appreciate misleading assertions. To wit, "flow" does not really make sense in context of concurrency. Flows, plural, sure ..
Well fair, but I do think you should give this article a read. It’s the genesis of kotlin’s coroutines, and other implementations of “structured concurrency” or nurseries as the author conceives of them.
Security Manager is one of the only unique selling points of Java, to remove it (without removing it because you need it underneath) is as big of a blunder as removing Applets from browsers and replacing it with something worse: WASM without GC and then adding GC to WASM...
If SVTwP is not better than NIO; Java ends with JDK 23.
> Warnings issued in JDK 17–23 generated minimal discussion in the Java ecosystem
Because no feature added after 1.8 made sense, so nobody upgraded. They are taking decisions off the wrong data.
> they are encouraged to transition to alternative sandboxing and API interception mechanisms
Unique, sure. Selling point? I really don't think so. This idea of "safely" running untrusted code in the jvm sandbox both never materialized (constant stream of sandbox-escape vulns i've seen over the years) and also was at the wrong level - anyone doing multi-tenant code execution is doing it via things like gvisor or at the OS-level.
I don't think I buy your assertion that nobody has upgraded. I know of a 3000-4000-strong eng org at a certain company that has upgraded all the way from 8 to 17 as of when i left 3 years ago. They primarily wanted the GC improvements because they translated into huge immediate efficiency gains on their workloads (huge Spark/Hadoop spend savings, and moderate savings for the non-big-data jvm workloads).
I do share your lament of applets though. It would've been a way better runtime for portable/install-less/JIT-install things than the current nightmare of html/css/js/etc. But they just didn't have the browser integration - it would've needed to be more than just "look we put a drawing surface into the web browser" - and they didn't have the "window into the world" either (that's browsers). Unfortunately, it's the front door program and platform that owns the users, and that's web browsers.
>The Security Manager was not so hard to maintain it merited a removal without replacement.
It sounds like the OpenJDK folk disagree with you, though. From the JEP:
>The Security Manager has not been the primary means of securing client-side Java code for many years, it has rarely been used to secure server-side code, and it is costly to maintain
>...Improve the maintainability of hundreds of JDK classes that currently delegate resource-access decisions to the Security Manager.
>The OpenJDK Core Libraries Group devotes significant time and energy to reviewing every change to any of these methods. Every new API must be designed, and its implementation carefully audited, with the least-privilege model in mind. However, only a tiny number of applications actually enable the Security Manager.
This seems like a big win in terms of maintainability of the core libraries.
The Security Manager was dead as soon as applets ceased to be relevant (which happened a long time before WASM appeared btw.). Deploying the Security Manager requires designing the application up front for it as well as maintaining policy files. Most developers are not aware how to do either.
But its biggest weakness is that it has to restrict a lot of overly powerful APIs. That's like spooning water with a sieve. It would have been better to let the host application restrict which APIs are visible in the first place, like it is done with browser APIs.
The projects that didn't upgrade so far are either dusty business-crirical applications that nobody cares to touch or that utterly deprioritize upgrades unless circumstances force them to. Most of the new features make a lot of sense, but nobody is going to gamble their job on forcing an upgrade just to being able to use them.
To suppress things like `System.exit(0)`, agents can be used. Proper sandboxing solutions would be VMs and containerization technologies. Achieving perfect sandboxing within a process is hopeless anyway.
With some work on better tooling it could've been used to detect and thwart supply chain attacks, which are a growing concern. Process level sandboxing is too coarse.
> No pinning virtual threads is huge. Finally you can virtual thread with near-wild abandon, as God intended.
I see that formerly it pinned virtual threads "when it executes code inside a synchronized block or method", and "frequent pinning for long durations can harm the scalability of an application by capturing carriers". You were supposed to "avoid frequent and long-lived pinning by revising synchronized blocks or methods that run frequently and guard potentially long I/O operations to use java.util.concurrent.locks.ReentrantLock instead."
How big a problem was this in practice? On the one hand, I think "harm the scalability" is putting it mildly—if you have a whole bunch of virtual threads doing IO, only running num_cores of them at once is devastating. On the other hand, holding a lock while doing IO smells wrong. Is this really common?
I think in practice it has to do with some libs (eg jdbc drivers) that would be relying on synchronized. If the performance with vthreads was much worse for some cases it would be a bit of failure
> I think in practice it has to do with some libs (eg jdbc drivers) that would be relying on synchronized.
Those usually have company / community backing that gets it fixed. The irony is you patch the ORM and you patch the JDBC driver only to realize the database pooling library in-between is the 1 that's broken and the author refuses to fix it.
It can deadlock and cause crashes if you do use a library impacted. It's sometimes hard to tell and you'd have to dig into the source. Sometimes the library maintainer wouldn't update the code to a different method for <reasons>.
> Is this really common?
Yes, maybe not in obvious ways e.g. many developers use Spring, which is backed by a large organization and you'd assume to have things covered but under the hood Spring itself uses many libraries and some often open source without much support (can be a personal project by a single developer).
I'm glad they're working on it but I still can't help but my miss async/await.
In C# the API is a bit overturned for sharing a GUI thread but it does the job. Structured Concurrency makes the scopes more obvious but I'm worried about the ergonomics. What is the core use case for the design? Is it just to make collecting a set of concurrent tasks bullet proof? Are we going to see scopes abused and passed around to handle the non-happy path of "a function always ends before it's caller."
It doesn't seem to service GUI programming all that well. I guess there's still Kotlin's approach but hopefully something happens on the Java side.
"Is it just to make collecting a set of concurrent tasks bullet proof?"
At a surface level, yeah basically. And ask anyone who's used python's multiprocessing how hard that is to actually get completely right.
I don't think structured concurrency is going to be some panacea of multiprocessing at all. It's to address code you'd see in golang that's like, make a waitgroup, fire off N goroutines, wait for success and gather errors. That code is not incredibly fun in Java right now.
w.r.t. async/await, imo the beauty of virtual threads is that you've no longer got function coloring, and the "await"s are free, implicit, and performant. and of course you're never precluded from using higher level application locks that have always been there, including synchronized now.
Also, specifically w.r.t. gui programming, I think Java is unfortunately kind of stuck. JavaFX has been put into the back of the closet, Swing is completely ossified (though tbh I still like it), and what energy is there behind any non-electron/web GUI development anymore anyway? In a world where vscode, one of the most popular new "IDEs"/IDE platforms, is written in a frickin web browser, and mobile apps dominate a huge % of what constitutes "native" GUI development, I don't really blame Java for not prioritizing it beyond keeping Swing working on e.g. hiDPI displays and so on.
> I really want structured concurrency out of preview!!
I'm guessing they thought it couldn't hurt to do another round of testing. Since OpenJDK 25 will be an LTS release, I suspect it will go out of preview in the next release.
ALL? no. but based on my read of the article's linked bit on thread pinning, it seems like it has been substantially resolved, and remaining pinning scenarios are quite rare (they mention you can look for them in JFR).
> Java streams is that they're as powerful as Ruby's functional-style operation chaining (arr.map{}.reduce(:+) etc)
This is not a unique Ruby feature though. Iterators are very common nowadays. Java streams have okay performance, much like .NET's LINQ you likely won't be able to use them in a really performance-sensitive code (although LINQ is improving quite a bit with each new release, overall it performs moderately to significantly faster than Java Streams, but usually slower than Rust iterators).
They are both free (Oracle relaxed their license in 2021) with some caveats. If you choose Oracle, to continue to be free, you must always use latest Java version, otherwise you need to pay for security patches. This means updating every 6 months with each Java release.
Unless you need Oracle's JDK specifically, use one of several certified OpenJDK distributions. Amazon Coretto is a popular choice and they already have a v24 version. There are a few others. Temurin (weird name but basically the eclipse.org one) doesn't yet have one but is popular.
At this point there is no/little functional difference between distributions. The main reasons for using Oracle's distribution are usually non-technical and have to do with compliance, existing license & support agreements with Oracle.
Unless you are a bank (or similar organization) that has deals with Oracle on this or your CIO/CTO/legal tells you to use Oracle, you should avoid Oracle. There is no technical advantage and you potentially expose yourself to complicated licensing and commercial requirements and related auditing requirements.
All OpenJDK distributions, from all vendors, are also licensed by Oracle (which develops OpenJDK) with the GPLv2+CPE licence. The vendors build Oracle's source code and host branded binaries. If you file an issue, unless it's a problem with the build, they just forward it to Oracle.
Oracle also distributes the JDK with that same licence here: https://jdk.java.net, so there are two Oracle distributions with two different licences, both free but one open-source.
Yes. Oracle version is not free anymore: you need at least an Oracle product to use it.
As far as I know, it is "free of charge" if you have an Oracle DB license.
So avoid oracle version outside enterprise contract
Surprised nobody mentioned JEP 491 [1] yet. Basically it ensures the "synchronized" keyword can no longer mess up virtual threads. That's a big win for running existing code in virtual threads.
Java’s version growth has been interesting to watch the past few years. I remember thinking “wow 9 is out, now 10, 11 is an LTS, we’ll go to that”. Still on Java 8. Too much other things to do.
It sure is weird seeing such high numbers. After pivoting away from java for a new job 4 years ago, I still get confused when people from 'old job' talk about how Java 24 is now here.
Kinda fun to think about that we'll have Java 30 before 2030 iirc.
How is Java these days compared to Kotlin, comparing latest versions of both? I know Java continues to improve and take features from Kotlin but Kotlin is also improving itself.
It is the Java Virtual Machine, not Kotlin Virtual Machine.
Thus Kotlin will always be a guest language and not the target of all companies designing JVM implementations.
That is left for Google with their .NET flavour, ART + Kotlin, where Android Java plays the same role as J# did for .NET, after Microsoft had let go of J++.
It's a perpetual discussion. Java enthusiasts will generally say there is no or only a small difference, while at the same time being excited about Java getting features that Kotlin has had years before (e.g. smart casting).
In general Java is getting better but more weighed down by legacy and existing design decisions than Kotlin, so a lot of improvements from Kotlin are not possible to be made in Java.
Java is running ahead of Kotlin in a few things, mainly virtual threads which don't require black-red functions like coroutines.
I find Java 21 very pleasant, as long as you figure out how to avoid ugly things like Spring’s autowiring of dependencies.
I haven’t really given kotlin a fair try, but I find it ugly the couple times I’ve tried to work with it.
What I’m really curious about: do IntelliJ’s refactorings work as well for kotlin as Java? I find the refactoring tools make up for Java’s shortcomings as a language.
Do things like inline method and inline base class work correctly? It’s not a given that IntelliJ is works correctly for Kotlin if the semantics of Kotlin are harder to analyze statically.
In my opinion the only critically missing feature in Java that Kotlin has are nullable types. It’s been proposed, but is stuck behind Valhalla.
Kotlin has a lot of other smaller features that help with conciseness. Like single line methods, but it’s still missing critical features like checked errors.
java is on a great trajectory now. it gets big updates. they know where they are missing on features. even without nullable types you have optional. it’s a great language for any project.
Optional is not good at all. It is not enforced by the compiler and optional itself can be null. In hot loops it can allocate like crazy. We need compiler support to enforce nullability and to get null into the type system.
What will be the implications of this? e.g. Can we now handle more req/sec on I/O blocking services, because more requests can be serviced by VTs and they will not be blocked waiting for IO, so kinda like Node.js async model (for free) but with multiple threads?
That was always possible and the whole point of virtual threads. This concerns reliability. So far there was this annoying papercut of virtual threads not freeing up their carrier thread when they were waiting to enter a `synchronized` lock. That could easily lead to reduced throughput or even deadlocks when all carrier threads got pinned.
Yeah, I mean now we can start using VTs on any system / lib without being worried of pinning. Isn't this a "huge" deal? Why is the community not shouting from the rooftops about this?
Theoretically it means, Java has now bettered Node.js "async / await" approach and that too without the two colored function approach. One process can now spawn thousands of threads to service IO and none of those threads are blocking / waiting (and with this release there is no gotcha / pitfall remaining).
Not mention all the Netty / reactive libraries have no use now (not that I am complaining).
Indeed, the relief is great. However, there are relatively few users of virtual threads yet. Even fewer are keeping up with the releases. Those using it in production already managed to work around the issues or have given up on it. We will hear more when Java 25 is released (which will be an Oracle LTS version) or if a backport to LTS 21 happens.
> My first experience with virtual threads was way less memory used.
understandable. Normal java threads have underlying OS threads, which have their own stack and memory overhead. virtual threads are much lighter in this sense.
JEP 484: Classfile API is going to be huge. It will take a while for full adoption, but finally being able abstract the backend of ByteBuddy/ASM/etc will be a gigantic boon. Being able to read/write classifies is one of the biggest hurdles at upgrade time.
- If you're using virtual threads you must have been pining (pun intended) for freeing up the carrier thread when a virtual thread waits for a `synchronized` lock.
- Stabilized FFI library
- Unnamed variables and patterns
- Always improvements to GCs and the runtime. Compact Object Headers v2 might be worthwhile on non-critical systems even though it's still experimental.
I stopped following java ecosystem closely around the time java 9 was released (last new thing I remember is the introduction of modules). How much has the language/bytecode/VM changed since then? What would be the best resources to catch up that won't take too much of my time?
SecurityManager dies not with a bang, but a whimper. The professor who taught a generally-misguided Java elective extolled the benefits of the security manager whenever he could. I was tremendously skeptical at the time. I'm inappropriately smug to have been proven right now, several decades later.
I really want structured concurrency out of preview!! I think it helps close one of the last gaps golang has over Java in the ease-of-concurrent-programming side of things. Go makes channels and waitgroups pretty easy. I think structured concurrency is a great side-step of those primitives by actually making the higher-level tasks you use those tools to accomplish easier to write and reason about. Continuing a trend I see where go tends to have somewhat better primitives, but then obstinately does nothing with them to actually make the higher-level tasks easier to accomplish.
No pinning virtual threads is huge. Finally you can virtual thread with near-wild abandon, as God intended.
Love seeing Streams still getting love. I do a lot of fizzbuzz-esque interviews (the "can you code your way out of a paper bag" type screens) for my company and I think it says a lot that, in general, people who pick Java and use streams pass but people who don't use streams often get tripped up in their loop logic and fail (or, even if they don't fail per se, don't pass). It says a lot about ergonomics and intuitiveness, and also the power of the abstraction to tersely and compactly solve real problems, when a language is a big ally in interviews. And the cool thing about Java streams is that they're as powerful as Ruby's functional-style operation chaining (arr.map{}.reduce(:+) etc) but they're actually performant. I feel it also bears mentioning that people who use Ruby in these interviews, few as they are, almost always pass and do so while writing very few LOC :)
Go is the poster child for not having structured concurrency, the article that started this movement was an explicit take down of go’s concurrency primitive “go func” being dangerous.
https://vorpus.org/blog/notes-on-structured-concurrency-or-g...
I think Kotlin still leads here, and even the Java changes don’t have the same nice ergonomics you get with Kotlin’s DSL. Would love to see more tenseness from Kotlin leak into Java.
Yet, like most Go design decisions, they will end up retrofiting what should have been there.
Kotlin has the issue of being a guest language, and wanting to play in many playgrounds, eventually it will diverge as it always happens.
As it is already happening, like now how will Kotlin async deal with virtual threads expectations, including writing portable code that doesn't suffer from runtime semantics, depending on the target platform.
Something better than making everyone take context as the first arg in every function? It’s go’s own brute force way of function coloring, except you have to write it yourself and drag this arbitrary bag of data through every function, what a horrible stapled-on mess.
> explicit take down of ... "go func"
I stopped at "go statements are a form of goto statement."
This is simply not correct. They have some diagrams and squinted and said "hey, that looks the same as a goto statement", but unfortunatley they have their diagrams wrong. "go func" will run at scheduler's pleasure, not immediately after the statement "go func..". A goto statement is a deterministic flow control directive. It will goto where you tell it.
you should have read the rest of it then, because in the context of Dijkstra's famous paper [0] (that this is written in the style of) the argument here is being able to understand program flow in the programmers' mind. Your description of the go func actually makes it WORSE, because the program doesn't just go there, it goes there later.
[0] https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.p...
That may be true, but regardless, it is most definitely nothing like a goto and it is misleading. & Yes I have read Dijkstra and as it happens have my own critical views regarding Go's goroutines (which are really inspired by CSP), but just don't appreciate misleading assertions. To wit, "flow" does not really make sense in context of concurrency. Flows, plural, sure ..
Well fair, but I do think you should give this article a read. It’s the genesis of kotlin’s coroutines, and other implementations of “structured concurrency” or nurseries as the author conceives of them.
Security Manager is one of the only unique selling points of Java, to remove it (without removing it because you need it underneath) is as big of a blunder as removing Applets from browsers and replacing it with something worse: WASM without GC and then adding GC to WASM...
If SVTwP is not better than NIO; Java ends with JDK 23.
> Warnings issued in JDK 17–23 generated minimal discussion in the Java ecosystem
Because no feature added after 1.8 made sense, so nobody upgraded. They are taking decisions off the wrong data.
> they are encouraged to transition to alternative sandboxing and API interception mechanisms
Feel free to link to anything useful!
Unique, sure. Selling point? I really don't think so. This idea of "safely" running untrusted code in the jvm sandbox both never materialized (constant stream of sandbox-escape vulns i've seen over the years) and also was at the wrong level - anyone doing multi-tenant code execution is doing it via things like gvisor or at the OS-level.
I don't think I buy your assertion that nobody has upgraded. I know of a 3000-4000-strong eng org at a certain company that has upgraded all the way from 8 to 17 as of when i left 3 years ago. They primarily wanted the GC improvements because they translated into huge immediate efficiency gains on their workloads (huge Spark/Hadoop spend savings, and moderate savings for the non-big-data jvm workloads).
I do share your lament of applets though. It would've been a way better runtime for portable/install-less/JIT-install things than the current nightmare of html/css/js/etc. But they just didn't have the browser integration - it would've needed to be more than just "look we put a drawing surface into the web browser" - and they didn't have the "window into the world" either (that's browsers). Unfortunately, it's the front door program and platform that owns the users, and that's web browsers.
Can you point to one vuln?
> I don't think I buy your assertion that nobody has upgraded.
Nobody that uses Security Manager has upgraded I meant.
Found this: https://www.reddit.com/r/java/comments/15ksmm2/javas_securit...
Nothing sticks out, except container companies are probably very happy?
I wonder if the guys working on this did a search before starting: https://github.com/search?type=code&q=AccessController.doPri... (187k files)
https://openjdk.org/jeps/486 goes into detail about the motivation for removing support for Security Manager.
I have read it but it does not make sense.
This work is destructive for no reason.
But I am curious how classloaders will work now!?
Huh, it is not no reason. You just do not like their reasons.
I disagree with them, all.
I also dislike the Win32 removal since JDK 22, but I understand that Windows 32-bit assembly is un-maintainable. There is a reason ARM keeps 32-bit.
The Security Manager was not so hard to maintain it merited a removal without replacement.
>The Security Manager was not so hard to maintain it merited a removal without replacement.
It sounds like the OpenJDK folk disagree with you, though. From the JEP:
>The Security Manager has not been the primary means of securing client-side Java code for many years, it has rarely been used to secure server-side code, and it is costly to maintain
>...Improve the maintainability of hundreds of JDK classes that currently delegate resource-access decisions to the Security Manager.
>The OpenJDK Core Libraries Group devotes significant time and energy to reviewing every change to any of these methods. Every new API must be designed, and its implementation carefully audited, with the least-privilege model in mind. However, only a tiny number of applications actually enable the Security Manager.
This seems like a big win in terms of maintainability of the core libraries.
The Security Manager was dead as soon as applets ceased to be relevant (which happened a long time before WASM appeared btw.). Deploying the Security Manager requires designing the application up front for it as well as maintaining policy files. Most developers are not aware how to do either.
But its biggest weakness is that it has to restrict a lot of overly powerful APIs. That's like spooning water with a sieve. It would have been better to let the host application restrict which APIs are visible in the first place, like it is done with browser APIs.
The projects that didn't upgrade so far are either dusty business-crirical applications that nobody cares to touch or that utterly deprioritize upgrades unless circumstances force them to. Most of the new features make a lot of sense, but nobody is going to gamble their job on forcing an upgrade just to being able to use them.
To suppress things like `System.exit(0)`, agents can be used. Proper sandboxing solutions would be VMs and containerization technologies. Achieving perfect sandboxing within a process is hopeless anyway.
With some work on better tooling it could've been used to detect and thwart supply chain attacks, which are a growing concern. Process level sandboxing is too coarse.
There are plenty of places that are at least on Java 11, so I highly doubt the "no one upgraded" part.
I meant to 17 so they would see the warning.
That has as much to do with Oracle lawyers and ambiguous licensing issues as anything else.
> No pinning virtual threads is huge. Finally you can virtual thread with near-wild abandon, as God intended.
I see that formerly it pinned virtual threads "when it executes code inside a synchronized block or method", and "frequent pinning for long durations can harm the scalability of an application by capturing carriers". You were supposed to "avoid frequent and long-lived pinning by revising synchronized blocks or methods that run frequently and guard potentially long I/O operations to use java.util.concurrent.locks.ReentrantLock instead."
How big a problem was this in practice? On the one hand, I think "harm the scalability" is putting it mildly—if you have a whole bunch of virtual threads doing IO, only running num_cores of them at once is devastating. On the other hand, holding a lock while doing IO smells wrong. Is this really common?
I think in practice it has to do with some libs (eg jdbc drivers) that would be relying on synchronized. If the performance with vthreads was much worse for some cases it would be a bit of failure
> I think in practice it has to do with some libs (eg jdbc drivers) that would be relying on synchronized.
Those usually have company / community backing that gets it fixed. The irony is you patch the ORM and you patch the JDBC driver only to realize the database pooling library in-between is the 1 that's broken and the author refuses to fix it.
> How big a problem was this in practice?
It can deadlock and cause crashes if you do use a library impacted. It's sometimes hard to tell and you'd have to dig into the source. Sometimes the library maintainer wouldn't update the code to a different method for <reasons>.
> Is this really common?
Yes, maybe not in obvious ways e.g. many developers use Spring, which is backed by a large organization and you'd assume to have things covered but under the hood Spring itself uses many libraries and some often open source without much support (can be a personal project by a single developer).
I'm glad they're working on it but I still can't help but my miss async/await.
In C# the API is a bit overturned for sharing a GUI thread but it does the job. Structured Concurrency makes the scopes more obvious but I'm worried about the ergonomics. What is the core use case for the design? Is it just to make collecting a set of concurrent tasks bullet proof? Are we going to see scopes abused and passed around to handle the non-happy path of "a function always ends before it's caller."
It doesn't seem to service GUI programming all that well. I guess there's still Kotlin's approach but hopefully something happens on the Java side.
"Is it just to make collecting a set of concurrent tasks bullet proof?"
At a surface level, yeah basically. And ask anyone who's used python's multiprocessing how hard that is to actually get completely right.
I don't think structured concurrency is going to be some panacea of multiprocessing at all. It's to address code you'd see in golang that's like, make a waitgroup, fire off N goroutines, wait for success and gather errors. That code is not incredibly fun in Java right now.
w.r.t. async/await, imo the beauty of virtual threads is that you've no longer got function coloring, and the "await"s are free, implicit, and performant. and of course you're never precluded from using higher level application locks that have always been there, including synchronized now.
Also, specifically w.r.t. gui programming, I think Java is unfortunately kind of stuck. JavaFX has been put into the back of the closet, Swing is completely ossified (though tbh I still like it), and what energy is there behind any non-electron/web GUI development anymore anyway? In a world where vscode, one of the most popular new "IDEs"/IDE platforms, is written in a frickin web browser, and mobile apps dominate a huge % of what constitutes "native" GUI development, I don't really blame Java for not prioritizing it beyond keeping Swing working on e.g. hiDPI displays and so on.
> I really want structured concurrency out of preview!!
I'm guessing they thought it couldn't hurt to do another round of testing. Since OpenJDK 25 will be an LTS release, I suspect it will go out of preview in the next release.
.NET also removed their version of security manager (Code Access Security) for similar reasons.
Just like I expect WebAssembly security conversation to change when folks start plugging components left and right, beyond straight compute logic.
> I'm inappropriately smug to have been proven right now, several decades later.
I think you were proven right at least a decade ago. As you said, this is just the final whimper.
> No pinning virtual threads is huge
Have ALL previous pinning scenarios been resolved, including native calls?
ALL? no. but based on my read of the article's linked bit on thread pinning, it seems like it has been substantially resolved, and remaining pinning scenarios are quite rare (they mention you can look for them in JFR).
> Java streams is that they're as powerful as Ruby's functional-style operation chaining (arr.map{}.reduce(:+) etc)
This is not a unique Ruby feature though. Iterators are very common nowadays. Java streams have okay performance, much like .NET's LINQ you likely won't be able to use them in a really performance-sensitive code (although LINQ is improving quite a bit with each new release, overall it performs moderately to significantly faster than Java Streams, but usually slower than Rust iterators).
New features: https://openjdk.org/projects/jdk/24/
For ARM32 and Risc-V releases they should appear in the coming days here: https://bell-sw.com/pages/downloads
Raspberry 2 and Vision Five 2 are very future proof peices of hardware that Oracle and OpenJDK ignores!
Dumb question, but what are the licensing implications between using an OpenJDK vs the official Oracle Release of the JDK?
They are both free (Oracle relaxed their license in 2021) with some caveats. If you choose Oracle, to continue to be free, you must always use latest Java version, otherwise you need to pay for security patches. This means updating every 6 months with each Java release.
Unless you need Oracle's JDK specifically, use one of several certified OpenJDK distributions. Amazon Coretto is a popular choice and they already have a v24 version. There are a few others. Temurin (weird name but basically the eclipse.org one) doesn't yet have one but is popular.
At this point there is no/little functional difference between distributions. The main reasons for using Oracle's distribution are usually non-technical and have to do with compliance, existing license & support agreements with Oracle.
Unless you are a bank (or similar organization) that has deals with Oracle on this or your CIO/CTO/legal tells you to use Oracle, you should avoid Oracle. There is no technical advantage and you potentially expose yourself to complicated licensing and commercial requirements and related auditing requirements.
All OpenJDK distributions, from all vendors, are also licensed by Oracle (which develops OpenJDK) with the GPLv2+CPE licence. The vendors build Oracle's source code and host branded binaries. If you file an issue, unless it's a problem with the build, they just forward it to Oracle.
Oracle also distributes the JDK with that same licence here: https://jdk.java.net, so there are two Oracle distributions with two different licences, both free but one open-source.
Forgive me if I answer with a counter-question, but why would you use the Oracle distribution without paying for Oracle support too?
Because it’s what came up when you googled “install java on aws”.
Yes. Oracle version is not free anymore: you need at least an Oracle product to use it. As far as I know, it is "free of charge" if you have an Oracle DB license. So avoid oracle version outside enterprise contract
It's free. But you must always use latest Java.
Surprised nobody mentioned JEP 491 [1] yet. Basically it ensures the "synchronized" keyword can no longer mess up virtual threads. That's a big win for running existing code in virtual threads.
[1] https://openjdk.org/jeps/491
Java’s version growth has been interesting to watch the past few years. I remember thinking “wow 9 is out, now 10, 11 is an LTS, we’ll go to that”. Still on Java 8. Too much other things to do.
It sure is weird seeing such high numbers. After pivoting away from java for a new job 4 years ago, I still get confused when people from 'old job' talk about how Java 24 is now here. Kinda fun to think about that we'll have Java 30 before 2030 iirc.
You could potentially save money by upgrading, but likely 8 will continue to work fine for a long time. That's java for you.
> Still on Java 8. Too much other things to do.
Understandable. Depending on your use-case, sure go ahead and stay there.
However keep in mind that you're missing out on a lot of stuff. Java 8 is like literally from 11 years ago.
nice discussion, fwiw i added a structured summary here https://extraakt.com/extraakts/java-24-discussion-features-v...
How is Java these days compared to Kotlin, comparing latest versions of both? I know Java continues to improve and take features from Kotlin but Kotlin is also improving itself.
It is the Java Virtual Machine, not Kotlin Virtual Machine.
Thus Kotlin will always be a guest language and not the target of all companies designing JVM implementations.
That is left for Google with their .NET flavour, ART + Kotlin, where Android Java plays the same role as J# did for .NET, after Microsoft had let go of J++.
> Thus Kotlin will always be a guest language
If you a writing libraries for the JVM, Java is preferred to Kotlin because it does not drag along a standard library dependency.
To be fair there is Kotlin Multiplatform where this is not the case. https://kotlinlang.org/docs/multiplatform.html
Yes, and it has the issue of having its own way of #ifdef, because not all platforms offer the same semantics.
It is no different than writing C code across UNIX, Windows, mainframe, microcomputers and embedded, consoles, and somehow work across all of them.
I write server-side Kotlin at $DAYJOB, for several years.
Kotlin used to be a marked improvement over Java.
A series of large language changes, starting with JDK 16, have leveled the playing field somewhat.
Nowadays Java has Record types (data classes), sealed interfaces, pattern matching, etc.
Java's pattern matching actually got the ability to use guard clauses in match expressions BEFORE Kotlin implemented it:
https://kotlinlang.org/docs/whatsnew21.html#guard-conditions...
If Java had the ability to write free-floating functions outside of classes, and to declare function types succinctly like:
It'd probably be on-par with Kotlin for me.Check out Manifold project. It might not be for you since it's a bit of an aftermarket hack. But it's open source and has some crazy innovative ideas.
It's a perpetual discussion. Java enthusiasts will generally say there is no or only a small difference, while at the same time being excited about Java getting features that Kotlin has had years before (e.g. smart casting).
In general Java is getting better but more weighed down by legacy and existing design decisions than Kotlin, so a lot of improvements from Kotlin are not possible to be made in Java.
Java is running ahead of Kotlin in a few things, mainly virtual threads which don't require black-red functions like coroutines.
I find Java 21 very pleasant, as long as you figure out how to avoid ugly things like Spring’s autowiring of dependencies.
I haven’t really given kotlin a fair try, but I find it ugly the couple times I’ve tried to work with it.
What I’m really curious about: do IntelliJ’s refactorings work as well for kotlin as Java? I find the refactoring tools make up for Java’s shortcomings as a language.
> avoid ugly things like Spring's autowiring of dependencies.
This seems awfully close to "avoid Spring" to me, heh.
Though, I've grown rather fond of Spring Boot over time, but I've gathered that's not exactly the popular consensus.
> This seems awfully close to "avoid Spring" to me, heh.
Exactly :)
IntelliJ is excellent for Kotlin, on par or better than for Java. It's unsurprising as Jetbrains basically uses Kotlin to sell IntelliJ.
Do things like inline method and inline base class work correctly? It’s not a given that IntelliJ is works correctly for Kotlin if the semantics of Kotlin are harder to analyze statically.
In my opinion the only critically missing feature in Java that Kotlin has are nullable types. It’s been proposed, but is stuck behind Valhalla.
Kotlin has a lot of other smaller features that help with conciseness. Like single line methods, but it’s still missing critical features like checked errors.
Pick your poison.
> It’s been proposed, but is stuck behind Valhalla.
It is actually a central part of Valhalla now [1].
[1] https://openjdk.org/projects/valhalla/
Yes that qualifies as "stuck behind valhalla" for me. Valhalla... truly is Valhalla. Will we ever see it?
java is on a great trajectory now. it gets big updates. they know where they are missing on features. even without nullable types you have optional. it’s a great language for any project.
Optional is not good at all. It is not enforced by the compiler and optional itself can be null. In hot loops it can allocate like crazy. We need compiler support to enforce nullability and to get null into the type system.
I wouldn't really use either, unless Scala was not viable. Both feel like watered down versions of what I can do in Scala, which has little downside
Already installed, GraalVM is also available for Java 24.
Lots of goodies.
Finally no pinning for virtual threads!
Yes!
I will compare my NIO multiplayer system to SVTwP (Sync. Virt. Threads without Pinning) and report back!
Looking forward to hearing about it.
What will be the implications of this? e.g. Can we now handle more req/sec on I/O blocking services, because more requests can be serviced by VTs and they will not be blocked waiting for IO, so kinda like Node.js async model (for free) but with multiple threads?
That was always possible and the whole point of virtual threads. This concerns reliability. So far there was this annoying papercut of virtual threads not freeing up their carrier thread when they were waiting to enter a `synchronized` lock. That could easily lead to reduced throughput or even deadlocks when all carrier threads got pinned.
Yeah, I mean now we can start using VTs on any system / lib without being worried of pinning. Isn't this a "huge" deal? Why is the community not shouting from the rooftops about this?
Theoretically it means, Java has now bettered Node.js "async / await" approach and that too without the two colored function approach. One process can now spawn thousands of threads to service IO and none of those threads are blocking / waiting (and with this release there is no gotcha / pitfall remaining).
Not mention all the Netty / reactive libraries have no use now (not that I am complaining).
Indeed, the relief is great. However, there are relatively few users of virtual threads yet. Even fewer are keeping up with the releases. Those using it in production already managed to work around the issues or have given up on it. We will hear more when Java 25 is released (which will be an Oracle LTS version) or if a backport to LTS 21 happens.
As someone coming from Node.js: virtual threads are amazing. Async behaviour without the async/await headaches.
You can now safely use virtual threads to run code that uses "synchronized".
My first experience with virtual threads was way less memory used.
> My first experience with virtual threads was way less memory used.
understandable. Normal java threads have underlying OS threads, which have their own stack and memory overhead. virtual threads are much lighter in this sense.
JEP 484: Classfile API is going to be huge. It will take a while for full adoption, but finally being able abstract the backend of ByteBuddy/ASM/etc will be a gigantic boon. Being able to read/write classifies is one of the biggest hurdles at upgrade time.
Java 24 already? What’s the standout feature this time—anything that makes it worth upgrading from 21? Always cool to see how it keeps evolving.
My favorite is the stream gatherers, an addition to the stream processing API that will let streams do things like sliding windows.
https://docs.oracle.com/en/java/javase/22/core/stream-gather...
Ahead Of Time (AOT) linking is nice as well, should cut down cold start time.
Are record patterns stable yet?
Java releases are timeboxed, so they don't need standout features.
Ooh, looks like they sync up with years going forward. That's... actually really quite nice.
https://www.java.com/releases/matrix/
It's just a coincidence. There are two releases per year. JDK 27 will be released in September 2026.
Not for long. JDK 27 is coming out in September 2026
that would actually be cool and useful.
the development team could either lengthen or shorten a couple of development cycles to stay in sync with the years.
- If you're using virtual threads you must have been pining (pun intended) for freeing up the carrier thread when a virtual thread waits for a `synchronized` lock.
- Stabilized FFI library
- Unnamed variables and patterns
- Always improvements to GCs and the runtime. Compact Object Headers v2 might be worthwhile on non-critical systems even though it's still experimental.
I stopped following java ecosystem closely around the time java 9 was released (last new thing I remember is the introduction of modules). How much has the language/bytecode/VM changed since then? What would be the best resources to catch up that won't take too much of my time?