Why can't SBT's thread context classloader load JDK classfiles as resources?

Viewed 524
lihaoyi test$ tree
.
└── Foo.scala

0 directories, 1 file

lihaoyi test$ cat Foo.scala
object Main{
  def main(args: Array[String]): Unit = {
    println(getClass.getClassLoader.getResourceAsStream("java/lang/String.class"))
    println(getClass.getClassLoader.getClass)
    println(Thread.currentThread().getContextClassLoader.getResourceAsStream("java/lang/String.class"))
    println(Thread.currentThread().getContextClassLoader.getClass)
  }
}

lihaoyi test$ sbt run
[info] Loading global plugins from /Users/lihaoyi/.sbt/0.13/plugins
[info] Set current project to test (in build file:/Users/lihaoyi/Dropbox/Workspace/test/)
[info] Updating {file:/Users/lihaoyi/Dropbox/Workspace/test/}test...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/lihaoyi/Dropbox/Workspace/test/target/scala-2.10/classes...
[info] Running Main
sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@18e38ff2
class sbt.classpath.ClasspathUtilities$$anon$1
null
class sbt.classpath.ClasspathFilter
[success] Total time: 2 s, completed 29 May, 2017 4:14:11 PM

lihaoyi test$

Here, we can see that the getClass.getClassLoader and the Thread.currentThread.getContextClassLoader are returning different values. What's more, the Thread.currentThread.getContextClassLoader seems to be refusing to load java/lang/String.class, while the other can.

Notably, when I run the jar file using an external tool like scalac/scala, or java, both classloaders are able to load the classfile as a resource

lihaoyi test$ scalac Foo.scala

lihaoyi test$ scala Main
sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@1b28cdfa
class scala.reflect.internal.util.ScalaClassLoader$URLClassLoader
sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@7229724f
class scala.reflect.internal.util.ScalaClassLoader$URLClassLoader

I would expect SBT to behave similarly: to have the Main.getClass.getClassLoader and the Thread.currentThread().getContextClassLoader both be able to load java/lang/String.class as a resource. What gives?

2 Answers
Related