users@jersey.java.net

[Jersey] Re: Jersey fails in GFv3.1

From: JAKUB PODLESAK <jakub.podlesak_at_oracle.com>
Date: Wed, 20 Jul 2011 15:32:54 +0200

Hi Markus,

If you try with the following request, things should work as expected:

curl -v -X SEARCH \
              -HAccept:application/xml \
             -H Content-Type:application/xml \
             -T queryschemadiscovery.xml
http://localhost:8080/GF3Fail/quipsy

The issue is that when the client does not specify required media type,
Jersey utilizes the first provider capable of writing the response body
object.
In this case, Jersey tried to respond in JSON format, and there a
different marshaller
is used than what is used by the XML provider.

I do not have a build-able source of the test case web app, but you can
try to return
JSONJAXBContext (see [1]) from your JAXBContext resolver to fix the issue.
Of course, you will be getting JSON response out of the resource unless
you request XML,
but you should avoid getting the nasty 500 back.

~Jakub

[1]http://jersey.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/json/JSONJAXBContext.html


On 15.7.2011 17:25, Markus Karg wrote:
> Jakub,
>
> two good news and two bad news. :-)
>
> The bad news first: I did not find the time to set up a pom file, but
> only can send a ready-to-run WAR file plus the Java source code files.
> Also, the problem happens with this simple WAR, too, so it really seems
> to be a problem of GF3, as the applications runs in my standalone
> environment pretty well (not as WAR but using embedded grizzly).
>
> Now the good news: First, I found a simple workaround -- I just added
> @Produces("application/xml") to my method and everything is running fine
> in GF3 now. Second, attached you will find a WAR that produces the
> problem plus source code.
>
> Here is how you can enforce it:
>
> asadmin deploy GF3Fail.war
>
> curl -v -X SEARCH -H Content-Type:application/xml -T
> queryschemadiscovery.xml http://localhost:8080/GF3Fail/quipsy
>
> (queryschemadiscovery.xml is found in ZIP)
>
> The result is that you will receive a "500 Internal Server Error" and
> GF3's server.log contains this:
>
> javax.xml.bind.JAXBException: class
> net.java.dev.webdav.jaxrs.search.xml.elements.BasicSearchSchema nor any
> of its super class is known to this context
>
> Again, the same is running well in my standalone setup, and it runs well
> in GFv2 using a bundled Jersey release.
>
> Hope this helps in discovering the difference between GFv2 and GFv3. If
> you need more, please let me know.
>
> Regards
> Markus
>
> -----Original Message-----
> From: Jakub Podlesak [mailto:jakub.podlesak_at_oracle.com]
> Sent: Donnerstag, 14. Juli 2011 16:56
> To: users_at_jersey.java.net
> Cc: Markus Karg
> Subject: [Jersey] Re: Jersey fails in GFv3.1
>
> Hi Markus,
>
> On 07/13/2011 06:45 PM, Markus Karg wrote:
>> Jakub,
>>
>> I found the time to analyze our code, and was lucky to find a
> workaround:
>>
>> If I do not return a Custom JAXB class (for which Jersey
> must
>> find our ContextResolver -- which obviously does not work as
> I
>> already mentioned) but instead use the below code to
> manually
>> provide a String, everything is working well even in
>> GFv3.1.1_b11. :-)
> I agree generating the XML string manually is annoying.
>
>>
>> But certainly I am highly interested in the actual cause,
> why
>> Jersey is not finding our context resolver? I expect the
>> problem is that we have to return application/xml, which is
>> also provided by Jersey's own context resolvers. So how can
> we
>> convince Jersey that even in GF (outside it works!) it shall
>> use *our* context resolver to marshal that Custom JAXB
> class?
>> Or in other words, how to convice Jersey's own context
>> resolver that it shall *not* marshall our custom JAXB class?
> The default marshaling process flow is like follows:
>
> 1. Jersey tries to obtain a JAXB Marshaller instance
> (via custom ContextResolver<Marshaller>) first
> If succeeded, the marshaller is used to marshal the data
>
> 2. if the above marshaller is not available
> (missing resolver|resolver returns null)
> Jersey tries to get a JAXBContext instance
> (via ContextResolver<JAXBContext>)
> in order to get a JAXB marshaller from it.
> if there is no custom JAXBContext available,
> the default one for the given Java type is used:
> JAXBContext.newInstance(type)
>
> Attaching a zipped web application with a custom JAXBContext resolver
> and two JAXB beans. Things work fine for me here on GFv3.1 and also
> GFv3.1.1 b10.
>
> The ContaineeBean context is configured
> to use "anotherNS" instead of the default one, and that works fine:
>
> --8<--
> curl -XPOST -HAccept:application/xml \
> -HContent-type:application/xml \
> --data '<ns2:containeeBean
> xmlns:ns2="anotherNs"><content>foo</content></ns2:containeeBean>' \
> http://localhost:8080/jaxb-context/webresources/containee
>
> <?xml version="1.0" encoding="UTF-8"
> standalone="yes"?><containerBean><containee><content>foo</content></cont
> ainee></containerBean>
> -->8--
>
> Is it possible to send out similar test case application, where the
> issue reproduces?
>
> ~Jakub
>
>>
>> Thanks
>>
>>
>> Markus
>>
>> *From:*Jakub Podlesak [mailto:jakub.podlesak_at_oracle.com]
>> *Sent:* Dienstag, 12. Juli 2011 17:59
>> *To:* users_at_jersey.java.net
>> *Subject:* [Jersey] Re: Jersey fails in GFv3.1
>>
>> Hi Markus,
>>
>> That is really strange. Given that the very same application works
>> fine on GFv2 it might be related to some GFv3 class-loading magic.
>> Any chance you could isolate a small simple reproducible test case to
>> share?
>>
>> The only other option i can think of at the moment is you may try to
>> re-bundle your application, remove all Jersey jars from it and try to
>> redeploy. Does the issue reproduce then?
>>
>> ~Jakub
>>
>>
>>
>> On 07/12/2011 03:01 PM, Markus Karg wrote:
>>
>> [Crossposted to GlassFish Forum]
>>
>> Our JAX-RS application is working well standalone (Grizzly) as well as
>> in GFv2ur2 (Jersey-1.4 bundled in our EAR), but fails in GFv3.1
>> (Jersey-1.5 is part of GF)!
>>
>> In particular, we are providing a custom ContextResolver which
>> provides (besides more) two classes: "QuerySchemaDiscovery" and
>> "BasicSearchSchema". Within "getContext" we are doing some output to
>> see what class was requests (for debug purposes).
>>
>> Our resource method receives a "QuerySchemaDiscovere" instance (i. e.
>> JAXB can resolve it using our custom ContextResolver), then wants to
>> return an instance of "BasicSearchSchema". And here is the funny
> thing:
>> GFv3.1 says that "BasicSearchSchema" is not part of the JAXB context.
>> Moreover, there is a log entry found for
>> "getContext(QuerySchemaDiscovere)" but NOT for
>> "getContext(BasicSearchSchema)", so obviously is seems GFv3.1 is using
>> a differen context...
>>
>> Caused by: javax.xml.bind.JAXBException: class
>> net.java.dev.webdav.jaxrs.search.xml.elements.BasicSearchSchema nor
>> any of its super class is known to this context.
>> at
>> com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImp
>> l.java:611)
>> at
>> com.sun.xml.bind.v2.runtime.property.ArrayReferenceNodeProperty.serial
>> izeListBody(ArrayReferenceNodeProperty.java:112)
>> ... 56 more
>>
>> I cannot believe that it is a bug in my application, as it runs
>> standone and in GFv2ur2, so I think it is a bug in GFv3.1. Any ideas
> what to do?
>> Thanks!
>>
>> Markus
>>