users@jersey.java.net

SV: [Jersey] Jersey client accessing Jesery REST server message writer issue

From: Jimi Hullegård <jimi.hullegard_at_mogul.com>
Date: Tue, 10 Aug 2010 12:22:44 +0200

Hi Paul and Kevin,

I must say that I have more or less the same problems as you Kevin. And I definately suspect a classloader issue, since that was the problem when I tried to marshall and unmarshall JAXB objects before. It turned out that since my code is used in a Jira plugin the special classloader situation caused Jersey/JAXB to use the wrong classloader. It tried to use the one from Thread.currentThread().getContextClassLoader(), but that returned the Webapp classloader while all relevant code (including jaxb and jersey classes) were in the plugin classloader.

I got around that problem by providing my own ContextResolver<JAXBContext> that created a JAXBContext with the correct classloader.

So, I really suspect that somehow, somewere, Jersey is trying to use the context class loader from the thread, and end up with the wrong one. But I can't for the love of me figure out how to change this behaivor, or change what classloader is returned by Thread.currentThread().getContextClassLoader(). I guess there is some code that runs long before my code is running, because I tried specifically setting the threads context class loader in the constructor of my plugin class, but that didn't help at all.

Maybe you have any input on this, Paul? Is there a solution similar to the ContextResolver<JAXBContext> that I can try, so I can specifically tell jersey/jaxb to use a specific classloader? Without having to write my own message body writer... If I use my own contextresolver and marshall the object into a string, then I can post it using jersey just fine, but I would like not having to marshall it myself.

And Kevin, sorry if you think that I hijacked your thread. Maybe some of these links can help you, even though they don't work for me:

http://jersey.576304.n2.nabble.com/com-sun-jersey-api-client-ClientHandlerException-A-message-body-reader-for-Java-type-td4122001.html

http://markmail.org/thread/btvlaxkpxf2hluou#query:+page:1+mid:upvg2l24l47ywvlh+state:results

http://jersey.576304.n2.nabble.com/Jersey-client-problem-with-mvn-assembly-td4129445.html

Regards
/Jimi

________________________________
Från: Paul Sandoz [Paul.Sandoz_at_oracle.com]
Skickat: den 10 augusti 2010 11:40
Till: users_at_jersey.dev.java.net
Ämne: Re: [Jersey] Jersey client accessing Jesery REST server message writer issue

Hi Kevin,

It looks like there might be a class loading issue. It indicates that the Client instance cannot see the JAXB libs and therefore the JAXB message body writers for the client are not being utilized. Can you access JAXB directly from the application code in server 1 e.g. new JAXBContext(Transaction.class);

When you say simple calls did you try a simple GET request such as:

  String s = webResource....get(String.class);

if that works it certainly indicates an issue with JAXB rather than a fundamental issue with META-INF/services.

Anything else in the logs on initialization? If you set JDK logging to CONFIG or above you may got some more clues.

Since Jersey is distributed with GF you might want to be careful if you are also distributing a different version of Jersey in the WEB-INF/lib, also GF ships with JAXB so you may not require it to be in the WEB-INF/lib unless you need a specific version.

Paul.

On Aug 10, 2010, at 3:41 AM, Kevin Duffey wrote:

Hey all,

I am working on a project that uses two servers to communicate back and forth. The one server makes a REST call to the 2nd server. Both are my own code, both use Jersey and so forth. They both use the same .xsd and compiled JAXB classes. From server 1 I can reach server 2 no problem on simple calls. It's when I use the Jersey client code to pass a JAXB object to server 2 that I get the problem.

Client client = Client.create();
WebResource webResource = client.resource(getServerURL()).path("resources/transaction");
Transaction response = webResource.header("Authorization", auth).accept("application/vnd.mycompany..transactions+xml").type("application/vnd.mycompany.transactions+xml").post(Transaction.class, t);

Maybe I am doing this wrong? But when I execute this code I get the

com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java type...

exception. I did some searching and see where Paul has replied to make sure all the JAXB libraries are in the class path. I definitely have all these in the WEB-INF/lib folder of my .war app that I deploy on both servers.

So I am stumped as of now why this is telling me to have a message body writer. The Transaction class is a class generated from the .xsd.. and in fact on the server 1, I can make a REST call to it with xml in the format of the Transaction JAXB class, and it works. So I am not sure why it is telling me I need a separate writer.. it should have been part of the JAXB generated shouldn't it?

I am using Jersey client 1.1.5 and GlassFish v3.

Thanks in advance.