Option to target system JDK instead of JDK8 (#27083)

Inspired by the proposal by @nvollmar in 0940dfc
This commit is contained in:
Arnout Engelen 2019-06-17 16:55:54 +02:00 committed by GitHub
parent 51789515f2
commit af3ee37d6c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 20 deletions

View file

@ -23,7 +23,6 @@ import spray.boilerplate.BoilerplatePlugin
initialize := { initialize := {
// Load system properties from a file to make configuration from Jenkins easier // Load system properties from a file to make configuration from Jenkins easier
loadSystemProperties("project/akka-build.properties") loadSystemProperties("project/akka-build.properties")
assert(CrossJava.Keys.fullJavaHomes.value.contains("8"), "JDK 8 is not installed but required to build akka")
initialize.value initialize.value
} }

View file

@ -11,8 +11,11 @@ import java.time.format.DateTimeFormatter
import java.time.ZonedDateTime import java.time.ZonedDateTime
import java.time.ZoneOffset import java.time.ZoneOffset
import sbt.Keys._ // Overriding CrossJava imports #26935
import sbt.Keys.{fullJavaHomes=>_,_}
import sbt._ import sbt._
import CrossJava.autoImport._
import org.scalafmt.sbt.ScalafmtPlugin.autoImport._ import org.scalafmt.sbt.ScalafmtPlugin.autoImport._
import scala.collection.breakOut import scala.collection.breakOut
@ -128,21 +131,15 @@ object AkkaBuild {
// compile options // compile options
scalacOptions in Compile ++= DefaultScalacOptions, scalacOptions in Compile ++= DefaultScalacOptions,
// Makes sure that, even when compiling with a jdk version greater than 8, the resulting jar will not refer to scalacOptions in Compile ++=
// methods not found in jdk8. To test whether this has the desired effect, compile akka-remote and check the CrossJava.targetJdkScalacOptions(targetSystemJdk.value, fullJavaHomes.value),
// invocation of 'ByteBuffer.clear()' in EnvelopeBuffer.class with 'javap -c': it should refer to
// "java/nio/ByteBuffer.clear:()Ljava/nio/Buffer" and not "java/nio/ByteBuffer.clear:()Ljava/nio/ByteBuffer":
scalacOptions in Compile ++= (
if (JavaVersion.isJdk8)
Seq("-target:jvm-1.8")
else
// -release 8 is not enough, for some reason we need the 8 rt.jar explicitly #25330
Seq("-release", "8", "-javabootclasspath", CrossJava.Keys.fullJavaHomes.value("8") + "/jre/lib/rt.jar")),
scalacOptions in Compile ++= (if (allWarnings) Seq("-deprecation") else Nil), scalacOptions in Compile ++= (if (allWarnings) Seq("-deprecation") else Nil),
scalacOptions in Test := (scalacOptions in Test).value.filterNot(opt => scalacOptions in Test := (scalacOptions in Test).value.filterNot(opt =>
opt == "-Xlog-reflective-calls" || opt.contains("genjavadoc")), opt == "-Xlog-reflective-calls" || opt.contains("genjavadoc")),
javacOptions in compile ++= DefaultJavacOptions ++ JavaVersion.sourceAndTarget(CrossJava.Keys.fullJavaHomes.value("8")), javacOptions in compile ++= DefaultJavacOptions ++
javacOptions in test ++= DefaultJavacOptions ++ JavaVersion.sourceAndTarget(CrossJava.Keys.fullJavaHomes.value("8")), CrossJava.targetJdkJavacOptions(targetSystemJdk.value, fullJavaHomes.value),
javacOptions in test ++= DefaultJavacOptions ++
CrossJava.targetJdkJavacOptions(targetSystemJdk.value, fullJavaHomes.value),
javacOptions in compile ++= (if (allWarnings) Seq("-Xlint:deprecation") else Nil), javacOptions in compile ++= (if (allWarnings) Seq("-Xlint:deprecation") else Nil),
javacOptions in doc ++= Seq(), javacOptions in doc ++= Seq(),

View file

@ -15,8 +15,9 @@ import akka.CrossJava.nullBlank
/* /*
* Tools for discovering different Java versions, * Tools for discovering different Java versions,
* will be in sbt 1.3.0 (https://github.com/sbt/sbt/pull/4139 et al) *
* but until that time replicated here * Some of these will be in sbt 1.3.0 (https://github.com/sbt/sbt/pull/4139 et al)
* but are replicated here until that time
*/ */
case class JavaVersion(numbers: Vector[Long], vendor: Option[String]) { case class JavaVersion(numbers: Vector[Long], vendor: Option[String]) {
def numberStr: String = numbers.mkString(".") def numberStr: String = numbers.mkString(".")
@ -49,21 +50,59 @@ object JavaVersion {
def sourceAndTarget(fullJavaHome: File): Seq[String] = def sourceAndTarget(fullJavaHome: File): Seq[String] =
if (isJdk8) Seq.empty if (isJdk8) Seq.empty
else Seq("-source", "8", "-target", "8", "-bootclasspath", fullJavaHome + "/jre/lib/rt.jar") else Seq("-source", "8", "-target", "8", "-bootclasspath", fullJavaHome + "/jre/lib/rt.jar")
} }
object CrossJava { object CrossJava extends AutoPlugin {
object Keys { object autoImport {
val discoveredJavaHomes = settingKey[Map[String, File]]("Discovered Java home directories") val discoveredJavaHomes = settingKey[Map[String, File]]("Discovered Java home directories")
val javaHomes = settingKey[Map[String, File]]("The user-defined additional Java home directories") val javaHomes = settingKey[Map[String, File]]("The user-defined additional Java home directories")
val fullJavaHomes = settingKey[Map[String, File]]("Combines discoveredJavaHomes and custom javaHomes.") val fullJavaHomes = settingKey[Map[String, File]]("Combines discoveredJavaHomes and custom javaHomes.")
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._
import Keys._ def targetJdkScalacOptions(targetSystemJdk: Boolean, fullJavaHomes: Map[String, File]): Seq[String] =
selectOptions(
targetSystemJdk,
fullJavaHomes,
Seq("-target:jvm-1.8"),
// '-release 8' is not enough, for some reason we need the 8 rt.jar
// explicitly. To test whether this has the desired effect, compile
// akka-remote and check the invocation of 'ByteBuffer.clear()' in
// EnvelopeBuffer.class with 'javap -c': it should refer to
//""java/nio/ByteBuffer.clear:()Ljava/nio/Buffer" and not
// "java/nio/ByteBuffer.clear:()Ljava/nio/ByteBuffer". Issue #27079
(java8home: File) => Seq("-release", "8", "-javabootclasspath", java8home + "/jre/lib/rt.jar")
)
def targetJdkJavacOptions(targetSystemJdk: Boolean, fullJavaHomes: Map[String, File]): Seq[String] =
selectOptions(
targetSystemJdk,
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` #27079
(java8home: File) => Seq("-source", "8", "-target", "8", "-bootclasspath", java8home + "/jre/lib/rt.jar")
)
private def selectOptions(targetSystemJdk: Boolean, fullJavaHomes: Map[String, File], jdk8options: Seq[String], jdk11options: File => Seq[String]): Seq[String] =
if (targetSystemJdk)
Nil
else if (JavaVersion.isJdk8)
jdk8options
else 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 Akka. To target your system JDK, use the \"set every targetSystemJdk := true\" sbt command. Resulting artifacts may not work on JDK 8")
}
val crossJavaSettings = Seq( val crossJavaSettings = Seq(
discoveredJavaHomes := CrossJava.discoverJavaHomes, discoveredJavaHomes := CrossJava.discoverJavaHomes,
javaHomes := ListMap.empty, javaHomes := ListMap.empty,
fullJavaHomes := CrossJava.expandJavaHomes(discoveredJavaHomes.value ++ javaHomes.value)) fullJavaHomes := CrossJava.expandJavaHomes(discoveredJavaHomes.value ++ javaHomes.value),
targetSystemJdk := false,
)
// parses jabaa style version number adopt@1.8 // parses jabaa style version number adopt@1.8
def parseJavaVersion(version: String): JavaVersion = { def parseJavaVersion(version: String): JavaVersion = {