在OSGi Bundle中使用SwingUtilities.invokeLater时找不到类

时间:2012-05-15 14:20:51

标签: java swing osgi event-dispatch-thread invokelater

(编辑:问题解决了 - 最后看详情)

我想在OSGi Bundle中创建一个带JFrame的Swing WindowAdapter。当我使用SwingUtilities.invokeLater执行此操作时,找不到WindowAdapter类。如果没有invokeLater则可行。

在使用WindowAdapter时,我需要做什么才能找到invokeLater? 在OSGi环境中invokeLater是否不合适?

细节:

我使用自定义启动器启动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实例(请参阅堆栈跟踪)标记为已处理。在EDT中调用openImpl后,BundleWiringImpl.getClassLoader会返回null,因为它已标记为已处理。最终这导致了NPE。 (我应该采取额外的步骤来发布我的Felix加载器的50行,这可能会使错误显而易见。)

3 个答案:

答案 0 :(得分:0)

答案您尝试使用的WindowAdapter类位于java.awt.event,但您不导入该包。编辑:这似乎没有解决问题(见评论),但下面的背景故事仍然存在。

背景故事你的清单看起来是手工制作的,我建议你不要这样做(你会犯错误,让清单很好地保持同步是一件麻烦事)。如果您正在使用Eclipse,请查看bndtools,或者对于任何其他环境,请查看bnd

答案 1 :(得分:0)

我的代码在EDT中调用openImpl之前停止了OSGi框架。

在我的其他代码关闭OSGi框架之前立即调用invokeLater openImpl。使用invokeLater调用openImpl的时间安排在稍后,在“稍后”发生之前,我的代码会关闭OSGi框架。

在这种情况下,Apache Felix框架将BundleWiringImpl实例(请参阅堆栈跟踪)标记为已处置。在EDT中调用openImpl后,BundleWiringImpl.getClassLoader会返回null,因为它已标记为已处理。最终这会导致NPE。

答案 2 :(得分:-1)

stacktrace包含一些安全检查“ProtectionDomain,.. doIntersectionPrivilege”。 您是否尝试禁用SecurityManager。您可以使用以下VM选项禁用:

-Djava.security.manager =

另见: How to disable Java security manager?