2012-05-05 35 views
1

我使用CXF JAXRSClientFactory從各種JAX-RS接口創建代理實例。在深處,這個工廠調用Proxy.newProxyInstance(),傳入我的接口和CXF客戶端接口。如何從兩個獨立的類加載器創建一個java.lang.reflect.Proxy?

在OSGi下,如果包含我的接口類的包導入org.apache.cxf.jaxrs.client,這將很有用。但是有一天我決定要將CXF隱藏在我的應用程序類中,所以我創建了一個將客戶端工廠封裝在一個服務中的bundle。現在,我從代理髮出IllegalArgumentException異常,說「MyInterface從類加載器不可見」或「客戶端從類加載器不可見」。

問題是我的工廠包導入CXF,但不是我的應用程序。而我的應用程序包不會導入CXF。所以容器中的任何地方都沒有classloader,它可以同時看到CXF Client類和我的JAX-RS接口。

有沒有辦法解決這個問題,而無需將CXF導入到我的應用程序包中?例如,我的工廠包可以動態創建一個新的類加載器,它是兩個類加載器的聯合,所以它可以同時看到CXF和我的應用程序類?或者我可以欺騙代理無論如何接受這兩個接口?

+0

這在2008年通過博客彼得柯瑞恩斯似乎很密切的關係我的問題,但我還沒有完全在CXF的背景下grokked彼得的解決方案尚未:http://blog.osgi.org/2008/08 /classy-solutions-to-tricky-proxies.html –

+0

我在Peter的解決方案中做了一個剪輯(創建一個可以看到這兩個類的集合類加載器)。除了JAX-RS子資源之外,它看起來很有效。 CXF在ClientProxyImpl.invoke()中隨時創建額外的代理,因爲這些子資源被訪問,並且我沒有看到任何方法來截取CXF代碼中的代碼。 –

回答

1

從CXF 2.6.1開始,這是一個可以解決的問題。關閉的問題CXF-4290添加了一個新的API來將自定義類加載器傳遞給JAXRSClientFactory。使用這個和新的org.apache.cxf.jaxrs.client.ProxyClassLoader類,我現在可以爲任意應用程序類創建代理。

ProxyClassLoader classLoader = new ProxyClassLoader(); 
    classLoader.addLoader(resourceApiClass.getClassLoader()); 
    classLoader.addLoader(JAXRSClientFactoryBean.class.getClassLoader()); 

    JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean(); 
    bean.setAddress(baseUrl); 
    bean.setServiceClass(resourceApiClass); 
    bean.setClassLoader(classLoader); 
    return bean.create(resourceApiClass);