如何从两个单独的类加载器创建java.lang.reflect.Proxy?

时间:2012-05-05 02:42:13

标签: java osgi classloader

我使用CXF JAXRSClientFactory从各种JAX-RS接口创建代理实例。在内部,这个工厂调用Proxy.newProxyInstance(),传入我的界面和CXF客户端界面。

在OSGi下,如果包含我的接口类的bundle导入org.apache.cxf.jaxrs.client,这将非常有用。但有一天,我决定将CXF隐藏在我的应用程序类中,因此我创建了一个将客户端工厂封装在服务中的软件包。现在我从Proxy获得了IllegalArgumentException,说“从类加载器中看不到MyInterface”或“从类加载器中看不到客户端”。

问题是我的工厂捆绑包导入CXF而不是我的应用程序。我的应用程序包不会导入CXF。所以在容器中的任何地方都没有可以看到CXF Client类和我的JAX-RS接口的类加载器。

有没有办法在不将CXF导入我的应用程序包的情况下解决这个问题?例如,我的工厂捆绑包可以动态地创建一个新的类加载器,它是两个类加载器的联合,因此它可以看到CXF和我的应用程序类吗?或者我可以欺骗代理接受这两个接口吗?

1 个答案:

答案 0 :(得分: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);