Класс не найден при использовании SwingUtilities.invokeLater в OSGi Bundle
(РЕДАКТИРОВАТЬ: проблема решена - подробности см. В конце)
Я хочу создать свинг JFrame
с WindowAdapter
в комплекте OSGi. Когда я делаю это с помощью SwingUtilities.invokeLater
, WindowAdapter
класс не найден. Без invokeLater
оно работает.
Что мне нужно сделать, чтобы WindowAdapter
найдено при использовании invokeLater
? Является invokeLater
не подходит в среде OSGi?
Детали:
Я запускаю экземпляр платформы Apache Felix с помощью своего собственного модуля запуска, устанавливаю пакет и запускаю его. Метод запуска моего пакета выглядит так:
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, я пытался исправить это, но пока не нашел решения. Так почему бы не сделать мой первый вопрос в Stackru:-)
РЕДАКТИРОВАТЬ:
После полчаса отладки выясняется, что проблема была полностью моей: мой код остановил среду OSGi openImpl
вызывается в EDT.
Таким образом, фреймворк Apache Felix обозначил BundleWiringImpl
Экземпляр (см. трассировку стека) как расположен. Когда мой openImpl
вызывается в EDT, BundleWiringImpl.getClassLoader
возвращается null
потому что он помечен как утилизированный. В конце концов это приводит к NPE.
(Я должен был пройти дополнительные шаги, чтобы опубликовать 50 строк моего загрузчика Felix, что могло бы сделать ошибку очевидной.)
3 ответа
Мой код остановил структуру OSGi до openImpl
вызывается в EDT.
Без invokeLater
openImpl
вызывается немедленно и до того, как мой другой код закроет среду OSGi. С invokeLater
призыв к openImpl
запланировано на более позднее время, и до того, как произойдет "позднее", мой код завершает работу OSGi.
В этом случае платформа Apache Felix пометила BundleWiringImpl
Экземпляр (см. трассировку стека) как расположен. Когда мой openImpl
вызывается в EDT, BundleWiringImpl.getClassLoader
возвращается null
потому что он помечен как утилизированный. В конце концов это приводит к NPE.
Ответ WindowAdapter
класс, который вы пытаетесь использовать, расположен в java.awt.event
, но вы не импортируете этот пакет. Изменить: это, похоже, не решило проблему (см. Комментарии), но предыстория ниже остается.
Предыстория Ваш манифест выглядит созданным вручную, я бы посоветовал вам не делать этого (вы будете делать ошибки, и вам будет сложно правильно синхронизировать манифест). Посмотрите на bndtools, если вы используете Eclipse, или просто bnd для любой другой среды.
Трассировка стека содержит некоторые проверки безопасности "ProtectionDomain,..doIntersectionPrivilege". Вы пытались отключить SecurityManager. Вы можете отключить это с помощью следующей опции VM:
-Djava.security.manager =
Смотрите также здесь: Как отключить менеджер безопасности Java?