2012-12-31 80 views
3

Karaf v2.3.0,org.apache.aries.blueprint.core:1.0.1,在从另一个包导入的服务上调用接口方法时抛出ClassCastException。接口方法在接口上定义并由实现类实现。我无法弄清楚服务代理如何认为它是Impl(TicketServiceImpl)而不是接口(TicketService)。我很感激任何有关如何解决此问题的建议或建议。Karaf OSGI白羊座蓝图ClassCastException:Impl无法转换为接口

例外:

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] 
    ... 

奇怪的是,立刻异常之前,我打印代理.getInterfaces(),这意味着代理的票务服务,不TicketServiceImpl。

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

我也试过迫使类测试在代理:

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 

回答

1

几乎得到了它......在票务的抛出ClassCastException是在客户端Bean固定通过删除“初始化方法”客户端blueprint.xml。现在,不是从init-method启动doProcess(),而是由driver.onRegisterService()启动,它调用client.doProcess(),它没有问题地调用TicketService.add(),没有例外。

<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> 

这让我想起了客户一直在试图使用该服务的服务代理结束正在修建之前(在它的初始化方法=“doProcess”)。我认为等待客户正式注册的第三类(司机)将确保代理准备好被客户使用。

但是,然后我将第二个服务属性添加到客户端。第二个服务在调用其方法时会间歇性地抛出ClassCastException。现在我认为这可能是一个古老的竞争条件;我通过添加驱动程序稍微减慢了客户端的速度,但速度不够慢,无法防止在准备好之前使用第二个服务。这也可能是错误的。我很感激任何想法。

如果问题没有神奇地消失,我将添加一个ClassCastException的catch,并假定该服务尚未就绪。

+0

也许? http://wiki.osgi.org/wiki/Service_Compatibility“通过调用getAllServiceReferences()而不是getServiceReferences()来忽略兼容性...使用ServiceTracker,调用open(true)而不是open()...尝试投射服务实例添加到接口将导致ClassCastException。请参见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

+0

想知道为什么骆驼蓝图关闭OSGI服务兼容性检查... – spiraleddy

+0

基于此,将检查代码为“捆绑软件无法导入任何包含您想要代理的服务的软件包“https://mail.osgi.org/pipermail/osgi-dev/2011-February/003019.html – spiraleddy