summaryrefslogtreecommitdiff
path: root/src/repl/scala/tools/nsc
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-12-12 15:33:02 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-12-12 15:33:02 +1000
commita346b779324a474a180b1370fddc5a58ff629410 (patch)
treeecac6c1da900a9d59aa2e046315d3b89a093f563 /src/repl/scala/tools/nsc
parent3de1c0c56ee530f4e75533fc9e1909fe0cde31b5 (diff)
downloadscala-a346b779324a474a180b1370fddc5a58ff629410.tar.gz
scala-a346b779324a474a180b1370fddc5a58ff629410.tar.bz2
scala-a346b779324a474a180b1370fddc5a58ff629410.zip
Support extra module references in the REPL
By default, scala-compiler.jar is in the bootclasspath, which gives us a `null` when we call `classOf[IMain].getClassLoader`. That value is used as the parent class loader of the classloader that evals code in the REPL. Under JDK9, this breaks lookup of classes on the module path: ``` scala -J--add-modules=java.compiler -J--add-exports=jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 9-ea). Type in expressions for evaluation. Or try :help. scala> new com.sun.tools.javap.JavapTask(); java.lang.NoClassDefFoundError: com/sun/tools/javap/JavapTask at java.base/java.lang.Class.getDeclaredMethods0(Native Method) at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:2948) ``` A workaround is to use `-nobootcp`. This commit uses the system classloader as the parent in place of the null classloader to make this work in both cases. ``` qscala -J--add-modules=java.compiler -J--add-exports=jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED Welcome to Scala 2.12.2-20161208-165912-3de1c0c (Java HotSpot(TM) 64-Bit Server VM, Java 9-ea). Type in expressions for evaluation. Or try :help. scala> new com.sun.tools.javap.JavapTask(); res0: com.sun.tools.javap.JavapTask = com.sun.tools.javap.JavapTask@1f1cddf3 scala> ``` Note that the `:javap` command still requires `-nobootcp` because code in the REPL implements an interface in a the `java.compiler` module.
Diffstat (limited to 'src/repl/scala/tools/nsc')
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala6
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala6
2 files changed, 8 insertions, 4 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index 0dd96b2616..d1096fda4e 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -105,8 +105,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
class ILoopInterpreter extends IMain(settings, out) {
- override protected def parentClassLoader =
- settings.explicitParentLoader.getOrElse( classOf[ILoop].getClassLoader )
+ override protected def parentClassLoader = {
+ val replClassLoader = classOf[ILoop].getClassLoader // might be null if we're on the boot classpath
+ settings.explicitParentLoader.orElse(Option(replClassLoader)).getOrElse(ClassLoader.getSystemClassLoader)
+ }
}
/** Create a new interpreter. */
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index 99acc34811..980d12f9b8 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -255,8 +255,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
}
/** Parent classloader. Overridable. */
- protected def parentClassLoader: ClassLoader =
- settings.explicitParentLoader.getOrElse( this.getClass.getClassLoader() )
+ protected def parentClassLoader: ClassLoader = {
+ val replClassLoader = this.getClass.getClassLoader() // might be null if we're on the boot classpath
+ settings.explicitParentLoader.orElse(Option(replClassLoader)).getOrElse(ClassLoader.getSystemClassLoader)
+ }
/* A single class loader is used for all commands interpreted by this Interpreter.
It would also be possible to create a new class loader for each command