Class.forName() 不适用于特定的 class
Class.forName() is not working with a particular class
我正在尝试使用 java 反射加载一堆 classes。一切似乎都工作正常(如果找不到 class,我正在处理异常)。
但是有一个特定的 class 引发了另一个异常,该异常不是通过调用 Class.forname() 而是通过内部方法抛出的,所以我什至无法捕获它。
这是我的代码:
try {
URL url = Class.forName(qualifiednameOfTheClass);
} catch (ClassNotFoundException ex) {
// ok class not found can be handled
} catch (Exception e){
// catch every other exception just to try to get the strange exception
}
所以使用这段代码一切正常,我在很多 classes 上使用它并且它正在工作(有时它发现它有时没有)。
但是有一种情况不能正常工作,我不明白为什么。如果 qualifiednameOfTheClass = sun.security.krb5.SCDynamicStoreConfig
我的代码引发异常:
Exception in thread "mythread-1" java.lang.UnsatisfiedLinkError: no
osx in java.library.path at
java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886) at
java.lang.Runtime.loadLibrary0(Runtime.java:849) at
java.lang.System.loadLibrary(System.java:1088) at
sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:67)
at
sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:47)
at java.security.AccessController.doPrivileged(Native Method) at
sun.security.krb5.SCDynamicStoreConfig.(SCDynamicStoreConfig.java:39)
at java.lang.Class.forName0(Native Method) at
java.lang.Class.forName(Class.java:190) at
com.myclass.getJARFromClassForName(JavaId.java:510)
at com.myclass.getJARUrl(Id.java:550) at
com.myclass.collectInformation(Graph.java:366)
at
com.myclass.createNode(Graph.java:166)
at com.myclass.Graph.(Graph.java:143) at
com.myclass2.run(myclass2.java:246)
at java.lang.Thread.run(Thread.java:745)
因此,正如您在错误中看到的那样,我们有一个奇怪的异常,即使像我的代码中那样使用通用捕获也无法捕获它,我不明白为什么会引发它以及它到底是什么 osx图书馆(我在 linux)
编辑:我唯一找到的是 link http://www.straub.as/java/pocketapi/index7.html 但它是德语的,所以我用 google 翻译阅读它,但我不知道我是否明白它是对的,但是说那里列出的 classes 不能用 Class.forname() 本身复制。
这是真的吗?有什么原因不能加载反射还是我做错了什么?
"Cannot be caught" 因为它是 Error
,而不是 Exception
。我建议查看 JDK 中 Throwable
的对象层次结构。
尝试将其更改为 Throwable
,您将获得更好的运气。我不知道为什么会发生错误。
这看起来像是使用本机代码的 JNI class。我不知道你在做什么,但我觉得这不是个好主意。
这不是 class 预期的加载方式,直接加载此内部 class 似乎不起作用。您需要使用标准加密 API 加载 class,以便可以按预期加载此 class,或者可能根本不加载(它可能是仅适用于 OSX)
正如您在所提供的 link 中看到的那样,此方法在某些 class 处失败。
在这些对象上调用此方法时,Java 需要首先加载其他内容,因为这是特定于平台的内容,默认情况下不提供。在您的情况下,它是 Kerberos,一种安全性 API。
正如您在其 Documentation 中所见,它会在特定路径 (java.library.path) 中搜索一些文件。因为在那里找不到它,所以它会抛出一个错误。
请注意,错误 UnsatisfiedLinkError 并不是指为 sun.security.krb5.SCDynamicStoreConfig 本身查找 class 名称.指的是在java.library.path.
提供的路径下找不到原生库
例如,这条路径本身指向 Windows,指向 C:Windows/system32/.
但是,您可能会使用 catch(Error e)
捕获此错误,请注意 Error 不是 Exception(Throwable hierarchy).
请注意,捕获 Error 通常不是一个好主意,因为您无法确定 JVM 是否可以从中恢复。
我正在尝试使用 java 反射加载一堆 classes。一切似乎都工作正常(如果找不到 class,我正在处理异常)。
但是有一个特定的 class 引发了另一个异常,该异常不是通过调用 Class.forname() 而是通过内部方法抛出的,所以我什至无法捕获它。
这是我的代码:
try {
URL url = Class.forName(qualifiednameOfTheClass);
} catch (ClassNotFoundException ex) {
// ok class not found can be handled
} catch (Exception e){
// catch every other exception just to try to get the strange exception
}
所以使用这段代码一切正常,我在很多 classes 上使用它并且它正在工作(有时它发现它有时没有)。
但是有一种情况不能正常工作,我不明白为什么。如果 qualifiednameOfTheClass = sun.security.krb5.SCDynamicStoreConfig
我的代码引发异常:
Exception in thread "mythread-1" java.lang.UnsatisfiedLinkError: no osx in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886) at java.lang.Runtime.loadLibrary0(Runtime.java:849) at java.lang.System.loadLibrary(System.java:1088) at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:67) at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:47) at java.security.AccessController.doPrivileged(Native Method) at sun.security.krb5.SCDynamicStoreConfig.(SCDynamicStoreConfig.java:39) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:190) at com.myclass.getJARFromClassForName(JavaId.java:510) at com.myclass.getJARUrl(Id.java:550) at com.myclass.collectInformation(Graph.java:366) at com.myclass.createNode(Graph.java:166) at com.myclass.Graph.(Graph.java:143) at com.myclass2.run(myclass2.java:246) at java.lang.Thread.run(Thread.java:745)
因此,正如您在错误中看到的那样,我们有一个奇怪的异常,即使像我的代码中那样使用通用捕获也无法捕获它,我不明白为什么会引发它以及它到底是什么 osx图书馆(我在 linux)
编辑:我唯一找到的是 link http://www.straub.as/java/pocketapi/index7.html 但它是德语的,所以我用 google 翻译阅读它,但我不知道我是否明白它是对的,但是说那里列出的 classes 不能用 Class.forname() 本身复制。
这是真的吗?有什么原因不能加载反射还是我做错了什么?
"Cannot be caught" 因为它是 Error
,而不是 Exception
。我建议查看 JDK 中 Throwable
的对象层次结构。
尝试将其更改为 Throwable
,您将获得更好的运气。我不知道为什么会发生错误。
这看起来像是使用本机代码的 JNI class。我不知道你在做什么,但我觉得这不是个好主意。
这不是 class 预期的加载方式,直接加载此内部 class 似乎不起作用。您需要使用标准加密 API 加载 class,以便可以按预期加载此 class,或者可能根本不加载(它可能是仅适用于 OSX)
正如您在所提供的 link 中看到的那样,此方法在某些 class 处失败。
在这些对象上调用此方法时,Java 需要首先加载其他内容,因为这是特定于平台的内容,默认情况下不提供。在您的情况下,它是 Kerberos,一种安全性 API。
正如您在其 Documentation 中所见,它会在特定路径 (java.library.path) 中搜索一些文件。因为在那里找不到它,所以它会抛出一个错误。
请注意,错误 UnsatisfiedLinkError 并不是指为 sun.security.krb5.SCDynamicStoreConfig 本身查找 class 名称.指的是在java.library.path.
提供的路径下找不到原生库
例如,这条路径本身指向 Windows,指向 C:Windows/system32/.
但是,您可能会使用 catch(Error e)
捕获此错误,请注意 Error 不是 Exception(Throwable hierarchy).
请注意,捕获 Error 通常不是一个好主意,因为您无法确定 JVM 是否可以从中恢复。