scala - Class.forName(...) 与 Class.forName(...) Thread.currentThread.getContextClassLoader.loadClass(...) 行为

标签 scala classloader

我想从 Scala REPL 动态加载由 Guava 库定义的 Class 对象。但是,我观察到不同的行为,具体取决于我检索 Class 定义的方式:

scala> :cp guava-10.0.1.jar
Added '/Users/xxx/guava-10.0.1.jar'.  Your new classpath is:
"/Users/rouvoy/Development/tools/axis/default/lib:/Users/xxx/guava-10.0.1.jar"

scala> Class.forName("com.google.common.base.Ascii")
res0: java.lang.Class[_] = class com.google.common.base.Ascii

Class.forName(...) 方法工作正常,并设法检索 Class 对象,但我想了解为什么,当使用 ContextClassLoader,我无法找到类定义——尽管它在 Java 中工作得很好?

scala> Thread.currentThread.getContextClassLoader.loadClass("com.google.common.base.Ascii")
java.lang.ClassNotFoundException: com.google.common.base.Ascii
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at .<init>(<console>:8)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:680)

scala> Class.forName("com.google.common.base.Ascii",true,Thread.currentThread.getContextClassLoader)
java.lang.ClassNotFoundException: com.google.common.base.Ascii
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at .<init>(<console>:8)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:680)

最佳答案

Scala 和 Java 之间的类加载略有不同。当您为 scala 可执行文件(脚本或 .bat)指定 -cp 时,它不会添加到基类路径中,而只会添加到 Scala 类加载器中。我怀疑当您指定 :cp 时,REPL 也是如此。

要真正向 java 类路径添加某些内容,请使用 scala 或 scalac 的 -toolcp 选项。

查看我的回答:scala classloaders confusion .

关于scala - Class.forName(...) 与 Class.forName(...) Thread.currentThread.getContextClassLoader.loadClass(...) 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7937892/

相关文章:

java - 舍入前可以检测到 "java.lang.ArithmeticException: Rounding necessary"吗?

oop - 2D 和 3D 向量的正确类层次结构

斯卡拉 2.12.4 : Cannot access protected static Java method from another package anymore

scala - 使用 Scala Akka 框架来阻止 CLI 调用

java - WebSphere 中的 XML.loadString 抛出 java.lang.VerifyError

java - Db4o API 在 NetBeans 中看不到动态加载的类?

java - JProfiler - "Run GC"按钮与堆快照的 "Perform full GC in heap snapshot"选项

java - 从 Scala 到 Java 1.8

java - 启用安全管理器时 URLClassLoader 发出的 ClassNotFoundException

java - 实现过滤类加载器