3

Karaf v2.3.0, org.apache.aries.blueprint.core:1.0.1, throws ClassCastException when an interface method is called on service imported from another bundle. The interface method is defined on the interface and implemented by the implementation class. I can't figure out how the service proxy thinks its the Impl (TicketServiceImpl) instead of the interface (TicketService). I'm grateful for any suggestions or advice on how to work around this.

Exception:

    Caused by: java.lang.ClassCastException: 
    org.abc.TicketServiceImpl cannot be cast to
    org.abc.TicketService at 
    Proxy3ac85313_c60c_42db_8def_ea7bd3d7411c.add(Unknown Source)
    ...
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.6.0_37]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)[:1.6.0_37]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)[:1.6.0_37]
    at java.lang.reflect.Method.invoke(Method.java:597)[:1.6.0_37]
    at org.apache.aries.blueprint.utils.ReflectionUtils.invoke(ReflectionUtils.java:297)[7:org.apache.aries.blueprint.core:1.0.1]
    at org.apache.aries.blueprint.container.BeanRecipe.invoke(BeanRecipe.java:958)[7:org.apache.aries.blueprint.core:1.0.1]
    ...

Oddly, immediately before the exception, I print proxy .getInterfaces() which implies the proxy is TicketService, not TicketServiceImpl.

    MyTicketServer proxy interfaces: org.abc.TicketService, 
    org.apache.aries.proxy.weaving.WovenProxy 
    MyTicketServer Proxy class name: Proxy3ac85313_c60c_42db_8def_ea7bd3d7411c

I also tried forcing a Class test on the proxy:

    if (myTicketService instanceof TicketService) { <-- you'd think this would help
        myTicketService.add(ticket); //<-- Throws proxy ClassCastException!!
    } // implies problem is in the return path through proxy back to method
spiraleddy
  • 147
  • 10

1 Answers1

1

Almost got it... The classCastException on TicketService was fixed by removing the "init-method" on the client bean in the client blueprint.xml. Now, instead of doProcess() being launched from init-method, it is launched by driver.onRegisterService(), which calls the client.doProcess(), which calls TicketService.add() with no problem, no exceptions.

<bean id="driver" class="org.xyz.RetrieveDriver"></bean>
<service id="ticketRetriever" interface="org.xyz.TicketRetriever"
    ref="ticketRetrieverRT">
    <registration-listener ref="driver"
        registration-method="onRegisterService" 
        unregistration-method="onUnregisterService" />
</service>

This made me think the client had been trying to use the service (in it's init-method="doProcess") before the service proxy was finished being built. I thought the third class (the driver) waiting for the client to be officially registered would ensure the proxies were ready to be used by the client.

But, then I added second service attribute to the client. The second service intermittently throws the ClassCastException when its method is called. Now I think it may be a plain old race condition; that I slowed down the client a little by adding the driver, but not slow enough to prevent the second service from being used before its ready. This may be wrong too. I'm grateful on any thoughts.

If the problem doesn't magically go away, I will add a catch for the ClassCastException with the assumption that the service isn't ready yet.

spiraleddy
  • 147
  • 10
  • Maybe? http://wiki.osgi.org/wiki/Service_Compatibility "ignore compatibility ... by calling getAllServiceReferences() instead of getServiceReferences(). With ServiceTracker, call open(true) instead of just open()…attempting to cast the service instance to the interface will result in a ClassCastException. SEE http://svn.apache.org/viewvc/camel/trunk/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintHelper.java?view=markup, getOsgiService(){...tracker.open(true)..} – spiraleddy Jan 04 '13 at 18:06
  • based on that, will check code for "bundle cannot import any package containing a service you want to proxy" https://mail.osgi.org/pipermail/osgi-dev/2011-February/003019.html – spiraleddy Jan 04 '13 at 18:49
  • 1
    After tightening down the imports and exports between the bundles, I have not encountered the problem again. I'm nearly positive the problem was related to the TicketService package being exposed by another bundle in the Ticket grouping. – spiraleddy Jan 15 '13 at 11:45
  • Dude this was a huge help for a similar problem I was having. Thank you so much for taking time to update your SO! :) – Bane Jun 20 '14 at 20:47