Next Scala 3 LTS version will increase minimum required JDK version

New Relic has some usage numbers at https://newrelic.com/sites/default/files/2024-04/new-relic-state-of-the-java-ecosystem-report-2024-04-30.pdf

The numbers are a year old, but it shows 8 at 28.8%, 11 at 32.9%, and 17 at 35.4%. And the 8 and 11 numbers are dropping sharply every year.

Perhaps they’ll publish 2025 numbers soon.

1 Like

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+.)

7 Likes

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.

2 Likes

Actually, taking the case of lazy vals, this is no longer correct. Code compiled targeting Java 8 uses Unsafe to performantly implement lazy vals, but the Unsafe API will be removed in a future Java version.

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.

7 Likes

Yes, thanks for the clarification.

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.

2 Likes

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 don’t think Unsafe will ever go away

the death of Unsafe is highly exagerated

I don’t think these predictions make any sense considering what the JDK team is communicating, and what’s going on in the JDK development repo.

See JEP 498: Warn upon Use of Memory-Access Methods in sun.misc.Unsafe and JEP draft: Integrity by Default. Unsafe will warn on access as soon as Java 24, and may become unusable as early as 26, a year from now.

I think it would be a mistake for Scala to hope that Unsafe is sticking around, and that the JDK team are just overstating their plans.

At best they’ll put it behind a JVM flag, but I wouldn’t be so sure, as even that will break existing deployments.

They did exactly this with reflective access to JDK internals in JEP 403: Strongly Encapsulate JDK Internals, and are planning to do this for native access (JNI) as well.

3 Likes

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 :slight_smile:

Scala should provide an alternative or a complete replacement to the use of Unsafe

While I think your bet isn’t likely to pan out, as long as we agree on this, the rest doesn’t really matter :slight_smile:

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.

2 Likes

I think this should also be put in context of the fact that as of August 31st, 2024:

For new apps and any app updates, app developers must target Android 14 (API level 34) or higher to be accepted by Google Play

(from https://median.co/blog/google-plays-target-api-level-requirement-for-android-apps)

And Android 14 (API 34) supports JDK 17.

4 Likes

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+

Better target Java 21, because no one will use Java 17 in the next years.
At alibaba, most of us just jump from Java 8 to Java 21.

3 Likes

visit javaalmanac.io to see API changes and Java 25 the next LTS will be released in September 2025.

Keeping the compatibility with Android that we already have (or even improving it) would certainly be nice :+1:

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.

2 Likes

Please do. And link the bug here then :pray: