ServiceTracker有时会错过服务?

时间:2009-10-06 06:19:29

标签: java osgi

我有一个带过滤器的OSGi服务跟踪器。我注意到它有一个错过的服务(不调用'addingService')。当我在我的osgi(equinox)shell中使用services命令时,使用跟踪器使用的过滤器,将返回错过的服务。

2 个答案:

答案 0 :(得分:2)

事实证明,在Equinox中,ServiceTracker#addingService的链接经过检查BundleContextImpl#isAssignableTo并引用该服务。这将检查引用的类是否针对侦听包中的相同源(jar)进行连接。

在我的情况下,尝试从引用获取服务实现的类的源导致null。原因是该服务实际上是由第三个包中的类创建的(该类称为注册包中的方法,并使用返回值来创建服务)。

为相关包添加导入解决了此问题

答案 1 :(得分:1)

来自OSGi in practice book (preview)Neil BARTLETT包含有关跟踪服务的有趣章节(第4.8章)。

您是否在插件激活器中正确设置了此跟踪器? 以下是本书的一个例子:

package org.osgi.book.reader.dbmailbox;

import javax.sql.DataSource;
import org.osgi.book.reader.api.Mailbox;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

public class DbMailboxActivator implements BundleActivator{

private BundleContext context;
private ServiceTracker tracker;

public void start(BundleContext context) throws Exception{
  this.context=context;
  tracker=new ServiceTracker(context,DataSource.class.getName(),new DSCustomizer());
  tracker.open();
}

public void stop(BundleContext context) throws Exception{
  tracker.close();
}

private class DSCustomizer implements ServiceTrackerCustomizer{
  public Object addingService(ServiceReference ref){
    DataSource ds = (DataSource)context.getService(ref);
    DbMailbox mbox=new DbMailbox(ds);

    ServiceRegistration registration = context.registerService(Mailbox.class.getName(),mbox,null);
      return registration;
  }

    public void modifiedService(ServiceReference ref, Object service){
    }

    public void removedService(ServiceReference ref,Object service){
      ServiceRegistration registration = (ServiceRegistration)service;
      registration.unregister();
      context.ungetService(ref);
    }
  }
}