Skip to content

Runtime reflection of classes in the empty package broken under Java 9 #304

Closed
@retronym

Description

@retronym
⚡ cat /tmp/Test.java; javac -d /tmp/out /tmp/Test.java && (java_use 9; scala -nobootcp -J-Dscala.ext.dirs=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/scala-ext)
public class Test {
}

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> val cl = new java.net.URLClassLoader(Array(new java.io.File("/tmp/out").toURI.toURL), getClass.getClassLoader); val cls = cl.loadClass("Test"); val instance = cls.getConstructor().newInstance(); val mirror = reflect.runtime.universe.runtimeMirror(cl); val sym = mirror.reflect(instance)(reflect.ClassTag(cls)).symbol
java.lang.AssertionError: assertion failed: no symbol could be loaded from class Test in package with name Test and classloader java.net.URLClassLoader@199806aa
  at scala.reflect.runtime.JavaMirrors$JavaMirror.classToScala1(JavaMirrors.scala:1022)
  at scala.reflect.runtime.JavaMirrors$JavaMirror.$anonfun$classToScala$1(JavaMirrors.scala:980)
  at scala.reflect.runtime.JavaMirrors$JavaMirror.$anonfun$toScala$1(JavaMirrors.scala:97)
  at scala.reflect.runtime.TwoWayCaches$TwoWayCache.$anonfun$toScala$1(TwoWayCaches.scala:38)
  at scala.reflect.runtime.TwoWayCaches$TwoWayCache.toScala(TwoWayCaches.scala:34)
  at scala.reflect.runtime.JavaMirrors$JavaMirror.toScala(JavaMirrors.scala:95)
  at scala.reflect.runtime.JavaMirrors$JavaMirror.classToScala(JavaMirrors.scala:980)
  at scala.reflect.runtime.JavaMirrors$JavaMirror.classSymbol(JavaMirrors.scala:196)
  at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.symbol(JavaMirrors.scala:234)
  at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.symbol(JavaMirrors.scala:233)
  ... 29 elided

By contrast, if we place Test in some package, p1:

⚡ cat /tmp/Test.java; javac -d /tmp/out /tmp/Test.java && (java_use 9; scala -nobootcp -J-Dscala.ext.dirs=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/scala-ext)
package p1;

public class Test {
}

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> val cl = new java.net.URLClassLoader(Array(new java.io.File("/tmp/out").toURI.toURL), getClass.getClassLoader); val cls = cl.loadClass("p1.Test"); val instance = cls.getConstructor().newInstance(); val mirror = reflect.runtime.universe.runtimeMirror(cl); val sym = mirror.reflect(instance)(reflect.ClassTag(cls)).symbol
cl: java.net.URLClassLoader = java.net.URLClassLoader@1a8e44fe
cls: Class[_] = class p1.Test
instance: Any = p1.Test@5d8e4fa8
mirror: reflect.runtime.universe.Mirror = JavaMirror with java.net.URLClassLoader@1a8e44fe of type class java.net.URLClassLoader with classpath [file:/tmp/out/] and parent being scala.tools.nsc.interpreter.IMain$TranslatingClassLoader@7b9088f2 of type class scala.tools.nsc.interpreter.IMain$TranslatingClassLoader with classpath [(memory)] and parent being scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@3acc3ee of type class scala.reflect.internal.util.ScalaClassLoader$URLClassLoader with classpath [jrt:/modules/java.activation,jrt:/modules/java.annotations.common,jrt:/modules/java.base,jrt:/modules/java.compact1,jrt:/modules/java.compact2,jrt:/modules...

The same problem exists in a more vanilla classloader setup:

cat /tmp/Test.java; javac -d /tmp/out /tmp/Test.java && (java_use 9; scala -classpath /tmp/out -nobootcp -J-Dscala.ext.dirs=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/scala-ext)
public class Test {
}

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> val test = new Test()
test: Test = Test@6aad919c

scala> val mirror = reflect.runtime.universe.runtimeMirror(test.getClass.getClassLoader)
mirror: reflect.runtime.universe.Mirror = JavaMirror with scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@3b57f915 of type class scala.reflect.internal.util.ScalaClassLoader$URLClassLoader with classpath [jrt:/modules/java.activation,jrt:/modules/java.annotations.common,jrt:/modules/java.base,jrt:/modules/java.compact1,jrt:/modules/java.compact2,jrt:/modules/java.compact3,jrt:/modules/java.compiler,jrt:/modules/java.corba,jrt:/modules/java.datatransfer,jrt:/modules/java.desktop,jrt:/modules/java.httpclient,jrt:/modules/java.instrument,jrt:/modules/java.jnlp,jrt:/modules/java.logging,jrt:/modules/java.management,jrt:/modules/java.naming,jrt:/modules/java.prefs,jrt:/modules/java.rmi,jrt:/modules/java.scripting,jrt:/modules/java.se,jrt:/modules/java.se.ee,jrt:/modules/java.secu...
scala> val sym = mirror.reflect(test).symbol
java.lang.AssertionError: assertion failed: no symbol could be loaded from class Test in package with name Test and classloader scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@3b57f915
  at scala.reflect.runtime.JavaMirrors$JavaMirror.classToScala1(JavaMirrors.scala:1022)
  at scala.reflect.runtime.JavaMirrors$JavaMirror.$anonfun$classToScala$1(JavaMirrors.scala:980)
  at scala.reflect.runtime.JavaMirrors$JavaMirror.$anonfun$toScala$1(JavaMirrors.scala:97)
  at scala.reflect.runtime.TwoWayCaches$TwoWayCache.$anonfun$toScala$1(TwoWayCaches.scala:38)
  at scala.reflect.runtime.TwoWayCaches$TwoWayCache.toScala(TwoWayCaches.scala:34)
  at scala.reflect.runtime.JavaMirrors$JavaMirror.toScala(JavaMirrors.scala:95)
  at scala.reflect.runtime.JavaMirrors$JavaMirror.classToScala(JavaMirrors.scala:980)
  at scala.reflect.runtime.JavaMirrors$JavaMirror.classSymbol(JavaMirrors.scala:196)
  at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.symbol(JavaMirrors.scala:234)
  at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.symbol(JavaMirrors.scala:233)
  ... 29 elided

This issue prevents startup of SBT under Java 9 (even after using the patched SBT in sbt/sbt#2951 with the instructions) if the build definitition contains an AutoPlugin with an autoimport module, like this one in scala/scala.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions