Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-4290

Allow user-specified classloader for JAXRSClientFactory

    XMLWordPrintableJSON

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.5
    • Fix Version/s: 2.5.4, 2.6.1
    • Component/s: JAX-RS
    • Labels:
      None
    • Environment:

      Apache Karaf 2.2.4, CXF 2.5.0

    • Estimated Complexity:
      Unknown

      Description

      I wrote a helper class that isolates CXF's JAXRSClientFactory from users. My helper exposes this interface as a OSGi service:

      public interface JaxRsClientBuilder {
          <T> T createClient(@Nonnull String baseUrl, @Nonnull Class<T> resourceApiClass);
      }
      

      However, I discovered a blocking problem. If the user of my helper doesn't import org.apache.cxf.jaxrs.client in its OSGi classloader, then I get exceptions from java.lang.reflect.Proxy because there's no classloader anywhere that can see both resourceApiClass and org.apache.cxf.jaxrs.client.Client. I tried a solution (based on http://blog.osgi.org/2008/08/classy-solutions-to-tricky-proxies.html) where I dynamically make an aggregate classloader that can see both resourceApiClass and Client. I think I can trick JAXRSClientFactory into using this new classloader for the main resource (by passing in a new Proxy instance as the resource class), but I can't wedge my custom classloader in for subresources because of the way ClientProxyImpl.invoke() calls JAXRSClientFactory.

      I request the following as a possible solution. Certainly, I'd accept a better solution. For example, it looks like JAX-RS 2.0 should eliminate this problem by making Client into a public interface instead of an implementation detail.
      1) add a new method variant to JAXRSClientFactory that takes a classloader
      2) pass this classloader to JAXRSClientFactoryBean, and use it instead of cri.getServiceClass().getClassLoader() or the thread context classloader
      3) change ClientProxyImpl to save this classloader and use it for subresources

      See also the following which describes my failed attempt to work around this issue: http://stackoverflow.com/questions/10458378/how-can-i-make-a-java-lang-reflect-proxy-from-two-separate-classloaders

        Attachments

          Activity

            People

            • Assignee:
              sergey_beryozkin Sergey Beryozkin
              Reporter:
              cdolan Chris Dolan
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: