Ste*_*eod 7 java classloader contextclassloader
我的数百名用户中只有一个在启动Java桌面应用程序时遇到问题.只有三分之一的时间才开始.另外三分之二的时间在启动时抛出NullPointerException:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:394)
at javax.swing.JEditorPane.registerEditorKitForContentType(JEditorPane.java:1327)
at javax.swing.JEditorPane.registerEditorKitForContentType(JEditorPane.java:1309)
at javax.swing.JEditorPane.loadDefaultKitsIfNecessary(JEditorPane.java:1387)
at javax.swing.JEditorPane.getKitTypeRegistry(JEditorPane.java:1344)
at javax.swing.JEditorPane.getEditorKitClassNameForContentType(JEditorPane.java:1340)
at javax.swing.JTextPane.<init>(JTextPane.java:76)
at myapp.Launcher$1.run(Launcher.java:13)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:633)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Run Code Online (Sandbox Code Playgroud)
我已经按照堆栈跟踪找到原因
Thread.currentThread().getContextClassLoader()
Run Code Online (Sandbox Code Playgroud)
在JEditorPane中返回null.
谷歌搜索显示,这是一个零星的,非常罕见的,神秘的问题,影响了一些人.
我的问题是,作为一种解决办法,我能做些什么?如果我在创建EditorPane之前调用它,这可能会有效:
Thread.currentThread().setContextClassLoader(MyClass.class.getClassLoader());
Run Code Online (Sandbox Code Playgroud)
但我并不像我想的那样真正理解类加载器(并且我试图更好地理解它们).我觉得改变EDT中的contextClassLoader可能会产生不良影响.
任何想法我能做什么?
编辑:我与熟悉Java ClassLoaders的人有一些通信.这似乎是一个模糊的ClassLoader竞争条件.也就是说,Java中的一个错误.
Thread.currentThread().getContextClassLoader()
Run Code Online (Sandbox Code Playgroud)
如果 中的代码JEditorPane.registerEditorKitForContentType没有检查上述代码中的 null 返回值,则这是 中的错误JEditorPane。请注意,MyClass.class.getClassLoader() 也可能返回 null。您唯一可以依赖的就是系统 ClassLoader。
设置调用上下文的模式ClassLoader通常如下所示:
Thread thread = Thread.currentThread();
ClassLoader old = thread.getContextClassLoader();
thread.setContextClassLoader(fooClassLoader);
try {
// do call that depends on context ClassLoader
} finally {
thread.setContextClassLoader(old);
}
Run Code Online (Sandbox Code Playgroud)
应通过设置的值setContextClassLoader取决于使用它的代码的意图以及ClassLoader您正在运行的框架的设计。
在独立的应用程序中,您可能可以只使用它ClassLoader(将引用传递给当前类):
private ClassLoader findClassLoaderForContext(Class<?> c) {
ClassLoader context = Thread.currentThread().getContextClassLoader();
ClassLoader me = c.getClassLoader();
ClassLoader system = ClassLoader.getSystemClassLoader();
return (context == null) ? (me == null) ? system : me : context;
}
Run Code Online (Sandbox Code Playgroud)
在类加载器敏感的插件框架中(Java EE 服务器就是一个典型的例子),了解加载方案的性质和用法是值得的。
| 归档时间: |
|
| 查看次数: |
2242 次 |
| 最近记录: |