There seems to be an emerging consensus that we should skip 11 and go straight to 17.
Some have suggested staying on 8 but enabling additional features based on target version — as we already do for certain features. I want to be clear that that isn’t happening; we are not going that route. The cost of continuing to support 8 ecosystem-wide, relative to the benefit, is too high. This isn’t only about the compiler; it’s also about the standard library, the library ecosystem, and the tooling ecosystem.
The suggestion that we ought to go straight to 21 — that also isn’t happening. Not in this round — we can revisit the question for the following LTS. 21 is too new, its adoption numbers are too low. (Regardless, perhaps there are 21+ features we could support when compiling on 21+ for 21+.)
I second Eugene’s remarks. This change in Scala 3 won’t help most tooling in the short term, but in the long term, it will. To get that long term benefit, we should start the process now.
So, the fact that scalac emits bytecode that is compatible with Java 8 does hold you (and your users) back from using some future Java version.
And it’s not just about maintenance cost: this strategy actually is no longer viable. Continuing to emit bytecode that supports Java 8 means choosing not to support newer Java versions.
I’m not arguing one way or the other, but I don’t think Unsafe will ever go away. Java is excelent because with very few exceptions you can take Java 1.0 binaries and run them on the latest JVM and the ecosystem’s dependence on Unsafe is so high that banning it is impossible.
The Java ecosystem isn’t like Scala’s ecosystem. It has public libraries that haven’t received updates in years but that people still use, in addition to project binaries that are no longer updated. This is also why runtime reflection, method overloads or bytecode manipulation plays such a big role in the ecosystem.
Unsure what the Java 25 schedule is, but the death of Unsafe is highly exagerated. At best they’ll put it behind a JVM flag, but I wouldn’t be so sure, as even that will break existing deployments.
I think it all boils down to what the compiler team has the capacity to maintain. I’d like Java 17 if that’s the only way to get interop with Java 17 features. I’d prefer it if this was optional though. I know that in the ecosystem Scala moves fast and breaks things, but maybe we all should strive for more compatibility instead of less, this having the potential to upset people again.
That was the point I also wanted to make. I wasn’t arguing for staying on 8, and I’m personally fine with going straight to 17, even though I do have a (java) case at work that is actually stuck on 11 for the time being for more than just corporate or administrative reasons. I was arguing against going even further and for being a little conservative about dropping Java compatibility since Scala itself is already moving at a crazy pace.
I mean, yes, Scala should provide an alternative or a complete replacement to the use of Unsafe, it’s definitely not wise to remain on it as the sole choice. And I’m aware that the JVM starts warning people that Unsafe is used.
But I’m willing to bet that Unsafe will not go away in Java 26 or even Java 30 for that matter. I’m even willing to bet that even after the advent of true AI that will be able to replace all software developers, it will still use Unsafe-driven libraries, while ignoring all warnings
There were questions about this on Discord, from people who just wanted to understand the reasons for this better — what the context is. If you want to read the ensuing discussion, it starts here: Discord . (Sorry, I know not everyone has Discord access, at work anyway.)
(Regardless, we’d like to keep this thread focused on the 11 vs 17 decision.)
That sounds like one of the reasons why kotlin evolution is so slow, they recently launched kotlin 2.0 and there was no single new language feature, but was all about fixing their compiler mess and bytecode issues, also android only supports a subset of Java 8 apis, scala is free from that limitation
It is a bit of a shame to be defeatist on this one. If we had taken the time when 2.12 came about to implement a -release flag for JDK7, then Scala would probably still be in the race for Android. Note that with d8 today most of Scala code is able to run on Android, except for e.g. specialized lambdas which still need workarounds. So please do not break that and provide JDK8 output even if migrating to a more recent version.
Android development it’s not stuck on JDK 8, only the Android Runtime Api support
The JDK (11, 17) can be used for android development tools, like android studio/gradle
The API or JRE features in Android are limited to a subset of JDK 8 natively and by desugaring a subset of JDK 11 even if you are using a newer JDK to compile the project
In any case for anyone developing scala on android/ios would be best to use Gluon which uses a real JVM on mobile enabled by GraalVM and supports everything from Java 11+
Keeping the compatibility with Android that we already have (or even improving it) would certainly be nice
But maybe that doesn’t require sticking with Java 8 bytecode. Doesn’t the desugaring work also on Java 17 bytecode?
From what you’re saying, it seems like the problem isn’t the Java version of the bytecode. But something else, like using classes which are unavailable or is it something else?
It has to do with the way Scala translates lambdas to invokedynamic calls. If the lambda is on specialized types (that is, primitives) then there is a cast error at runtime. I could workaround it by substituting reference types. If there is interest I can try to set up a reproducer.