Consider following scala script:
import scala.reflect.internal.util.ScalaClassLoader
object Test {
def main(args: Array[String]) {
val classloaderForScalaLibrary = classOf[ScalaClassLoader.URLClassLoader].getClassLoader
println(classloaderForScalaLibrary)
val classloaderForTestClass = this.getClass.getClassLoader
println(classloaderForTestClass)
this.getClass.getClassLoader.asInstanceOf[ScalaClassLoader.URLClassLoader]
}
}
The output is:
scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@71c8becc
scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@71c8becc
java.lang.ClassCastException: scala.reflect.internal.util.ScalaClassLoader$URLClassLoader cannot be cast to scala.reflect.internal.util.ScalaClassLoader$URLClassLoader
at Main$.main(Test.scala:8)
at Main.main(Test.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at scala.reflect.internal.util.ScalaClassLoader.$anonfun$run$2(ScalaClassLoader.scala:98)
at scala.reflect.internal.util.ScalaClassLoader.asContext(ScalaClassLoader.scala:32)
...
Why can't I cast ScalaClassLoader$URLClassLoader
to ScalaClassLoader$URLClassLoader
?
Edit:
On running:
scala -J-verbose:class Test.scala | grep ScalaClassLoader
The output is:
[Loaded scala.reflect.internal.util.ScalaClassLoader$URLClassLoader from file:/C:/Development/Software/scala-2.12.2/lib/scala-reflect.jar]
...
...
[Loaded scala.reflect.internal.util.ScalaClassLoader$URLClassLoader from file:/C:/DEVELO~1/Software/SCALA-~1.2/lib/scala-reflect.jar]
So there is definitely some shady class loading going on. Now trying to investigate why this is so
this.getClass.getClassLoader
) issun.misc.Launcher$AppClassLoader@68de145
and I can assert as instance ofURLClassLoader
(this.getClass.getClassLoader.asInstanceOf[URLClassLoader]
). What aboutnew ScalaClassLoader.URLClassLoader(Seq(), null).asInstanceOf[ScalaClassLoader.URLClassLoader]
?? – Johnsenscala Test.scala
it works for me, when I run it fromsbt
orIntelliJ
I get aClassCastException
with a different class loader. – Seftonscalac
gives me proper result and casting is working fine.scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@e6ea0c6
. I'm using scala2.12.2
– JohnsenClassCastExceptions
for the same class can happen when the class was loaded twice by different classloaders. In that case the classes are not considered equal by the JVM even though the have the same name. – Seftonscala.reflect.internal.util.ScalaClassLoader$URLClassLoader
not be loaded only once. Curios who can load it twice? – Johnsenscala 2.12.2
on MacOS. – Johnsenthis.getClass.getClassLoader.getParent
tell who is the rootClassLoader
? To me onscalac
givesnull
which means itself is a Parent Loader. But IDE gives mesun.misc.Launcher$ExtClassLoader@5034c75a
. – Johnsenscala Test.scala -J-verbose:class | grep ScalaClassLoader
which gives all theScalaClassLoader
being loaded. for me there is one loading only[Loaded scala.reflect.internal.util.ScalaClassLoader$URLClassLoader from /usr/local/scala-2.12.2/lib/scala-reflect.jar
– Johnsen-J-verbose:class
flag. It did reveal the double class loading. Now I need to figure out why – Schwartz