From 91f8a63b125c5241de5a1a5e46daa578d7b9bc39 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 2 Mar 2018 16:13:37 -0500 Subject: [PATCH] Add marker interface LibraryClassLoader This mixes in a market interface with scalaVersion method into URLClassLoader. We can use this later to distinguish new launcher vs old one. --- .../src/main/scala/xsbt/boot/Launch.scala | 2 +- .../scala/xsbt/boot/LibraryClassLoader.scala | 7 +++++++ .../src/test/scala/ScalaProviderTest.scala | 20 +++++++++++++++---- .../main/java/xsbti/LibraryClassLoader.java | 11 ++++++++++ 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 launcher-implementation/src/main/scala/xsbt/boot/LibraryClassLoader.scala create mode 100644 launcher-interface/src/main/java/xsbti/LibraryClassLoader.java diff --git a/launcher-implementation/src/main/scala/xsbt/boot/Launch.scala b/launcher-implementation/src/main/scala/xsbt/boot/Launch.scala index 08bbb54..a8c63e7 100644 --- a/launcher-implementation/src/main/scala/xsbt/boot/Launch.scala +++ b/launcher-implementation/src/main/scala/xsbt/boot/Launch.scala @@ -328,7 +328,7 @@ class Launch private[xsbt] (val bootDirectory: File, val lockBoot: Boolean, val private object LoaderInit { val (library, other) = module.fullClasspath.partition(_.getName.startsWith("scala-library")) - val libraryLoader = new URLClassLoader(toURLs(library), parentLoader) + val libraryLoader = new LibraryClassLoader(toURLs(library), parentLoader, scalaVersion) val fullLoader = new URLClassLoader(toURLs(other), libraryLoader) } diff --git a/launcher-implementation/src/main/scala/xsbt/boot/LibraryClassLoader.scala b/launcher-implementation/src/main/scala/xsbt/boot/LibraryClassLoader.scala new file mode 100644 index 0000000..810db4f --- /dev/null +++ b/launcher-implementation/src/main/scala/xsbt/boot/LibraryClassLoader.scala @@ -0,0 +1,7 @@ +package xsbt.boot + +import java.net.{ URL, URLClassLoader } + +final class LibraryClassLoader(urls: Array[URL], parent: ClassLoader, + val scalaVersion: String) extends URLClassLoader(urls, parent) with xsbti.LibraryClassLoader { +} diff --git a/launcher-implementation/src/test/scala/ScalaProviderTest.scala b/launcher-implementation/src/test/scala/ScalaProviderTest.scala index 425468a..d28890c 100644 --- a/launcher-implementation/src/test/scala/ScalaProviderTest.scala +++ b/launcher-implementation/src/test/scala/ScalaProviderTest.scala @@ -15,8 +15,10 @@ object ScalaProviderTest extends Specification { "provide ClassLoader for Scala 2.8.2" in { checkScalaLoader("2.8.2") } "provide ClassLoader for Scala 2.9.0" in { checkScalaLoader("2.9.0") } "provide ClassLoader for Scala 2.9.2" in { checkScalaLoader("2.9.2") } - "provide ClassLoader for Scala 2.10.4" in { checkScalaLoader("2.10.4") } - "provide ClassLoader for Scala 2.11.0" in { checkScalaLoader("2.11.0") } + "provide ClassLoader for Scala 2.10.7" in { checkScalaLoader("2.10.7") } + "provide ClassLoader for Scala 2.11.12" in { checkScalaLoader("2.11.12") } + // This requires the test to run in JDK 8 + // "provide ClassLoader for Scala 2.12.4" in { checkScalaLoader("2.12.4") } } "Launch" should { @@ -68,10 +70,20 @@ object ScalaProviderTest extends Specification { val provider = launcher.getScala(version) val loader = provider.loader // ensure that this loader can load Scala classes by trying scala.ScalaObject. - tryScala(loader) + tryScala(loader, loader.getParent) getScalaVersion(loader) must beEqualTo(versionValue) + + val libraryLoader = provider.loader.getParent + // Test the structural type + libraryLoader match { + case x: ClassLoader with LibraryLoader => x.scalaVersion must be(version) + } + tryScala(libraryLoader, libraryLoader) } - private def tryScala(loader: ClassLoader) = Class.forName("scala.Product", false, loader).getClassLoader must be(loader) + private def tryScala(loader: ClassLoader, libraryLoader: ClassLoader) = + Class.forName("scala.Product", false, loader).getClassLoader must be(libraryLoader) + + type LibraryLoader = { def scalaVersion: String } } object LaunchTest { def testApp(main: String): Application = testApp(main, Array[File]()) diff --git a/launcher-interface/src/main/java/xsbti/LibraryClassLoader.java b/launcher-interface/src/main/java/xsbti/LibraryClassLoader.java new file mode 100644 index 0000000..ec80256 --- /dev/null +++ b/launcher-interface/src/main/java/xsbti/LibraryClassLoader.java @@ -0,0 +1,11 @@ +package xsbti; + +import java.io.File; + +/** + * Marker interface for classloader with just scala-library. + */ +public interface LibraryClassLoader +{ + public String scalaVersion(); +}