scala classloaders confusion

后端 未结 2 2021
隐瞒了意图╮
隐瞒了意图╮ 2021-02-14 15:04

Please consider the following test program (using scala 2.9.0.1)

object test
{
  def main(args:Array[String]) = {
    println(ClassLoader.getSystemClassLoader.ge         


        
相关标签:
2条回答
  • 2021-02-14 15:31

    The second null is explained by java.lang.Class#getClassLoader()

    Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader.

    So, this is why classOf[Object].getClassLoader returns null, it's loaded by the bootstrap classloader (it is in rt.jar, more specifically, it is in a jar which is in $JAVA_HOME/lib).

    The first null is harder to explain. It seems that Scala leaves the system classloader as-is, and only adds the options -cp to it's own classloader (ScalaClassLoader in scala/util/ClassLoader.scala).

    Using the following:

    object Test {
      def main(args:Array[String]) = {
        println(ClassLoader.getSystemClassLoader)
        println(this.getClass.getClassLoader)
        println(classOf[Object].getClassLoader)
      }
    }
    

    and running it with:

    $ scala -cp /temp Test
    

    we get the following output:

    sun.misc.Launcher$AppClassLoader@11b86e7
    URLClassLoader(
      file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/resources.jar
      file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/rt.jar
      file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/jsse.jar
      file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/jce.jar
      file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/charsets.jar
      file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/ext/dnsns.jar
      file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/ext/localedata.jar
      file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/ext/sunjce_provider.jar
      file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/ext/sunmscapi.jar
      file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/ext/sunpkcs11.jar
      file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/jline.jar
      file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/scala-compiler.jar
      file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/scala-dbc.jar
      file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/scala-library.jar
      file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/scala-swing.jar
      file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/scalap.jar
      file:/C:/temp/
    )
    
    null
    

    So the System classloader is left untouched, but the Scala classloader gets the items from -cp added to it.

    Moral of the story: don't use the system classloader in Scala if you want to access resources from the classpath.

    EDIT: Ok, I've investigated this a bit more, and scala.bat is executing the following command line (under pure Windows, shortened for readability)

    java.exe -Xmx256M -Xms32M -Dscala.home="xxx" -cp "libsfromscalahome" scala.tools.nsc.MainGenericRunner  -cp /temp Test
    

    So the -cp option from the command line is only being passed as an option to MainGenericRunner, not the java. I believe, from looking at the code, that under unix you can specify the -toolcp option to scala to get something included in the java classpath. Something like (totally untested):

    $ scala -toolcp /temp Test
    

    This option isn't available in scala.bat. Which means if you're working under windows, you'll have to get the resources using

    println(this.getClass.getClassLoader.getResource("toto"))
    

    I couldn't find an issue in the Scala Lang Issues, but if it's a problem for you, raise an issue and submit a fix. I'm sure they'll be thrilled :-)

    EDIT: I have raised this as issue SI 5062 -toolcp should be available on windows, in the scala.bat, and provided a pull request for it on github.

    0 讨论(0)
  • 2021-02-14 15:46

    From Wikipedia's classloader article:

    The system class loader loads code found on java.class.path, which maps to the system CLASSPATH variable.

    Not sure about the second null though. Maybe someone else can clear that up.

    0 讨论(0)
提交回复
热议问题