users@jersey.java.net

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

From: Pavel Bucek <Pavel.Bucek_at_Sun.COM>
Date: Fri, 06 Aug 2010 15:23:56 +0200

Aha, I thought you are on server side. In that case you can try
something like

DefaultClientConfig dcc = new DefaultClientConfig();
dcc.getClasses().add(YourProvider.class);
Client c = new Client(dcc);

Pavel

On 8/6/10 3:08 PM, Jimi Hullegård wrote:
> Hi Pavel,
>
> Thanks for the link, but I have already seen that page. And I already have registered my resolver in the spring context. But since I don't have access to any "main" spring applicationContext.xml from within my Jira plugin I had to add it to the spring context the "Jira plugin way", but as I wrote in a previous reply I could confirm that my resolver actually was inserted in the spring context.
>
> Regarding the part of the web.xml it doesn't apply to my case, since I don't have an web application.
>
> /Jimi
>
> ________________________________________
> Från: Pavel.Bucek_at_Sun.COM [Pavel.Bucek_at_Sun.COM]
> Skickat: den 6 augusti 2010 14:53
> Till: users_at_jersey.dev.java.net
> Ämne: Re: [Jersey] Is there a way to set what classloader JAXBContext uses when using Jersey?
>
> this might help:
> http://stackoverflow.com/questions/1942792/jersey-implementing-contextresolverjaxbcontext-in-spring
>
> Pavel
>
> On 8/6/10 2:08 PM, Moises Lejter wrote:
>
>> To get the easy stuff out of the way, is this new class in the same package as your resources? Do you have an Application class, and does it list it among your singletons?
>>
>> I'm thinking that the fact it's in the Spring context need not mean Jersey saw it ...
>>
>> Moises
>>
>> Sent from my iPhone
>>
>> On Aug 6, 2010, at 6:38 AM, Jimi Hullegård<jimi.hullegard_at_mogul.com> wrote:
>>
>>
>>
>>> Hi Paul,
>>>
>>> First of all, could you point out the part of the Jersey code base that uses the thread context class loader? I looked around a little in the Jersey source code but couldn't find anything. Infact, when I look at the source code for the classes and methods from the stacktrace I noticed that it is *JAXB* that is using the thread context class loader as far as I can see, using the class ContextFinder.
>>>
>>> So the path is:
>>> MyPlugin -> Jersey -> JAXB, all within the same current classloader (ie the plugin class loader)
>>>
>>> Then the newInstance method of JAXBContext then uses the newInstance method of ContextFinder that uses the context class loader. But this is not good, since the context class loader is the WebappClassLoader. I assume this is because no context class loader was provided when the current thread was created, so it used the one of the parent thread.
>>>
>>> Also, changing the context class loader during the creation of the client instance didn't have any effect at all. Changing it during the get call worked, but that seems like to much of a hack for me to be comfortable with, especially since it is needed for every single request.
>>>
>>> I also tried creating my own ContextResolver<JAXBContext>, annotated it using @Provider and injected it in the spring application context by specifing it as a<component> in my atlassian-plugin.xml as the Jira documentation specifies. And I was able to look it up in using applicationContext.getBean("myContextResolver"), so I know it was injected into the spring context. But I still get the same error, and it never seems to notice my resolver.
>>>
>>> When I debug this in eclipse, I notice that when it comes into the method getJAXBContext(Class type) the mtContext field is null so it resolves to using the method getStoredJAXBContext that creates the Jaxbcontext the normal way (ie not using my resolver, and using the wrong classloader).
>>>
>>> Is there any good documentation on what is needed in order to make Jersey pick up my resolver class? Any help would be really appreciated.
>>>
>>> Regards
>>> /Jimi
>>>
>>> ________________________________________
>>> Från: Paul Sandoz [Paul.Sandoz_at_oracle.com]
>>> Skickat: den 6 augusti 2010 10:47
>>> Till: users_at_jersey.dev.java.net
>>> Ämne: Re: [Jersey] Is there a way to set what classloader JAXBContext uses when using Jersey?
>>>
>>> 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
>>>>
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>>
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>