It sounds likely that you are picking up an incompatible service.
Check whether you open the ServiceTracker with "open(true)" or
"open(false)"... or just "open()", which is equivalent to
"open(false)".

FYI the open(false)/open() variant is nearly always correct.

To explain a little more... the service will only be compatible with
your bundle if both your bundle and the service publisher import the
service interface from the same place. Any of the following will work:

a) You have an API bundle exporting the interface, and both the
service publisher and your consumer import it from that API bundle.
b) The service publisher has its own copy of the interface and exports
it; your consumer bundle imports it from the publisher.
c) Your consumer has its own copy of the interface and exports it; the
service publisher imports it from you (this way around is unusual, but
will still work).

However if the publisher imports the interface from a different place
than your consumer, then the interfaces are different, even though
they have the same class names! Therefore you will naturally get
ClassCastExceptions.

OSGi protects us from these incompatibilities, so long as we open our
service trackers with "open()/open(false)". If we say "open(true)"
then we are explicitly asking to be provided with incompatible service
instances, which is very rarely what we want.

Rgds
Neil

On Sun, Jul 3, 2011 at 9:08 PM, Erwin Hogeweg
<[email protected]> wrote:
> Hi,
>
> Apologies in advance if this is stupid beginners question. I have searched
> the web and consulted my "OSGIi in Action", but to no avail.
>
> I have a simple service bundle, and I want to track the availability of that
> service i another bundle. Sounds pretty basic. For some reason I get a
> reference to the implementation object instead of a ref to the interface
> when ServiceTrackerCustomizer.addingService() is called. No big deal, but
> when I try to cast that ref back to the interface a ClassCastException is
> thrown.
>
> I have a faint feeling that this has something to do with class loaders, but
> I cannot pinpoint the real issue.
>
> In the Activator of the service bundle:
>
>   private MyService myService;  // Interface for MyServiceImpl
>
>   public final void start(BundleContext bundleContext) {
>       context = bundleContext;
>
>       myService = new MyServiceImpl();
>       context.registerService(MyService.class.getName(), myService, null);
>   }
> Only the package with the MyService interface is exported.
>
> In the class that implements the ServiceTrackerCustomizer:
>
>   public Object addingService(ServiceReference reference) {
>       MyService myService = (MyService)context.getService(reference);   //
> throws ClassCastException. reference is of type MyClassImpl
>       ...
>   }
>
> This bundle only imports the package with MyService.
>
>
> Thanks for your attention.
>
> Your help is greatly appreciated.
>
> Kind Regards,
>
> Erwin
> _______________________________________________
> OSGi Developer Mail List
> [email protected]
> https://mail.osgi.org/mailman/listinfo/osgi-dev
>

_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to