RFC: sbt 2.0 on JDK 17

Hello,

On behalf of the sbt project, I would like to solicit your feedback on the minimum JDK version required for sbt 2.0.

sbt 1.x has existed for nine years, which continues to support JDK 8, 11, 17, and 25. For sbt 2.x, we are considering to update the minimum JDK version to be JDK 17, in coordination with the post-3.8 Scala 3.x ecosystem.

_ JDK 17 Min JDK 8 Min
Scala 3.8+ in metabuild :white_check_mark: :cross_mark:
JDK 26 (requires Scala 3.8+) :white_check_mark: :cross_mark:
JDK 8 library publishing :warning: (--release 8) :white_check_mark:
Plugin cross building :warning: (--release 8) :white_check_mark:

Note: --release 8 flag tells the Scala compiler to emit bytecode that is compatible with JDK 8.

Thus far the 2.0 RC series and the 2.x plugins have been published with JDK 8, but if we were to make the jump, it would be better to take the leap now rather than later. Regardless of this decision:

  1. we plan to keep sbt 1.x under minimum maintenance for a while to address security vulnerabilities etc.
  2. we will likely drop JDK 8 / 11 support at some point in the future, if not at 2.0, then 2.1 or later.

Thanks!

13 Likes

My vote goes to min JDK 17. Thanks Eugene for all your efforts with SBT, we wouldn’t have got this far without you.

5 Likes

For perspective, I see this as part of a broader shift happening in the JVM world where Java 8 and 11 are finally dying and 17+ is the new normal now. We already published a pretty long list of prominent JVM-based projects that have dropped support for 8 and/or 11 at Next Scala 3 LTS series will increase minimum required JDK version | The Scala Programming Language (Spring, Hibernate, Jetty, Spark 4…). In short, this is the new world: move to JDK 17+ or resign yourself to using old software indefinitely.

we plan to keep sbt 1.x under minimum maintenance for a while to address security vulnerabilities etc

That’s very good, because it means that anyone who has already a working sbt 1 build on JDK 8 or 11 will be free to simply keep using sbt 1, leaving sbt 2 free to make this jump forward.

And now I’d like to make my main argument for making this change now:

sbt 2’s lifecycle is likely to be very, very long — a decade or so, perhaps. (Consider how long sbt 1’s lifecycle was!)

And very importantly, Scala 3.7 lazy vals don’t work on JDK 26+. So in order to support JDK 26+, sbt needs to be on Scala 3.8+ (preferably 3.9 LTS), which forces dropping 8 and 11.

sbt 2 is already a “burn the forest” upgrade, meaning that the entire plugin ecosystem needs to ported and re-published and everyone needs to port their build definitions, too.

Keeping JDK 8/11 support for that entire lifecycle could be quite limiting.

And if we don’t drop 8 and 11 now, dropping them later would result in an unnecessary second (smaller, but still significant) forest fire where in order to support JDK 26+, the entire plugin ecosystem will need to be re-published a second time.

A single forest fire, burn once and be done, seems strongly preferable to me.

This isn’t only about the labor required for plugin authors. (Authors who, as always in F/OSS, are prone to going AWOL, creating ecosystem-wide delays and confusion.)

It’s also just about setting clear expectations for users. If we drop 8 and 11 now, in the initial sbt 2 release, we move all at once to a new state that is clear and easy for everyone to understand. Either a plugin is available for sbt 2 or it isn’t, and if it is available, it will continue to work on all supported JDKs for the entire sbt 2 lifecycle. Whereas if we have this second fire later, we will be creating a more complicated and confusing situation for everyone.

14 Likes

On a related note, it is my understanding that the current consensus of the community is that mature libraries should stick to the current LTS version of Scala 3: Long-term compatibility plans for Scala 3 | The Scala Programming Language
Personally, if I see a library using a non-LTS version, I would be wary of using it.

Based on that, while sbt is much more than just a library, it very much should behave like one in this regard IMHO. My current expectation would be that sbt 2 would be based on Scala 3.9 LTS, and remain there until the next LTS release.
Which, in turn, would imply the drop of Java 8.

7 Likes

I think you should go ahead, now’s the moment for breaking changes.

4 Likes

Just drop Java 8; otherwise, you cannot use anything from Java 17

3 Likes

I don’t see a problem with requiring JDK 17 at this point – it was released 2021 and it’s several LTS version behind current.

4 Likes

Go big! Go for JDK 17.

3 Likes

From down in the trenches: I have some legacy projects still on JVM 8, but at this point there’s no especially good reason for that. The upgrade would be a mild nuisance (a whole pile of internal libraries that ought to be upgraded along the way), but it has to be done sooner or later, so I wouldn’t mind having the forcing function.

2 Likes

Does these include sbt plugins? If not, then these would not really be affected. The migration would include only updating JDK used in CI/dev setup and adding --release:8 to continue targeting JDK 8.

Personally I’m all in favor for dropping JDK 8, and aligning for JDK 17 for the core of Scala tooling ecosystem. Metals already uses 17, now scala compiler, along with it’s runner (scala-cli which AFAIK required multiple hacks too support JDK 8)

2 Likes

Yeah, a bunch of them – we have a deep stack.

Personally I’d probably bump that to min JDK 21, but I doubt many would be of the same line of thinking :slight_smile:

So, yes, min JDK 17 seems reasonable at this point.

3 Likes

Once you’re breaking plugins it seems OK to move to the latest LTS. That’s JDK25.

Would that leave a significantly larger crater?

1 Like

Go for it!