I have an OSGi service tracker with a filter. I noticed that there's a service that it misses ('addingService' is not called). When I use the services command in my osgi (equinox) shell, with the filter that the tracker uses, the missed service is returned.
The OSGi in practice book (preview) from Neil BARTLETT contains an interesting chapter about Tracking Services (chapter 4.8).
Did you properly set up this tracker in a plugin activator?
Here is an example from the book:
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 DbMailboxActivatorimplementsBundleActivator{
private BundleContextcontext;
private ServiceTrackertracker;
public void start(BundleContextcontext) throws Exception{
this.context=context;
tracker=newServiceTracker(context,DataSource.class
.getName(),newDSCustomizer());
tracker.open();
}
public void stop(BundleContextcontext) throws Exception{
tracker.close();
}
private class DSCustomizer implements ServiceTrackerCustomizer{
public Object addingService(ServiceReferenceref){
DataSourceds=(DataSource)context.getService(ref);
DbMailboxmbox=newDbMailbox(ds);
ServiceRegistrationregistration=context.registerService(
Mailbox.class.getName(),mbox,null);
returnregistration;
}
publicvoidmodifiedService(ServiceReferenceref,
Objectservice){
}
publicvoidremovedService(ServiceReferenceref,Objectservice){
ServiceRegistrationregistration=
(ServiceRegistration)service;
registration.unregister();
context.ungetService(ref);
}
}
}
It turns out that in Equinox, the chain to ServiceTracker#addingService goes through a check BundleContextImpl#isAssignableTo with the reference to the service. This checks if the classes of the reference are wired for the same source (jar) in the listening bundle.
In my case, trying to get the source of the class that the service implements from the reference resulted in null. The reason was that the service was actually created by a class from a third bundle (that class called a method in the registering bundle and used the return value to create the service).
Adding an import for the package in question solved this issue