2012-05-15 57 views
0

未找到(编辑:问题就解决了 - 请参照最后的细节)类在OSGi的使用SwingUtilities.invokeLater时捆绑

我想在一个OSGi包来创建Swing JFrameWindowAdapter。当我使用SwingUtilities.invokeLater执行此操作时,找不到WindowAdapter类。没有invokeLater它的作品。

我该怎么做才能在使用invokeLater时发现WindowAdapter? 在OSGi环境中是不是invokeLater不合适?

细节:

我开始与我的自定义启动,安装软件包并启动Apache的菲利克斯框架实例。我的包的启动方法是这样的:

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上:-)

编辑:事实证明,这个问题完全是我的

调试半小时后: 我的代码停止openImpl之前OSGi框架被称为EDT。

因此Apache Felix框架将BundleWiringImpl实例(请参阅堆栈跟踪)标记为已处置。当我的openImpl在EDT中被调用时,BundleWiringImpl.getClassLoader返回null,因为它被标记为已处理。最终这导致NPE。 (我应该去张贴50行我菲利克斯装载机的可能做出错误明显的额外步骤。)

+0

如果代码是准确的,那么行MyFrame.java:24是“new JFrame()”,所以无法加载的类大概是javax.swing.JFrame。我真的被这个难住了。我想了很长一段时间...... –

+0

如果我有写jar版本,那么BundleWiringImpl的第1432行是这样的:http://grepcode.com/file/repo1.maven.org/maven2/org。 apache.felix/org.apache.felix.framework/4.0.2/org/apache/felix/framework/BundleWiringImpl.java?av = h#1432,这意味着getClassLoader()返回null或m_revision为null。 –

回答

0

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

没有invokeLateropenImpl被立即调用,在我的其他代码关闭OSGi框架之前。随着invokeLater调用openImpl计划在晚些时候,在“稍后”发生之前,我的代码关闭了OSGi框架。

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

+0

(发现自己的回答是可以接受的,并决定将我的问题从未答复的池中移出...) –

0

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

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

+0

当我将'java.awt.event'添加到Import-Package时,得到:'org.osgi.framework.BundleException:不允许导入java。*包:java.awt.event'。 –

+0

哦,好点,我完全错过了。尽管如此,我仍坚持认为你不应该手动建立清单,而是让一个工具去做。我会为此更新我的答案。 –

+0

我尝试了bndtools,看它是否有一些我的新手理解不包含的魔法。但是相关的MANIFEST条目是相同的,并且异常仍然被抛出。与此同时,我找到了一篇有趣的文章来解决这个问题。当我在几个小时内获得一点空闲时间并发布更新时,我会阅读它。 –

-1

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

-Djava.security。经理=

也看这里: How to disable Java security manager?

+0

我用'-Djava.security.manager -Djava.security.policy = java.policy'开始了我的应用程序,并把'grant {permission java.security.AllPermission; };在策略文件中。仍然是相同的堆栈跟踪。没有策略文件参数,我得到'java.security.AccessControlException:access denied(“java.lang.RuntimePermission”“createSecurityManager”)'。嗯。 –