From bcec7c0fa0cd9f68c4858d168f0dfadcb3ba4602 Mon Sep 17 00:00:00 2001 From: "He-Pin(kerr)" Date: Sun, 28 Jan 2024 17:46:03 +0800 Subject: [PATCH] feat: Add multi java lts support. (#1054) * feat: Add multi java lts support. * Simplify the code --------- Co-authored-by: JingZhang Chen --- .../classical/OptimizedActorWithJava21.java | 53 ++++++++++--------- project/CopyrightHeaderForJdk9.scala | 23 ++++---- project/Jdk9.scala | 50 ++++++++++++----- project/JdkOptions.scala | 13 +++++ project/ProjectFileIgnoreSupport.scala | 4 +- 5 files changed, 93 insertions(+), 50 deletions(-) diff --git a/docs/src/main/java-jdk-21/docs/actors/classical/OptimizedActorWithJava21.java b/docs/src/main/java-jdk-21/docs/actors/classical/OptimizedActorWithJava21.java index ab43f2f35c..7223b99ce4 100644 --- a/docs/src/main/java-jdk-21/docs/actors/classical/OptimizedActorWithJava21.java +++ b/docs/src/main/java-jdk-21/docs/actors/classical/OptimizedActorWithJava21.java @@ -1,33 +1,38 @@ - +package docs.actors.classical; // #pattern-matching -static class OptimizedActorWithJava21 extends UntypedAbstractActor { - public static class Msg1 {} +import org.apache.pekko.actor.UntypedAbstractActor; - public static class Msg2 {} - - public static class Msg3 {} - - @Override - public void onReceive(Object msg) throws Exception { - switch(msg) { - case Msg1 msg -> receiveMsg1((Msg1) msg); - case Msg2 msg -> receiveMsg2((Msg2) msg); - case Msg3 msg -> receiveMsg3((Msg3) msg); - default _ -> unhandled(msg); +public class OptimizedActorWithJava21 extends UntypedAbstractActor { + public static class Msg1 { } - } - private void receiveMsg1(Msg1 msg) { - // actual work - } + public static class Msg2 { + } - private void receiveMsg2(Msg2 msg) { - // actual work - } + public static class Msg3 { + } - private void receiveMsg3(Msg3 msg) { - // actual work - } + @Override + public void onReceive(Object msg) throws Exception { + switch (msg) { + case Msg1 msg1 -> receiveMsg1(msg1); + case Msg2 msg2 -> receiveMsg2(msg2); + case Msg3 msg3 -> receiveMsg3(msg3); + default -> unhandled(msg); + } + } + + private void receiveMsg1(Msg1 msg) { + // actual work + } + + private void receiveMsg2(Msg2 msg) { + // actual work + } + + private void receiveMsg3(Msg3 msg) { + // actual work + } } // #pattern-matching diff --git a/project/CopyrightHeaderForJdk9.scala b/project/CopyrightHeaderForJdk9.scala index aa1b6ccdc4..1707bbbc38 100644 --- a/project/CopyrightHeaderForJdk9.scala +++ b/project/CopyrightHeaderForJdk9.scala @@ -12,7 +12,6 @@ */ import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport.headerSources -import sbt.Keys.sourceDirectory import sbt.{ Compile, Def, Test, _ } object CopyrightHeaderForJdk9 extends AutoPlugin { @@ -20,16 +19,18 @@ object CopyrightHeaderForJdk9 extends AutoPlugin { override lazy val requires = CopyrightHeader && Jdk9 override lazy val trigger = allRequirements - override lazy val projectSettings: Seq[Def.Setting[_]] = { + private lazy val additionalFiles = Def.setting { import Jdk9._ - Seq( - Compile / headerSources ++= - (((Compile / sourceDirectory).value / SCALA_SOURCE_DIRECTORY) ** "*.scala").get, - Test / headerSources ++= - (((Test / sourceDirectory).value / SCALA_TEST_SOURCE_DIRECTORY) ** "*.scala").get, - Compile / headerSources ++= - (((Compile / sourceDirectory).value / JAVA_SOURCE_DIRECTORY) ** "*.java").get, - Test / headerSources ++= - (((Test / sourceDirectory).value / JAVA_TEST_SOURCE_DIRECTORY) ** "*.java").get) + for { + dir <- additionalSourceDirectories.value ++ additionalTestSourceDirectories.value + language <- List("java", "scala") + file <- (dir ** s"*.$language").get + } yield file + } + + override lazy val projectSettings: Seq[Def.Setting[_]] = { + + Seq(Compile / headerSources ++= additionalFiles.value, + Test / headerSources ++= additionalFiles.value) } } diff --git a/project/Jdk9.scala b/project/Jdk9.scala index 7c3bfb33f6..e368aeddb2 100644 --- a/project/Jdk9.scala +++ b/project/Jdk9.scala @@ -11,36 +11,60 @@ * Copyright (C) 2017-2022 Lightbend Inc. */ -import sbt._ import sbt.Keys._ +import sbt._ object Jdk9 extends AutoPlugin { import JdkOptions.notOnJdk8 + // 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 + // and the version 21 is special for any Java versions >= 21 + private val supportedJavaLTSVersions = List("9", "11", "17", "21") + lazy val CompileJdk9 = config("CompileJdk9").extend(Compile) lazy val TestJdk9 = config("TestJdk9").extend(Test).extend(CompileJdk9) - val SCALA_SOURCE_DIRECTORY = "scala-jdk-9" - val SCALA_TEST_SOURCE_DIRECTORY = "scala-jdk9-only" - val JAVA_SOURCE_DIRECTORY = "java-jdk-9" - val JAVA_TEST_SOURCE_DIRECTORY = "java-jdk9-only" + lazy val ScalaSourceDirectories: Seq[String] = getAdditionalSourceDirectoryNames("scala") + lazy val ScalaTestSourceDirectories: Seq[String] = getAdditionalSourceDirectoryNames("scala", isTest = true) + + lazy val JavaSourceDirectories: Seq[String] = getAdditionalSourceDirectoryNames("java") + lazy val JavaTestSourceDirectories: Seq[String] = getAdditionalSourceDirectoryNames("java", isTest = true) + + lazy val additionalSourceDirectories = + getAdditionalSourceDirectories(Compile, ScalaSourceDirectories ++ JavaSourceDirectories) + + lazy val additionalTestSourceDirectories = + getAdditionalSourceDirectories(Test, ScalaTestSourceDirectories ++ JavaTestSourceDirectories) + + private def getAdditionalSourceDirectoryNames(language: String, isTest: Boolean = false): Seq[String] = { + for { + version <- supportedJavaLTSVersions if version.toInt <= JdkOptions.JavaVersion.majorVersion + } yield { + if (isTest) { + s"$language-jdk$version-only" + } else { + s"$language-jdk-$version" + } + } + } + + private def getAdditionalSourceDirectories(task: Configuration, sourceDirectoryNames: Seq[String]) = Def.setting { + for (sourceDirectoryName <- sourceDirectoryNames) + yield (task / sourceDirectory).value / sourceDirectoryName + } lazy val compileJdk9Settings = Seq( // following the scala-2.12, scala-sbt-1.0, ... convention - unmanagedSourceDirectories := notOnJdk8( - Seq( - (Compile / sourceDirectory).value / SCALA_SOURCE_DIRECTORY, - (Compile / sourceDirectory).value / JAVA_SOURCE_DIRECTORY)), + unmanagedSourceDirectories := notOnJdk8(additionalSourceDirectories.value), scalacOptions := PekkoBuild.DefaultScalacOptions.value ++ notOnJdk8(Seq("-release", "11")), javacOptions := PekkoBuild.DefaultJavacOptions ++ notOnJdk8(Seq("--release", "11"))) lazy val testJdk9Settings = Seq( // following the scala-2.12, scala-sbt-1.0, ... convention - unmanagedSourceDirectories := notOnJdk8( - Seq( - (Test / sourceDirectory).value / SCALA_TEST_SOURCE_DIRECTORY, - (Test / sourceDirectory).value / JAVA_TEST_SOURCE_DIRECTORY)), + unmanagedSourceDirectories := notOnJdk8(additionalTestSourceDirectories.value), scalacOptions := PekkoBuild.DefaultScalacOptions.value ++ notOnJdk8(Seq("-release", "11")), javacOptions := PekkoBuild.DefaultJavacOptions ++ notOnJdk8(Seq("--release", "11")), compile := compile.dependsOn(CompileJdk9 / compile).value, diff --git a/project/JdkOptions.scala b/project/JdkOptions.scala index c89af7d652..852a2bb82d 100644 --- a/project/JdkOptions.scala +++ b/project/JdkOptions.scala @@ -27,6 +27,19 @@ object JdkOptions extends AutoPlugin { 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 + } + } + lazy val isJdk8: Boolean = VersionNumber(specificationVersion).matchesSemVer(SemanticSelector(s"=1.8")) lazy val isJdk11orHigher: Boolean = diff --git a/project/ProjectFileIgnoreSupport.scala b/project/ProjectFileIgnoreSupport.scala index d4a5414b64..fa055c94fb 100644 --- a/project/ProjectFileIgnoreSupport.scala +++ b/project/ProjectFileIgnoreSupport.scala @@ -19,9 +19,9 @@ import sbt.ConsoleLogger class ProjectFileIgnoreSupport(ignoreConfigFile: File, descriptor: String) { private lazy val stdoutLogger = ConsoleLogger(System.out) - private val javaSourceDirectories = Set("java", Jdk9.JAVA_SOURCE_DIRECTORY, Jdk9.JAVA_TEST_SOURCE_DIRECTORY) + private val javaSourceDirectories = Set("java") ++ Jdk9.JavaSourceDirectories ++ Jdk9.JavaTestSourceDirectories - private val scalaSourceDirectories = Set("scala", Jdk9.SCALA_SOURCE_DIRECTORY, Jdk9.SCALA_TEST_SOURCE_DIRECTORY) + private val scalaSourceDirectories = Set("scala") ++ Jdk9.ScalaSourceDirectories ++ Jdk9.ScalaTestSourceDirectories private lazy val ignoreConfig = { require(