2012-12-31 56 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