OSGi后台线程失败

时间:2013-01-09 21:48:05

标签: java multithreading osgi

BundleActivator运行后台线程并且后台线程有不可恢复的错误时应该怎么做?

public class Activator implements BundleActivator
{
   private Thread t;
   @Override
   public void start(BundleContext context) throws Exception
   {
      t = new Thread(new Runnable(){
            @Override
             public void run(){
                while (!Thread.interrupted()){
                  // do something which may throw a runtime exception
               }
            }
         });
      t.start();
   }
   @Override void stop(BundleContext context) throws Exception
   {
      t.interrupt();
      t.join();
   }
}

通过这个例子,我如何通知OSGi框架该线程已经死亡并且bundle被有效地停止并且没有运行?

4 个答案:

答案 0 :(得分:2)

看看Peter Kriens如何在this article中执行类似的行动。你需要做的就是在他的catch块中调用激活器上的stop,而不是执行printStackTrace。

答案 1 :(得分:2)

可能最好的办法就是记录错误,最好是OSGi Log Service。然后,管理员可以检测捆绑包的问题并决定要执行的操作。您应该将其实现为声明性服务组件而不是BundleActivator,因为这样可以更轻松地访问日志服务,并且您还可以在捆绑包中拥有多个这样的内容。

我认为捆绑包不应该试图阻止自己。这使得捆绑包处于一种奇怪的状态......它已停止但仍然运行代码...即调用stop()的代码。这可能只是短暂的一段时间,但感觉不对。

处于ACTIVE状态的捆绑包不一定必须一直“做某事”,它只有潜力来“做某事”。事情失败的事实不应该真正影响捆绑的外部状态。

答案 2 :(得分:1)

据我所知,OSGi无法在这种特殊情况下直接帮助您。我通常依靠uncaught exception handlers来获得线程崩溃的通知,或者我实现某种形式的SW看门狗。

关键在于,即使其中一个线程在一段时间后崩溃,生成多个线程并成功完成其start方法的bundle仍保持ACTIVE。

答案 3 :(得分:1)

尼尔(照例)非常正确。捆绑应该永远不会停止,因为它会干扰管理代理。启动/停止是从此管理代理程序到捆绑包的消息,表示它应该处于活动状态。如果捆绑包无法履行其职责,您应该记录消息,等待一段时间(越来越长)并重试。

日志是通知的地方,停止捆绑正在严重混合水平。