我有一个带过滤器的OSGi服务跟踪器。我注意到它有一个错过的服务(不调用'addingService')。当我在我的osgi(equinox)shell中使用services命令时,使用跟踪器使用的过滤器,将返回错过的服务。
答案 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);
}
}
}