Drugi zerowy jest wyjaśnione przez java.lang.Class#getClassLoader()
Zwraca ładującego klasy do klasy. Niektóre implementacje mogą używać null do reprezentowania programu ładującego klasy bootstrap. Ta metoda zwróci wartość null w takich implementacjach, jeśli ta klasa została załadowana przez moduł ładowania klasy bootstrap .
Tak, to dlaczego classOf[Object].getClassLoader
zwraca NULL, to ładowany przez classloader bootstrap (jest w rt.jar, bardziej konkretnie, to w słoiku, który jest w $ JAVA_HOME/lib).
Pierwszy zerowy jest trudniejszy do wyjaśnienia. Wygląda na to, że Scala opuszcza systemowy program ładujący klasy tak, jak jest, i dodaje tylko opcje -cp do swojego programu ładującego klasy (ScalaClassLoader w scala/util/ClassLoader.scala).
stosując następujący:
object Test {
def main(args:Array[String]) = {
println(ClassLoader.getSystemClassLoader)
println(this.getClass.getClassLoader)
println(classOf[Object].getClassLoader)
}
}
i uruchomienie go z:
$ scala -cp /temp Test
otrzymujemy następujący wynik:
[email protected]
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
Więc classloader systemu pozostało nietknięte, ale Scala classloader pobiera elementy z -cp dodane do niego.
Morał z opowieści: nie używaj programu ładującego klasy systemu w Scali, jeśli chcesz uzyskać dostęp do zasobów ze ścieżki klasy.
EDYCJA: Ok, zbadałem to nieco więcej i scala.bat realizuje następujące polecenie (pod czystej szyby, skrócony dla czytelności)
java.exe -Xmx256M -Xms32M -Dscala.home="xxx" -cp "libsfromscalahome" scala.tools.nsc.MainGenericRunner -cp /temp Test
Więc opcja cp z linii poleceń jest tylko były przekazywane jako opcja do MainGenericRunner, nie Java. Sądzę, że patrząc na kod, pod unixem można określić opcję -toolcp na scala, aby uzyskać element zawarty w ścieżce klas java. Coś jak (całkowicie niesprawdzone):
$ scala -toolcp /temp Test
Ta opcja nie jest dostępna w scala.bat. Co oznacza, że jeśli pracujesz w systemie Windows, musisz dostać zasobów przy użyciu
println(this.getClass.getClassLoader.getResource("toto"))
nie mogłem znaleźć problem w Scala Lang Issues, ale jeśli jest to dla Ciebie problem, podniesienie problemu i przedstawienia naprawa. Jestem pewien, że będą zachwyceni :-)
EDYCJA: Podniosłem to jako wydanie SI 5062 -toolcp should be available on windows, in the scala.bat, i podałem żądanie pobrania go na github.