Класс не найден при использовании 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.

Без invokeLateropenImpl вызывается немедленно и до того, как мой другой код закроет среду 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?

Другие вопросы по тегам