根据http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fua_help_war.htm我设置了一个运行多个eclipse-help-plugins的专用Tomcat服务器。
服务器以及帮助已启动且运行良好。但现在我意识到停止服务器尤其是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来停止框架。
修改 我在contextDestroyed()和contextInitialized()中将代码更改为sce.getServletContext()。getAttribute(“osgi-bundlecontext”),但在这两种情况下,我都没有引用bundle上下文。 Bundle上下文始终为null。
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?
答案 0 :(得分:1)
EclipseStarter
是启动器应用程序的一部分,因此它在OSGi“外部”,因此它不会被捆绑ClassLoader加载...因此(最后!)它从FrameworkUtil.getBundle()返回null
你需要掌握系统包上下文...在过去的某个时刻你必须拥有这个,因为你成功启动了OSGi。那么为什么不在田野中记住它,或者在停止时间仍然可以看到它?
答案 1 :(得分:0)
查看帮助战争,您应该能够修改web.xml以覆盖桥接servlet。
由于BridgeServlet最终负责通过FrameworkLauncher启动和停止OSGI运行时,因此您应该能够覆盖BridgeServlet并获取FrameworkLauncher实例。 FrameworkLauncher没有提供标准的框架'而是将它包裹在它自己的类加载器和反射魔法周围。
那就是说:BridgeServlet已经负责关闭OSGI框架。除非它被窃听,否则在调用tomcat shutdown时可能会自行停止。
BridgeServlet没有设置osgi-context,我相信这可能只是一个" whiteboard"事情,整个servlet包含在OSGI容器中,而不是像这里那样。