users@jersey.java.net

Is there a way to set what classloader JAXBContext uses when using Jersey?

From: Jimi Hullegård <jimi.hullegard_at_mogul.com>
Date: Thu, 5 Aug 2010 22:49:29 +0200

Hi,

I'm writing a plugin for the Atlassian Jira application, and in my plugin I want to use Jersey as a REST client, and for example do a GET request to a REST server, and I want Jersey to handle the unmarshalling internally. As far as I understand, a simple resource.get(MyClass.class) should work, but that causes the following error:

java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory
 at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
 at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
 at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:192)
 at javax.xml.bind.ContextFinder.find(ContextFinder.java:385)
 at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
 at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
 at com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.getStoredJAXBContext(AbstractJAXBProvider.java:184)
 at com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.getJAXBContext(AbstractJAXBProvider.java:177)
 at com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.getUnmarshaller(AbstractJAXBProvider.java:129)
 at com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.getUnmarshaller(AbstractJAXBProvider.java:112)
 at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:106)
 at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:549)
 at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:502)
 at com.sun.jersey.api.client.WebResource.handle(WebResource.java:560)
 at com.sun.jersey.api.client.WebResource.get(WebResource.java:179)


I use jaxb-impl 2.1.12 and jersey-client 1.3, and I create the jersey client without any special configuration:

     DefaultClientConfig clientConfig = new DefaultClientConfig();
     client = Client.create(clientConfig);

I understand that the special ClassLoader situation for Jira plugins is the cause of this, because when I do the unmarshalling myself I can tell JAXB to use the plugin classloader (ie the same ClassLoader as the plugin class was loaded by) by this code:

jaxbContext = JAXBContext.newInstance("com.mycompany.my-rest-package", getClass().getClassLoader());

String objectAsString = resource.get(String.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
MyClass object = (MyClass )unmarshaller.unmarshal(new StringReader(objectAsString ));

And this works just fine. But I would really like to not have to handle the unmarshalling myself. So my question to you all is: Is there a way to tell Jersey to tell JAXB to use a specific classloader?


Regards
/Jimi Hullegård