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 = [ 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 # Scala 3.3 is the latest LTS version
{ groupId = "org.scala-lang", artifactId = "scala3-library", version = "3.3." } { 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 = [ updates.ignore = [

View file

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

View file

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

View file

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

View file

@ -15,14 +15,11 @@ import sbt.Keys._
import sbt._ import sbt._
object Jdk9 extends AutoPlugin { object Jdk9 extends AutoPlugin {
import JdkOptions.notOnJdk8
import JdkOptions.JavaVersion._ import JdkOptions.JavaVersion._
// The version 9 is special for any Java versions >= 9 // The version 17 is special for any Java versions >= 17
// and the version 11 is special for any Java versions >= 11
// and the version 17 is special for any Java versions >= 17
// and the version 21 is special for any Java versions >= 21 // 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) lazy val CompileJdk9 = config("CompileJdk9").extend(Compile)
@ -59,15 +56,15 @@ object Jdk9 extends AutoPlugin {
lazy val compileJdk9Settings = Seq( lazy val compileJdk9Settings = Seq(
// following the scala-2.12, scala-sbt-1.0, ... convention // following the scala-2.12, scala-sbt-1.0, ... convention
unmanagedSourceDirectories := notOnJdk8(additionalSourceDirectories.value), unmanagedSourceDirectories := additionalSourceDirectories.value,
scalacOptions := PekkoBuild.DefaultScalacOptions.value ++ notOnJdk8(Seq("-release", majorVersion.toString)), scalacOptions := PekkoBuild.DefaultScalacOptions.value ++ Seq("-release", majorVersion.toString),
javacOptions := PekkoBuild.DefaultJavacOptions ++ notOnJdk8(Seq("--release", majorVersion.toString))) javacOptions := PekkoBuild.DefaultJavacOptions ++ Seq("--release", majorVersion.toString))
lazy val testJdk9Settings = Seq( lazy val testJdk9Settings = Seq(
// following the scala-2.12, scala-sbt-1.0, ... convention // following the scala-2.12, scala-sbt-1.0, ... convention
unmanagedSourceDirectories := notOnJdk8(additionalTestSourceDirectories.value), unmanagedSourceDirectories := additionalTestSourceDirectories.value,
scalacOptions := PekkoBuild.DefaultScalacOptions.value ++ notOnJdk8(Seq("-release", majorVersion.toString)), scalacOptions := PekkoBuild.DefaultScalacOptions.value ++ Seq("-release", majorVersion.toString),
javacOptions := PekkoBuild.DefaultJavacOptions ++ notOnJdk8(Seq("--release", majorVersion.toString)), javacOptions := PekkoBuild.DefaultJavacOptions ++ Seq("--release", majorVersion.toString),
compile := compile.dependsOn(CompileJdk9 / compile).value, compile := compile.dependsOn(CompileJdk9 / compile).value,
classpathConfiguration := TestJdk9, classpathConfiguration := TestJdk9,
externalDependencyClasspath := (Test / externalDependencyClasspath).value) 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 // 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. // add jdk9 products to dependencyClasspathAsJars instead.
// Compile / fullClasspath ++= (CompileJdk9 / exportedProducts).value) // Compile / fullClasspath ++= (CompileJdk9 / exportedProducts).value)
Compile / dependencyClasspathAsJars ++= notOnJdk8((CompileJdk9 / exportedProducts).value)) Compile / dependencyClasspathAsJars ++= (CompileJdk9 / exportedProducts).value)
lazy val testSettings = Seq((Test / test) := { lazy val testSettings = Seq((Test / test) := {
(Test / test).value (Test / test).value

View file

@ -18,90 +18,24 @@ import sbt.librarymanagement.SemanticSelector
import sbt.librarymanagement.VersionNumber import sbt.librarymanagement.VersionNumber
object JdkOptions extends AutoPlugin { 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") lazy val specificationVersion: String = sys.props("java.specification.version")
object JavaVersion { object JavaVersion {
val majorVersion: Int = { val majorVersion: Int = java.lang.Runtime.version().feature()
// 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
}
} }
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 = lazy val versionSpecificJavaOptions =
if (isJdk17orHigher) { // for virtual threads
// for virtual threads "--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED" ::
"--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED" :: "--add-opens=java.base/java.lang=ALL-UNNAMED" ::
"--add-opens=java.base/java.lang=ALL-UNNAMED" :: // for aeron
// for aeron "--add-opens=java.base/sun.nio.ch=ALL-UNNAMED" ::
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED" :: // for LevelDB
// for LevelDB "--add-opens=java.base/java.nio=ALL-UNNAMED" :: Nil
"--add-opens=java.base/java.nio=ALL-UNNAMED" :: Nil
} else 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( val targetJdkJavacOptions = Seq("-source", "17", "-target", "17")
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(""))
} }

View file

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

View file

@ -15,7 +15,6 @@ import sbt.Keys._
import sbt._ import sbt._
object TestExtras { object TestExtras {
import JdkOptions.isJdk8
object Filter { object Filter {
object Keys { object Keys {
lazy val excludeTestNames = settingKey[Set[String]]( 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") "The jdk9-only JavaFlowSupportCompileTest.java" -> "stream-tests/target/test-reports/TEST-org.apache.pekko.stream.javadsl.JavaFlowSupportCompileTest.xml")
val testsToCheck = val testsToCheck =
if (isJdk8) baseList baseList ::: jdk9Only
else baseList ::: jdk9Only
testsToCheck.foreach((shouldExist _).tupled) 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("com.github.sbt" % "sbt-sbom" % "0.4.0")
addSbtPlugin("org.apache.pekko" % "pekko-sbt-paradox" % "1.0.1") 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") 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.PrivateKey
import java.security.cert.Certificate import java.security.cert.Certificate
import java.security.cert.X509Certificate import java.security.cert.X509Certificate
import scala.annotation.nowarn
import org.scalatest.matchers.must.Matchers import org.scalatest.matchers.must.Matchers
import org.scalatest.wordspec.AnyWordSpec import org.scalatest.wordspec.AnyWordSpec
/** @nowarn("msg=deprecated")
*/
class PemManagersProviderSpec extends AnyWordSpec with Matchers { class PemManagersProviderSpec extends AnyWordSpec with Matchers {
"A PemManagersProvider" must { "A PemManagersProvider" must {

View file

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