Как мога да направя java.lang.reflect.Proxy от два отделни зареждащи класове?

Използвам CXF JAXRSClientFactory за създаване на прокси екземпляри от различни JAX-RS интерфейси. Дълбоко вътре тази фабрика извиква Proxy.newProxyInstance(), предавайки моя интерфейс и CXF клиентския интерфейс.

Под OSGi това работи чудесно, ако пакетът, който съдържа моя интерфейсен клас, импортира org.apache.cxf.jaxrs.client. Но един ден реших, че искам да скрия CXF от моите класове на приложения, така че създадох пакет, който капсулира клиентската фабрика в услуга. Сега получавам IllegalArgumentException от Proxy, казващ "MyInterface не се вижда от зареждащия клас" или "Клиентът не се вижда от зареждащия клас".

Проблемът е, че моят фабричен пакет импортира CXF, но не и моето приложение. И пакетът ми с приложения не импортира CXF. Така че никъде в контейнера няма програма за зареждане на класове, която да вижда както CXF клиентския клас, така и моя JAX-RS интерфейс.

Има ли начин да реша това, без да импортирам CXF в моите пакети приложения? Например, може ли фабричният ми пакет да създаде динамично нов класов зареждащ механизъм, който е обединението на двата класови зареждащи, така че да може да вижда както CXF, така и моите класове на приложение? Или мога да заблудя проксито да приеме двата интерфейса така или иначе?


person Chris Dolan    schedule 05.05.2012    source източник
comment
Този блог от Peter Kriens през 2008 г. изглежда много тясно свързан с моя проблем, но все още не съм разбрал напълно решението на Peter в контекста на CXF: blog.osgi.org/2008/08/classy-solutions-to-tricky-proxies.html   -  person Chris Dolan    schedule 06.05.2012
comment
Намалях решението на Питър (създаване на агрегат за зареждане на класове в движение, който може да вижда и двата класа). Изглежда, че щеше да работи, с изключение на JAX-RS подресурси. CXF прави допълнителни проксита в движение в ClientProxyImpl.invoke() при достъпа до тези подресурси и не виждам начин да прихвана това в CXF кода.   -  person Chris Dolan    schedule 07.05.2012


Отговори (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);
person Chris Dolan    schedule 19.09.2012