Завершить OSGi-Framework, который работает в Tomcat

согласно http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fua_help_war.htm Я установил выделенный сервер Tomcat, на котором запущено несколько eclipse-help- плагины.

Сервер, а также помощь работают хорошо. Но теперь я понял, что остановка сервера, особенно OSGi-Framework, кажется проблемой. Мне всегда приходится убивать серверный процесс, если развернута война справки, и я считаю, что должен изящно завершить работу OSGi-Framework.

После некоторого исследования я придумал следующую реализацию ServletContextListener, которая останавливает системный пакет, вызывая bundleContext.getBundle(0).stop():

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkUtil;

public class OsgiShutdownListener implements ServletContextListener {

    /** {@inheritDoc} */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        Bundle bundle = FrameworkUtil.getBundle(org.eclipse.core.runtime.adaptor.EclipseStarter.class);
        BundleContext bundleContext = bundle.getBundleContext();
        try {
            bundleContext.getBundle(0).stop();
        } catch (BundleException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /** {@inheritDoc} */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("starting");

    }
}

Но FrameworkUtil.getBundle(org.eclipse.core.runtime.adaptor.EclipseStarter.class) всегда возвращает null, поэтому я никогда не получаю ссылку на BundleContext для остановки фреймворка.

EDIT: я изменил код на sce.getServletContext().getAttribute("osgi-bundlecontext") в contextDestroyed() и contextInitialized(), но в обоих случаях я не получаю ссылку на пакет контекст. Контекст пакета всегда нулевой.

public class OsgiShutdownListener implements ServletContextListener {

    private BundleContext bundleContext;

    /** {@inheritDoc} */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // Bundle bundle =
        // FrameworkUtil.getBundle(org.eclipse.core.runtime.adaptor.EclipseStarter.class);
        // this.bundleContext = bundle.getBundleContext();

        ServletContext context = sce.getServletContext();
        this.bundleContext = (BundleContext) context
                .getAttribute("osgi-bundlecontext");
        try {
            this.bundleContext.getBundle(0).stop();
        } catch (BundleException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /** {@inheritDoc} */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext();
        this.bundleContext = (BundleContext) context
                .getAttribute("osgi-bundlecontext");
    }
}

Как мне получить bundleContext в этой ситуации, чтобы остановить системный пакет? Или как изящно остановить OSGi-Framework при выключении сервера?


person shylynx    schedule 27.06.2013    source источник
comment
Каково значение sce.getServletContext().getServletContextName()? Мне интересно, как называется сервлет, который вызывает событие, и имеет ли сервлет структуру OSGI, прикрепленную в качестве атрибута ServletContext.   -  person Sheena Artrip    schedule 27.06.2013
comment
sce.getServletContext().getServletContextName() имеет значение null, потому что он вызывается контейнером при завершении работы.   -  person shylynx    schedule 28.06.2013


Ответы (2)


EclipseStarter является частью приложения запуска, поэтому он находится «вне» OSGi, поэтому он не загружается пакетом ClassLoader... поэтому (наконец-то!) он возвращает null из FrameworkUtil.getBundle().

Вам нужно получить контекст системного пакета... в какой-то момент в прошлом он должен был у вас быть, потому что вы успешно запустили OSGi. Так почему бы не запомнить его в поле или сделать так, чтобы он оставался видимым во время остановки?

person Neil Bartlett    schedule 27.06.2013
comment
Как получить ссылку на контекст пакета? Я пробовал sce.getServletContext().getAttribute(osgi-bundlecontext), но также получаю нулевую ссылку. (см. мое редактирование) - person shylynx; 28.06.2013
comment
Можно ли получить ссылку на контекст пакета OSGI после инициализации фреймворка с помощью EclipseStarter?? - person Jaime Hablutzel; 17.01.2014

Глядя на войну справки, вы должны иметь возможность изменить web.xml, чтобы переопределить сервлет моста.

http://grepcode.com/file/repository.grepcode.com/java/eclipse.org/3.5/org.eclipse.help/webapp/3.4.0/web-archive/help/WEB-INF/web.xml?av=f

http://eclipsesrc.appspot.com/jsrcs/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/BridgeServlet.java.html

Поскольку BridgeServlet в конечном итоге отвечает за запуск и остановку среды выполнения OSGI через FrameworkLauncher, вы должны иметь возможность переопределить BridgeServlet и получить экземпляр FrameworkLauncher. FrameworkLauncher не предоставляет стандартный «фреймворк», а вместо этого использует собственный загрузчик классов и магию отражения.

Тем не менее: BridgeServlet уже отвечает за закрытие среды OSGI. Если это не прослушивается, все, вероятно, должно останавливаться само по себе при вызове выключения tomcat.

BridgeServlet не устанавливает osgi-контекст, я полагаю, что это может быть только «белая доска», где весь сервлет содержится в контейнере OSGI, а не наоборот, как здесь.

person Sheena Artrip    schedule 28.06.2013