如何从两个独立的类加载器生成java.lang.reflect.Proxy?

如何从两个独立的类加载器生成java.lang.reflect.Proxy?,java,osgi,classloader,Java,Osgi,Classloader,我使用CXF JAXRSClientFactory从各种JAX-RS接口创建代理实例。在内部深处,该工厂调用Proxy.newProxyInstance(),传入my接口和CXF客户端接口 在OSGi下,如果包含我的接口类的bundle导入org.apache.cxf.jaxrs.client,这将非常有效。但是有一天,我决定从我的应用程序类中隐藏CXF,所以我创建了一个包,将客户机工厂封装在服务中。现在我从代理中得到IllegalArgumentException,它说“MyInterface

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

在OSGi下,如果包含我的接口类的bundle导入org.apache.cxf.jaxrs.client,这将非常有效。但是有一天,我决定从我的应用程序类中隐藏CXF,所以我创建了一个包,将客户机工厂封装在服务中。现在我从代理中得到IllegalArgumentException,它说“MyInterface在类装入器中不可见”或“Client在类装入器中不可见”

问题是我的factory bundle导入的是CXF,而不是我的应用程序。而且我的应用程序包不导入CXF。因此,容器中的任何地方都没有可以同时看到CXF客户机类和我的JAX-RS接口的类加载器


有没有办法在不将CXF导入我的应用程序包的情况下解决这个问题?例如,我的工厂包是否可以动态生成一个新的类加载器,它是两个类加载器的联合体,这样它就可以同时看到CXF和我的应用程序类?或者我可以愚弄代理接受这两个接口吗?

从CXF 2.6.1开始,这是一个可以解决的问题。已结束的问题添加了一个新的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);

从CXF 2.6.1开始,这是一个可以解决的问题。已结束的问题添加了一个新的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);

Peter Kriens在2008年写的这篇博客似乎与我的问题密切相关,但我还没有在CXF的上下文中完全了解Peter的解决方案:我对Peter的解决方案进行了改进(创建了一个可以同时看到两个类的聚合类加载器)。除了JAX-RS子资源之外,它看起来还可以工作。在访问这些子资源时,CXF会在ClientProxyImpl.invoke()中动态生成其他代理,我在CXF代码中看不到任何拦截方法。Peter Kriens在2008年发表的这篇博客似乎与我的问题密切相关,但我还没有在CXF的上下文中完全了解Peter的解决方案:我对Peter的解决方案进行了删节(动态创建一个可以同时看到这两个类的聚合类加载器)。除了JAX-RS子资源外,它似乎可以工作。在访问这些子资源时,CXF会在ClientProxyImpl.invoke()中动态创建其他代理,而我在CXF代码中看不到任何截取方法。