Please consider the following test program (using scala 2.9.0.1)
object test
{
def main(args:Array[String]) = {
println(ClassLoader.getSystemClassLoader.ge
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.
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.