Remove java8 home and scala steward pins related to java 11 and java 17 (#1968)

* remove use of java8 home

* scala deprecations

* upgrade paradox

* getId is deprecated

* remove targetSystemJdk build option

* Update JdkOptions.scala
This commit is contained in:
PJ Fanning 2025-07-30 13:34:30 +01:00 committed by GitHub
parent 1b9c197fd7
commit f23107fc43
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 40 additions and 138 deletions

View file

@ -1,17 +1,6 @@
updates.pin = [
# Pin logback to v1.3.x because v1.4.x needs JDK11
{ groupId = "ch.qos.logback", version="1.3." }
# Pin sbt-paradox to v0.9.x because 0.10.x needs JDK 11
{ groupId = "com.lightbend.paradox", artifactId = "sbt-paradox-project-info", version = "0.9." }
{ groupId = "com.lightbend.paradox", artifactId = "sbt-paradox", version = "0.9." }
# Scala 3.3 is the latest LTS version
{ groupId = "org.scala-lang", artifactId = "scala3-library", version = "3.3." }
# aeron 1.46 requires Java 17
{ groupId = "io.aeron", version = "1.45." }
# agrona 1.23 requires Java 17
{ groupId = "org.agrona", artifactId = "agrona", version = "1.22." }
# bndlib 7 requires Java 17
{ groupId = "biz.aQute.bnd", artifactId = "biz.aQute.bndlib", version = "6." }
]
updates.ignore = [

View file

@ -13,6 +13,7 @@
package org.apache.pekko.actor.typed.internal
import scala.annotation.nowarn
import scala.util.control.NonFatal
import org.apache.pekko
@ -26,6 +27,7 @@ import pekko.util.OptionVal
private[pekko] object LoggerClass {
// just to get access to the class context
@nowarn("msg=deprecated")
private final class TrickySecurityManager extends SecurityManager {
def getClassStack: Array[Class[_]] = getClassContext
}

View file

@ -14,6 +14,7 @@
package org.apache.pekko.util
import java.util.concurrent.TimeUnit
import scala.annotation.nowarn
import org.openjdk.jmh.annotations.{ Benchmark, Measurement, Scope, State }
@ -21,6 +22,7 @@ import org.openjdk.jmh.annotations.{ Benchmark, Measurement, Scope, State }
@Measurement(timeUnit = TimeUnit.MICROSECONDS)
class StackBench {
@nowarn("msg=deprecated")
class CustomSecurtyManager extends SecurityManager {
def getTrace: Array[Class[_]] =
getClassContext

View file

@ -140,10 +140,9 @@ object UnidocRoot extends AutoPlugin {
lazy val pekkoSettings = UnidocRoot.CliOptions.genjavadocEnabled
.ifTrue(Seq(
JavaUnidoc / unidoc / javacOptions := {
if (JdkOptions.isJdk8) Seq("-Xdoclint:none")
else Seq("-Xdoclint:none", "--ignore-source-errors", "--no-module-directories")
}))
JavaUnidoc / unidoc / javacOptions :=
Seq("-Xdoclint:none", "--ignore-source-errors", "--no-module-directories")
))
.getOrElse(Nil)
override lazy val projectSettings = {
@ -214,8 +213,6 @@ object BootstrapGenjavadoc extends AutoPlugin {
override lazy val requires =
UnidocRoot.CliOptions.genjavadocEnabled
.ifTrue {
// require 11, fail fast for 8, 9, 10
require(JdkOptions.isJdk11orHigher, "Javadoc generation requires at least jdk 11")
sbtunidoc.GenJavadocPlugin
}
.getOrElse(plugins.JvmPlugin)

View file

@ -15,14 +15,11 @@ import sbt.Keys._
import sbt._
object Jdk9 extends AutoPlugin {
import JdkOptions.notOnJdk8
import JdkOptions.JavaVersion._
// The version 9 is special for any Java versions >= 9
// and the version 11 is special for any Java versions >= 11
// and the version 17 is special for any Java versions >= 17
// The version 17 is special for any Java versions >= 17
// and the version 21 is special for any Java versions >= 21
private val supportedJavaLTSVersions = List("9", "11", "17", "21")
private val supportedJavaLTSVersions = List("17", "21")
lazy val CompileJdk9 = config("CompileJdk9").extend(Compile)
@ -59,15 +56,15 @@ object Jdk9 extends AutoPlugin {
lazy val compileJdk9Settings = Seq(
// following the scala-2.12, scala-sbt-1.0, ... convention
unmanagedSourceDirectories := notOnJdk8(additionalSourceDirectories.value),
scalacOptions := PekkoBuild.DefaultScalacOptions.value ++ notOnJdk8(Seq("-release", majorVersion.toString)),
javacOptions := PekkoBuild.DefaultJavacOptions ++ notOnJdk8(Seq("--release", majorVersion.toString)))
unmanagedSourceDirectories := additionalSourceDirectories.value,
scalacOptions := PekkoBuild.DefaultScalacOptions.value ++ Seq("-release", majorVersion.toString),
javacOptions := PekkoBuild.DefaultJavacOptions ++ Seq("--release", majorVersion.toString))
lazy val testJdk9Settings = Seq(
// following the scala-2.12, scala-sbt-1.0, ... convention
unmanagedSourceDirectories := notOnJdk8(additionalTestSourceDirectories.value),
scalacOptions := PekkoBuild.DefaultScalacOptions.value ++ notOnJdk8(Seq("-release", majorVersion.toString)),
javacOptions := PekkoBuild.DefaultJavacOptions ++ notOnJdk8(Seq("--release", majorVersion.toString)),
unmanagedSourceDirectories := additionalTestSourceDirectories.value,
scalacOptions := PekkoBuild.DefaultScalacOptions.value ++ Seq("-release", majorVersion.toString),
javacOptions := PekkoBuild.DefaultJavacOptions ++ Seq("--release", majorVersion.toString),
compile := compile.dependsOn(CompileJdk9 / compile).value,
classpathConfiguration := TestJdk9,
externalDependencyClasspath := (Test / externalDependencyClasspath).value)
@ -80,7 +77,7 @@ object Jdk9 extends AutoPlugin {
// Since sbt-osgi upgrade to 0.9.5, the fullClasspath is no longer used on packaging when use sbt-osgi, so we have to
// add jdk9 products to dependencyClasspathAsJars instead.
// Compile / fullClasspath ++= (CompileJdk9 / exportedProducts).value)
Compile / dependencyClasspathAsJars ++= notOnJdk8((CompileJdk9 / exportedProducts).value))
Compile / dependencyClasspathAsJars ++= (CompileJdk9 / exportedProducts).value)
lazy val testSettings = Seq((Test / test) := {
(Test / test).value

View file

@ -18,90 +18,24 @@ import sbt.librarymanagement.SemanticSelector
import sbt.librarymanagement.VersionNumber
object JdkOptions extends AutoPlugin {
object autoImport {
lazy val jdk8home = settingKey[String]("JDK 8 home. Only needs to be set when it cannot be auto-detected by sbt")
lazy val targetSystemJdk = settingKey[Boolean](
"Target the system JDK instead of building against JDK 8. When this is enabled resulting artifacts may not work on JDK 8!")
}
import autoImport._
lazy val specificationVersion: String = sys.props("java.specification.version")
object JavaVersion {
val majorVersion: Int = {
// FIXME replace with Runtime.version() when we no longer support Java 8
// See Oracle section 1.5.3 at:
// https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html
val version = specificationVersion.split('.')
val majorString =
if (version(0) == "1") version(1) // Java 8 will be 1.8
else version(0) // later will be 9, 10, 11 etc
majorString.toInt
}
val majorVersion: Int = java.lang.Runtime.version().feature()
}
lazy val isJdk8: Boolean =
VersionNumber(specificationVersion).matchesSemVer(SemanticSelector(s"=1.8"))
lazy val isJdk11orHigher: Boolean =
VersionNumber(specificationVersion).matchesSemVer(SemanticSelector(">=11"))
lazy val isJdk17orHigher: Boolean =
VersionNumber(specificationVersion).matchesSemVer(SemanticSelector(">=17"))
lazy val versionSpecificJavaOptions =
if (isJdk17orHigher) {
// for virtual threads
"--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED" ::
"--add-opens=java.base/java.lang=ALL-UNNAMED" ::
// for aeron
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED" ::
// for LevelDB
"--add-opens=java.base/java.nio=ALL-UNNAMED" :: Nil
} else Nil
// for virtual threads
"--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED" ::
"--add-opens=java.base/java.lang=ALL-UNNAMED" ::
// for aeron
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED" ::
// for LevelDB
"--add-opens=java.base/java.nio=ALL-UNNAMED" :: Nil
def notOnJdk8[T](values: Seq[T]): Seq[T] = if (isJdk8) Seq.empty[T] else values
def targetJdkScalacOptions(scalaVersion: String): Seq[String] =
Seq(if (scalaVersion.startsWith("3.")) "-Xtarget:17" else "release:17")
def targetJdkScalacOptions(
targetSystemJdk: Boolean,
jdk8home: Option[File],
fullJavaHomes: Map[String, File],
scalaVersion: String): Seq[String] =
selectOptions(
targetSystemJdk,
jdk8home,
fullJavaHomes,
Seq(if (scalaVersion.startsWith("3.")) "-Xtarget:8" else "release:8"),
(java8home: File) => Seq("-release", "8"))
def targetJdkJavacOptions(
targetSystemJdk: Boolean,
jdk8home: Option[File],
fullJavaHomes: Map[String, File]): Seq[String] =
selectOptions(
targetSystemJdk,
jdk8home,
fullJavaHomes,
Nil,
// '-release 8' would be a neater option here, but is currently not an
// option because it doesn't provide access to `sun.misc.Unsafe` https://github.com/akka/akka/issues/27079
(java8home: File) => Seq("-source", "8", "-target", "8", "-bootclasspath", java8home + "/jre/lib/rt.jar"))
private def selectOptions(
targetSystemJdk: Boolean,
jdk8home: Option[File],
fullJavaHomes: Map[String, File],
jdk8options: Seq[String],
jdk11options: File => Seq[String]): Seq[String] =
if (targetSystemJdk)
Nil
else if (isJdk8)
jdk8options
else
jdk8home.orElse(fullJavaHomes.get("8")) match {
case Some(java8home) =>
jdk11options(java8home)
case None =>
throw new MessageOnlyException(
"A JDK 8 installation was not found, but is required to build Apache Pekko. To manually specify a JDK 8 installation, set the JAVA_8_HOME environment variable to its path or use the \"set every jdk8home := \\\"/path/to/jdk\\\" sbt command. If you have no JDK 8 installation, target your system JDK with the \"set every targetSystemJdk := true\" sbt command, but beware resulting artifacts will not work on JDK 8")
}
lazy val targetJdkSettings = Seq(targetSystemJdk := false, jdk8home := sys.env.get("JAVA_8_HOME").getOrElse(""))
val targetJdkJavacOptions = Seq("-source", "17", "-target", "17")
}

View file

@ -11,7 +11,6 @@
* Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
*/
import JdkOptions.autoImport._
import MultiJvmPlugin.autoImport.MultiJvm
import com.lightbend.paradox.projectinfo.ParadoxProjectInfoPluginKeys._
@ -110,14 +109,7 @@ object PekkoBuild {
}
}
private def jvmGCLogOptions(isJdk11OrHigher: Boolean, isJdk8: Boolean): Seq[String] = {
if (isJdk11OrHigher)
// -Xlog:gc* is equivalent to -XX:+PrintGCDetails. See:
// https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-BE93ABDC-999C-4CB5-A88B-1994AAAC74D5
Seq("-Xlog:gc*")
else if (isJdk8) Seq("-XX:+PrintGCTimeStamps", "-XX:+PrintGCDetails")
else Nil
}
private val jvmGCLogOptions: Seq[String] = Seq("-Xlog:gc*")
// -XDignore.symbol.file suppresses sun.misc.Unsafe warnings
final val DefaultJavacOptions = Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-XDignore.symbol.file")
@ -129,21 +121,12 @@ object PekkoBuild {
TestExtras.Filter.settings,
// compile options
Compile / scalacOptions ++= DefaultScalacOptions.value,
Compile / scalacOptions ++=
JdkOptions.targetJdkScalacOptions(
targetSystemJdk.value,
optionalDir(jdk8home.value),
fullJavaHomes.value,
scalaVersion.value),
Compile / scalacOptions ++= JdkOptions.targetJdkScalacOptions(scalaVersion.value),
Compile / scalacOptions ++= (if (allWarnings) Seq("-deprecation") else Nil),
Test / scalacOptions := (Test / scalacOptions).value.filterNot(opt =>
opt == "-Xlog-reflective-calls" || opt.contains("genjavadoc")),
Compile / javacOptions ++= {
DefaultJavacOptions ++
JdkOptions.targetJdkJavacOptions(targetSystemJdk.value, optionalDir(jdk8home.value), fullJavaHomes.value)
},
Test / javacOptions ++= DefaultJavacOptions ++
JdkOptions.targetJdkJavacOptions(targetSystemJdk.value, optionalDir(jdk8home.value), fullJavaHomes.value),
Compile / javacOptions ++= JdkOptions.targetJdkJavacOptions,
Test / javacOptions ++= DefaultJavacOptions ++ JdkOptions.targetJdkJavacOptions,
Compile / javacOptions ++= (if (allWarnings) Seq("-Xlint:deprecation") else Nil),
doc / javacOptions := Seq(),
crossVersion := CrossVersion.binary,
@ -219,7 +202,7 @@ object PekkoBuild {
"-Djava.security.egd=file:/dev/./urandom")
defaults ++ CliOptions.runningOnCi
.ifTrue(jvmGCLogOptions(JdkOptions.isJdk11orHigher, JdkOptions.isJdk8))
.ifTrue(jvmGCLogOptions)
.getOrElse(Nil) ++
JdkOptions.versionSpecificJavaOptions
},
@ -258,7 +241,6 @@ object PekkoBuild {
Test / testOptions += Tests.Argument("-oDF"),
mavenLocalResolverSettings,
docLintingSettings,
JdkOptions.targetJdkSettings,
// a workaround for https://github.com/akka/akka/issues/27661
// see also project/Protobuf.scala that introduces /../ to make "intellij happy"
MultiJvm / assembly / fullClasspath := {
@ -319,10 +301,7 @@ object PekkoBuild {
lazy val docLintingSettings = Seq(
compile / javacOptions ++= Seq("-Xdoclint:none"),
test / javacOptions ++= Seq("-Xdoclint:none"),
doc / javacOptions ++= {
if (JdkOptions.isJdk8) Seq("-Xdoclint:none")
else Seq("-Xdoclint:none", "--ignore-source-errors")
})
doc / javacOptions ++= Seq("-Xdoclint:none", "--ignore-source-errors"))
def loadSystemProperties(fileName: String): Unit = {
import scala.collection.JavaConverters._

View file

@ -15,7 +15,6 @@ import sbt.Keys._
import sbt._
object TestExtras {
import JdkOptions.isJdk8
object Filter {
object Keys {
lazy val excludeTestNames = settingKey[Set[String]](
@ -69,8 +68,7 @@ object TestExtras {
"The jdk9-only JavaFlowSupportCompileTest.java" -> "stream-tests/target/test-reports/TEST-org.apache.pekko.stream.javadsl.JavaFlowSupportCompileTest.xml")
val testsToCheck =
if (isJdk8) baseList
else baseList ::: jdk9Only
baseList ::: jdk9Only
testsToCheck.foreach((shouldExist _).tupled)
})

View file

@ -33,5 +33,7 @@ addSbtPlugin("io.github.roiocam" % "sbt-depend-walker" % "0.1.1")
addSbtPlugin("com.github.sbt" % "sbt-sbom" % "0.4.0")
addSbtPlugin("org.apache.pekko" % "pekko-sbt-paradox" % "1.0.1")
addSbtPlugin("com.lightbend.paradox" % "sbt-paradox-theme" % "0.10.7")
addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.10.7")
addSbtPlugin("com.gradle" % "sbt-develocity" % "1.3")

View file

@ -16,12 +16,12 @@ package org.apache.pekko.remote.artery.tcp.ssl
import java.security.PrivateKey
import java.security.cert.Certificate
import java.security.cert.X509Certificate
import scala.annotation.nowarn
import org.scalatest.matchers.must.Matchers
import org.scalatest.wordspec.AnyWordSpec
/**
*/
@nowarn("msg=deprecated")
class PemManagersProviderSpec extends AnyWordSpec with Matchers {
"A PemManagersProvider" must {

View file

@ -13,6 +13,7 @@
package org.apache.pekko.remote.classic
import scala.annotation.nowarn
import scala.collection.mutable.Set
import scala.concurrent.duration._
import scala.util.control.NonFatal
@ -48,6 +49,7 @@ class RemoteInitErrorSpec extends AnyWordSpec with Matchers {
}
""").resolve()
@nowarn("msg=deprecated")
def currentThreadIds(): Set[Long] = {
val threads = Thread.getAllStackTraces().keySet()
threads.asScala.collect { case t: Thread if !t.isDaemon() => t.getId() }