users@jersey.java.net

Re: [Jersey] Is there a way to set what classloader JAXBContext uses when using Jersey?

From: Paul Sandoz <Paul.Sandoz_at_oracle.com>
Date: Fri, 6 Aug 2010 10:47:23 +0200

Hi Jim,

Jersey will utilize the thread context class loader to load provider
classes such as the JAXB provides, which from the stack trace seem to
be loaded just fine, so i am not sure why JAXB fails.

So one way to perhaps resolve this is to set the thread context class
loader when creating the client and then re-setting it back to the
previous value.

An alternative approach is to define your own
ContextResolver<JAXBContext> implementation that allows you to
instantiate JAXBContext and supply the classes/packages and class
aloder.

Paul.

On Aug 5, 2010, at 10:49 PM, Jimi Hullegård wrote:

> 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
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>