tags:

views:

121

answers:

2

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.

A: 

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);
    }
  }
}
VonC
A: 

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

IttayD
Registering objects as services that were created by another bundle does not really seem a reasonable thing do do, does it? I mean, this will badly interfere with OSGi's notion of active services of a bundle etc. IMHO you should have received an exception when attempting to register the "wrong" object though.
Robert Klemme