From 7630ed8201969c82a718a6630588fe4b2485f838 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Tue, 3 Jul 2018 11:06:04 +0200 Subject: [PATCH 1/3] Select most recent jdk When multiple jdk minor/patch versions are available, select the most recent one. --- .../main/scala/sbt/internal/CrossJava.scala | 52 ++++++++++++++----- .../scala/sbt/internal/CrossJavaTest.scala | 13 +++++ 2 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 main/src/test/scala/sbt/internal/CrossJavaTest.scala diff --git a/main/src/main/scala/sbt/internal/CrossJava.scala b/main/src/main/scala/sbt/internal/CrossJava.scala index 9ee668042..91b829261 100644 --- a/main/src/main/scala/sbt/internal/CrossJava.scala +++ b/main/src/main/scala/sbt/internal/CrossJava.scala @@ -10,6 +10,7 @@ package internal import java.io.File import scala.collection.immutable.ListMap +import scala.annotation.tailrec import sbt.io.Path import sbt.io.syntax._ import sbt.Cross._ @@ -308,24 +309,47 @@ private[sbt] object CrossJava { def javaHomes: Vector[(String, File)] } + // Sort version strings, considering 1.8.0 < 1.8.0_45 < 1.8.0_212 + @tailrec + def versionOrder(left: String, right: String): Boolean = { + val Pattern = """.*?([0-9]+)(.*)""".r + left match { + case Pattern(leftNumber, leftRest) => + right match { + case Pattern(rightNumber, rightRest) => + if (Integer.parseInt(leftNumber) < Integer.parseInt(rightNumber)) true + else if (Integer.parseInt(leftNumber) > Integer.parseInt(rightNumber)) false + else versionOrder(leftRest, rightRest) + case _ => + false + } + case _ => + true + } + } + object JavaDiscoverConfig { val linux = new JavaDiscoverConf { val base: File = file("/usr") / "lib" / "jvm" val JavaHomeDir = """java-([0-9]+)-.*""".r def javaHomes: Vector[(String, File)] = - wrapNull(base.list()).collect { - case dir @ JavaHomeDir(ver) => JavaVersion(ver).toString -> (base / dir) - } + wrapNull(base.list()) + .sortWith(versionOrder) + .collect { + case dir @ JavaHomeDir(ver) => JavaVersion(ver).toString -> (base / dir) + } } val macOS = new JavaDiscoverConf { val base: File = file("/Library") / "Java" / "JavaVirtualMachines" val JavaHomeDir = """jdk-?(1\.)?([0-9]+).*""".r def javaHomes: Vector[(String, File)] = - wrapNull(base.list()).collect { - case dir @ JavaHomeDir(m, n) => - JavaVersion(nullBlank(m) + n).toString -> (base / dir / "Contents" / "Home") - } + wrapNull(base.list()) + .sortWith(versionOrder) + .collect { + case dir @ JavaHomeDir(m, n) => + JavaVersion(nullBlank(m) + n).toString -> (base / dir / "Contents" / "Home") + } } // See https://github.com/shyiko/jabba @@ -333,12 +357,14 @@ private[sbt] object CrossJava { val base: File = Path.userHome / ".jabba" / "jdk" val JavaHomeDir = """([\w\-]+)\@(1\.)?([0-9]+).*""".r def javaHomes: Vector[(String, File)] = - wrapNull(base.list()).collect { - case dir @ JavaHomeDir(vendor, m, n) => - val v = JavaVersion(nullBlank(m) + n).withVendor(vendor).toString - if ((base / dir / "Contents" / "Home").exists) v -> (base / dir / "Contents" / "Home") - else v -> (base / dir) - } + wrapNull(base.list()) + .sortWith(versionOrder) + .collect { + case dir @ JavaHomeDir(vendor, m, n) => + val v = JavaVersion(nullBlank(m) + n).withVendor(vendor).toString + if ((base / dir / "Contents" / "Home").exists) v -> (base / dir / "Contents" / "Home") + else v -> (base / dir) + } } } diff --git a/main/src/test/scala/sbt/internal/CrossJavaTest.scala b/main/src/test/scala/sbt/internal/CrossJavaTest.scala new file mode 100644 index 000000000..8c363391b --- /dev/null +++ b/main/src/test/scala/sbt/internal/CrossJavaTest.scala @@ -0,0 +1,13 @@ +package sbt.internal + +import org.specs2.mutable.Specification + +class CrossJavaTest extends Specification { + "The Java home selector" should { + "select the most recent" in { + List("jdk1.8.0.jdk", "jdk1.8.0_121.jdk", "jdk1.8.0_45.jdk") + .sortWith(CrossJava.versionOrder) + .last must be equalTo ("jdk1.8.0_121.jdk") + } + } +} From 57e3183b8d5e8f48628379b81e16dc5e32843a78 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Tue, 3 Jul 2018 15:29:31 +0200 Subject: [PATCH 2/3] Discover jvm installed via Oracle Linux RPM's --- .../main/scala/sbt/internal/CrossJava.scala | 34 +++++++++++-------- .../scala/sbt/internal/CrossJavaTest.scala | 32 +++++++++++++++++ 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/main/src/main/scala/sbt/internal/CrossJava.scala b/main/src/main/scala/sbt/internal/CrossJava.scala index 91b829261..e337c6863 100644 --- a/main/src/main/scala/sbt/internal/CrossJava.scala +++ b/main/src/main/scala/sbt/internal/CrossJava.scala @@ -300,15 +300,16 @@ private[sbt] object CrossJava { } def discoverJavaHomes: ListMap[String, File] = { - import JavaDiscoverConfig._ - val configs = Vector(jabba, linux, macOS) - ListMap(configs flatMap { _.javaHomes }: _*) + ListMap(JavaDiscoverConfig.configs flatMap { _.javaHomes } sortWith (versionOrder): _*) } sealed trait JavaDiscoverConf { def javaHomes: Vector[(String, File)] } + def versionOrder(left: (_, File), right: (_, File)): Boolean = + versionOrder(left._2.getName, right._2.getName) + // Sort version strings, considering 1.8.0 < 1.8.0_45 < 1.8.0_212 @tailrec def versionOrder(left: String, right: String): Boolean = { @@ -329,36 +330,34 @@ private[sbt] object CrossJava { } object JavaDiscoverConfig { - val linux = new JavaDiscoverConf { - val base: File = file("/usr") / "lib" / "jvm" - val JavaHomeDir = """java-([0-9]+)-.*""".r + class LinuxDiscoverConfig(base: File) extends JavaDiscoverConf { + def candidates = wrapNull(base.list()) + val JavaHomeDir = """(java-|jdk)(1\.)?([0-9]+).*""".r def javaHomes: Vector[(String, File)] = - wrapNull(base.list()) - .sortWith(versionOrder) + candidates .collect { - case dir @ JavaHomeDir(ver) => JavaVersion(ver).toString -> (base / dir) + case dir @ JavaHomeDir(_, m, n) => + JavaVersion(nullBlank(m) + n).toString -> (base / dir) } } - val macOS = new JavaDiscoverConf { + class MacOsDiscoverConfig extends JavaDiscoverConf { val base: File = file("/Library") / "Java" / "JavaVirtualMachines" val JavaHomeDir = """jdk-?(1\.)?([0-9]+).*""".r def javaHomes: Vector[(String, File)] = wrapNull(base.list()) - .sortWith(versionOrder) .collect { case dir @ JavaHomeDir(m, n) => JavaVersion(nullBlank(m) + n).toString -> (base / dir / "Contents" / "Home") } } - // See https://github.com/shyiko/jabba - val jabba = new JavaDiscoverConf { + class JabbaDiscoverConfig extends JavaDiscoverConf { val base: File = Path.userHome / ".jabba" / "jdk" val JavaHomeDir = """([\w\-]+)\@(1\.)?([0-9]+).*""".r + def javaHomes: Vector[(String, File)] = wrapNull(base.list()) - .sortWith(versionOrder) .collect { case dir @ JavaHomeDir(vendor, m, n) => val v = JavaVersion(nullBlank(m) + n).withVendor(vendor).toString @@ -366,6 +365,13 @@ private[sbt] object CrossJava { else v -> (base / dir) } } + + val configs = Vector( + new JabbaDiscoverConfig, + new LinuxDiscoverConfig(file("/usr") / "java"), + new LinuxDiscoverConfig(file("/usr") / "lib" / "jvm"), + new MacOsDiscoverConfig + ) } def nullBlank(s: String): String = diff --git a/main/src/test/scala/sbt/internal/CrossJavaTest.scala b/main/src/test/scala/sbt/internal/CrossJavaTest.scala index 8c363391b..6b29db490 100644 --- a/main/src/test/scala/sbt/internal/CrossJavaTest.scala +++ b/main/src/test/scala/sbt/internal/CrossJavaTest.scala @@ -1,6 +1,7 @@ package sbt.internal import org.specs2.mutable.Specification +import sbt.internal.CrossJava.JavaDiscoverConfig.LinuxDiscoverConfig class CrossJavaTest extends Specification { "The Java home selector" should { @@ -10,4 +11,35 @@ class CrossJavaTest extends Specification { .last must be equalTo ("jdk1.8.0_121.jdk") } } + + "The Linux Java home selector" should { + "correctly pick up fedora java installations" in { + val conf = new LinuxDiscoverConfig(sbt.io.syntax.file(".")) { + override def candidates: Vector[String] = + """ + |java-1.8.0-openjdk-1.8.0.162-3.b12.fc28.x86_64 + |java-1.8.0-openjdk-1.8.0.172-9.b11.fc28.x86_64 + |java-1.8.0 + |java-1.8.0-openjdk + |java-openjdk + |jre-1.8.0 + |jre-1.8.0-openjdk + |jre-1.8.0-openjdk-1.8.0.172-9.b11.fc28.x86_64 + |jre-openjdk + """.stripMargin.split("\n").filter(_.nonEmpty).toVector + } + val (version, file) = conf.javaHomes.sortWith(CrossJava.versionOrder).last + version must be equalTo ("1.8") + file.getName must be equalTo ("java-1.8.0-openjdk-1.8.0.172-9.b11.fc28.x86_64") + } + + "correctly pick up Oracle RPM installations" in { + val conf = new LinuxDiscoverConfig(sbt.io.syntax.file(".")) { + override def candidates: Vector[String] = Vector("jdk1.8.0_172-amd64") + } + val (version, file) = conf.javaHomes.sortWith(CrossJava.versionOrder).last + version must be equalTo ("1.8") + file.getName must be equalTo ("jdk1.8.0_172-amd64") + } + } } From 46693548d7dd66a86c40f7820d166253b4a5989f Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Tue, 3 Jul 2018 15:50:57 +0200 Subject: [PATCH 3/3] Add missing copyright header --- main/src/test/scala/sbt/internal/CrossJavaTest.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/main/src/test/scala/sbt/internal/CrossJavaTest.scala b/main/src/test/scala/sbt/internal/CrossJavaTest.scala index 6b29db490..ba281b64f 100644 --- a/main/src/test/scala/sbt/internal/CrossJavaTest.scala +++ b/main/src/test/scala/sbt/internal/CrossJavaTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal import org.specs2.mutable.Specification