How can I safely resolve this issue of the Java classloader Java?

The same one of my hundreds of users had a problem launching an application for Java applications. It only starts for him about a third of the time. The other two-thirds of the time that a NullPointerException is thrown at startup:

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) 

I followed the stack trace, finding that the reason is because

 Thread.currentThread().getContextClassLoader() 

in JEditorPane returns null.

Googling shows that this is a sporadic, very rare and mysterious problem that affects several people.

My question is what can I do to work? This might work if I call it before creating EditorPane:

 Thread.currentThread().setContextClassLoader(MyClass.class.getClassLoader()); 

But I really do not understand class loaders, and also wanted to (and I tried to understand them better). I feel that changing contextClassLoader in EDT can have bad consequences.

Any ideas what I can do?

EDIT: I had a correspondence with a person who is well versed in Java ClassLoaders. It seems that this is an incomprehensible condition for the race of ClassLoader. That is, a bug in Java.

+7
java classloader contextclassloader
source share
1 answer
 Thread.currentThread().getContextClassLoader() 

If the code in JEditorPane.registerEditorKitForContentType does not check for a null return value in the above code, this is an error in JEditorPane . Note that MyClass.class.getClassLoader() can also return null . The only thing you can rely on is system ClassLoader .

The template for setting the ClassLoader context for the call usually looks something like this:

 Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); thread.setContextClassLoader(fooClassLoader); try { // do call that depends on context ClassLoader } finally { thread.setContextClassLoader(old); } 

The value that must be set through setContextClassLoader will depend on the intent of the code that consumes it and the structure of the ClassLoader frame in which you work.

In a standalone application, you can probably get away just using this ClassLoader (passing the ref link to the current class):

 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; } 

In a plugin sensitive to ClassLoader (for example, the Java EE server will be a prime example), it will pay to understand the nature and use of the loading scheme.

+4
source share

All Articles