【发布时间】:2012-05-15 14:20:51
【问题描述】:
(编辑:问题已解决 - 详情见最后)
我想在 OSGi Bundle 中创建一个带有 WindowAdapter 的 Swing JFrame。当我使用SwingUtilities.invokeLater 执行此操作时,找不到WindowAdapter 类。没有invokeLater 它可以工作。
我需要做什么才能在使用invokeLater 时找到WindowAdapter?
invokeLater 在 OSGi 环境中是否不合适?
详情:
我使用自定义启动器启动 Apache Felix 框架实例,安装捆绑包并启动它。我的 bundle 的 start 方法是这样的:
public void start(BundleContext arg0) throws Exception {
myFrame = new MyFrame();
myFrame.open();
}
这是 MyFrame 类:
public class MyFrame {
JFrame mainFrame;
public void open() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
openImpl();
}
});
// If called like this it works:
// openImpl();
}
public void openImpl() {
mainFrame = new JFrame("Title");
mainFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
WindowAdapter wa = new WindowAdapter() {
};
mainFrame.addWindowListener(wa);
mainFrame.setSize(800, 600);
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
}
}
这是我的捆绑清单:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.7.0_03-b05 (Oracle Corporation)
Built-By: Rainer Schwarze
Bundle-Name: DummyBdl
Bundle-Description: Dummy Bundle
Bundle-Vendor: admaDIC
Bundle-Version: 0.0.1
Bundle-Activator: dummybdl.Activator
Import-Package: org.osgi.framework, javax.swing
Export-Package: dummybdl.api
Export-Service: dummybdl.Provider
这是我得到的堆栈跟踪:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1432)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at dummybdl.MyFrame.openImpl(MyFrame.java:24)
at dummybdl.MyFrame$1.run(MyFrame.java:16)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
作为一个 OSGi 新手,我尝试了几件事来修复它,但到目前为止找不到解决方案。那么为什么不在 StackOverflow 上提出我的第一个问题 :-)
编辑:
调试了半个小时发现问题完全是我的问题:
我的代码在 EDT 中调用 openImpl 之前停止了 OSGi 框架。
因此,Apache Felix 框架将 BundleWiringImpl 实例(参见堆栈跟踪)标记为已释放。当我的 openImpl 在 EDT 中被调用时,BundleWiringImpl.getClassLoader 返回 null,因为它被标记为已处置。最终这会导致 NPE。
(我应该采取额外的步骤来发布我的 Felix 加载程序的 50 行,这可能会使错误变得明显。)
【问题讨论】:
-
如果您的代码是准确的,那么 MyFrame.java:24 行是“new JFrame()”,因此无法加载的类可能是 javax.swing.JFrame。我真的被这件事难住了。想了很久……
-
如果我有 write jar 版本,那么 BundleWiringImpl 的第 1432 行是这样的:grepcode.com/file/repo1.maven.org/maven2/org.apache.felix/…,这意味着 getClassLoader() 返回 null 或 m_revision 为 null。
标签: java swing osgi event-dispatch-thread invokelater