2009-12-06 18 views
7

Một và chỉ một trong số hàng trăm người dùng của tôi gặp sự cố khi khởi động ứng dụng Java trên máy tính để bàn của tôi. Nó chỉ bắt đầu cho anh ta khoảng một phần ba thời gian. Hai phần ba khác của thời gian một NullPointerException được ném lúc khởi động:Làm cách nào để tôi có thể giải quyết một cách an toàn vấn đề về trình nạp lớp ngữ cảnh Java này?

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) 

Tôi đã theo dấu vết ngăn xếp để thấy rằng nguyên nhân là

Thread.currentThread().getContextClassLoader() 

trong JEditorPane đang trở lại null.

Googling tiết lộ rằng đây là một vấn đề lẻ tẻ, không thường xuyên và bí ẩn ảnh hưởng đến một số người.

Câu hỏi của tôi là, tôi có thể làm gì với tư cách là công việc? Điều này có thể hoạt động, nếu tôi gọi nó trước khi tạo một EditorPane:

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

Nhưng tôi thực sự không hiểu các trình nạp lớp cũng như tôi muốn (và tôi đã cố gắng hiểu chúng tốt hơn). Tôi cảm thấy rằng việc thay đổi contextClassLoader trong EDT có thể có các nhánh xấu.

Bất kỳ ý tưởng nào tôi có thể làm?

EDIT: Tôi đã có một số thư từ với ai đó hiểu rõ về Java ClassLoaders. Có vẻ như đây là một tình trạng đua ClassLoader mơ hồ. Đó là, một lỗi trong Java.

+0

Bất kỳ cơ hội nào để nâng cấp thời gian chạy Java của người dùng? –

+0

@ Tamás, đây là ứng dụng dành cho máy Mac. Tôi đã yêu cầu anh ấy thử bản cập nhật Mac Java mới nhất. –

Trả lời

4
Thread.currentThread().getContextClassLoader() 

Nếu mã trong JEditorPane.registerEditorKitForContentType không kiểm tra một giá trị trả về null trong đoạn mã trên, đây là một lỗi trong JEditorPane. Lưu ý rằng MyClass.class.getClassLoader()may also return null. Người duy nhất bạn có thể dựa vào là system ClassLoader.

Các mô hình để thiết lập bối cảnh ClassLoader cho một lời gọi thường trông giống như sau:

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

Giá trị cần được thiết lập thông qua setContextClassLoader sẽ phụ thuộc vào mục đích của mã được tiêu thụ nó và thiết kế . của khuôn khổ ClassLoader bạn đang chạy trong

trong một ứng dụng độc lập, có lẽ bạn có thể nhận được ngay với chỉ sử dụng ClassLoader này (đi qua trong một ref đến lớp hiện hành):

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

Trong khung trình cắm thêm nhạy cảm ClassLoader (máy chủ Java EE sẽ là một ví dụ chính), nó sẽ trả tiền để hiểu bản chất và cách sử dụng chương trình tải.

+0

Tôi đã thử mẫu mà bạn đưa ra để thiết lập trình nạp lớp ngữ cảnh cho một lời gọi. Tôi thích nó bởi vì nó không làm hỏng mọi thứ có thể cho các ứng dụng khác của contextclassloader. –

Các vấn đề liên quan