users@jersey.java.net

[Jersey] Re: How does jersey runtime get its JAXBContext

From: Farrukh Najmi <farrukh_at_wellfleetsoftware.com>
Date: Wed, 15 Feb 2012 17:20:35 -0500

Hi Glen,

Thanks again for your kind help. My JAXBContextResolver does have the
@Provider annotation (see below)...
The CFX option seems like a lot of work and risk so I am going to poke
around some more before trying that.

Any comments from dev team on how to force my
JAXBContextResolver.getContext() method to be called within
com.sun.jersey.core.provider.jaxb.*AbstractJAXBProvider* method
"protected final Marshaller *getMarshaller*(Class type, MediaType mt)
throws JAXBException" method?

@Provider
public final class JAXBContextResolver implements
ContextResolver<JAXBContext> {

     private final JAXBContext context;

     public JAXBContextResolver() throws Exception {
         this.context = new JSONJAXBContext(
             JSONConfiguration.natural().build(),
BindingUtility.getJaxbContextPath());
     }

     public JAXBContext getContext(Class<?> objectType) {
         String pkgName = objectType.getPackage().getName();
         String[] pkgs = BindingUtility.getJaxbContextPath().split(":");
         List pkgs2 = Arrays.asList(pkgs);
         boolean found = pkgs2.contains(pkgName);

         return found ? context : null;
     }
}

On 02/15/2012 04:49 PM, Glen Mazza wrote:
> On 02/15/2012 04:22 PM, Farrukh Najmi wrote:
>> Hi Glen,
>>
>> Thanks for the pointer. I checked and believe that my REST app is
>> quite consistent with json-from-jaxb sample.
>> The problem seems to be that my ContextResolver<JAXBContext> impl
>> class' getContext() method is not being called when creating the
>> Marshaller for the REST request.
>> During startup of my server I see that my
>> ContextResolver<JAXBContext> impl class' constructor is called not
>> once but twice with similar stack trace.
>>
>> Since my ContextResolver<JAXBContext> impl class includes the package
>> "net.opengis.gml.v_3_1_1" in its context path it sure seems like if
>> its getContext() method was called during the creation of the
>> Marshaller then all would be well.
>>
>> Debugging the code it appears that
>> com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider method
>> "protected final Marshaller getMarshaller(Class type, MediaType mt)
>> throws JAXBException" never uses the ContextResolver because
>> fixedMediaType member is true. Why is my ContextResolver not being
>> called? I am not sure if the problem is in my code or jersey runtime
>> code.
>>
>> Any further advice on how to debug this further? Thanks very much.
>
> I recently modified the sample to use CXF's JAX-RS implementation
> (https://github.com/gmazza/jersey-samples-on-cxf/tree/master/json-from-jaxb),
> if desperate you might want to try a different framework to see if it
> returns different error messages or works (if nothing else, you can
> get *two* mailing lists to try to solve your problem :) But I noticed
> Jersey needs a JAXBContextResolver @Provider
> (http://www.jroller.com/gmazza/entry/jersey_samples_on_cxf#jc11) --
> did you remember to include a similar class in your project? That
> might be the story.
>
> Glen
>
>>
>> On 02/15/2012 03:51 PM, Glen Mazza wrote:
>>> Have you looked at the Jersey json-from-jaxb sample? I believe it
>>> uses a JAXBContext to provide both XML and JSON options, see the
>>> bottom of the file here:
>>> http://java.net/projects/jersey/sources/svn/content/trunk/jersey/samples/json-from-jaxb/README.html?rev=5653
>>>
>>> It might point out something that can fix your problem.
>>>
>>> Regards,
>>> Glen
>>>
>>> On 02/15/2012 03:26 PM, Farrukh Najmi wrote:
>>>>
>>>> Hi Guys,
>>>>
>>>> I am still stuck on the problem posted earlier in this thread under
>>>> a different subject.
>>>>
>>>> In order for me to get this resolved I am thinking I need a clearer
>>>> understanding of how jersey creates its JAXBContext that it uses to
>>>> marshal and unmarshal JAXB objects.
>>>> In particular I am curious how I can give the jersey runtime a
>>>> JAXBContext that I have alredayt created elsewhere.
>>>>
>>>> I would be grateful if someone could provide some guidance. Thanks.
>>>>
>>>> On 02/10/2012 02:59 PM, Farrukh Najmi wrote:
>>>>> Hi Guys,
>>>>>
>>>>> Upon further investigation here are some findings on my problem....
>>>>>
>>>>> * First the class in question
>>>>> net.opengis.gml.v_3_1_1.PolygonType is definitely in a jar
>>>>> in my classpath for the web app
>>>>> * The "JAXBException: <Class> is not known to this context"
>>>>> problem seems to be experienced due to ClassLoader issues in
>>>>> many cases:
>>>>> o https://issues.apache.org/jira/browse/GERONIMO-3793
>>>>> o http://mail-archives.apache.org/mod_mbox/cxf-users/200809.mbox/%3C1220547389.13894.37.camel@ubuntu%3E
>>>>> o http://healthvaultjavalib.codeplex.com/workitem/10842
>>>>> * I do not experience this problem when I use the SOAP
>>>>> endpoint to the same webapp but only when I use the jersey
>>>>> REST endpoint
>>>>> * In my own code I am not doing any ClassLoader magic that I
>>>>> know off
>>>>> * I am using spring-framework in case it is relevant
>>>>>
>>>>> Any idea what else I can try to get to the bottom of this? Is this
>>>>> issue more appropriate for the users_at_jaxb list?
>>>>>
>>>>>
>>>>> On 02/09/2012 12:53 PM, Farrukh Najmi wrote:
>>>>>>
>>>>>> I am getting the following exception in my jersey endpoint built
>>>>>> using jersey 1.10:
>>>>>>
>>>>>> javax.ws.rs.WebApplicationException: javax.xml.bind.MarshalException
>>>>>> - with linked exception:
>>>>>> [javax.xml.bind.JAXBException:
>>>>>> net.opengis.gml.v_3_1_1.PolygonType is not known to this context]
>>>>>> at
>>>>>> com.sun.jersey.core.provider.jaxb.AbstractJAXBElementProvider.writeTo(AbstractJAXBElementProvider.java:141)
>>>>>> at
>>>>>> com.sun.jersey.core.provider.jaxb.AbstractJAXBElementProvider.writeTo(AbstractJAXBElementProvider.java:79)
>>>>>> at
>>>>>> com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:306)
>>>>>> at
>>>>>> com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1437)
>>>>>> at
>>>>>> com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
>>>>>> at
>>>>>> com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
>>>>>> at
>>>>>> com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
>>>>>> at
>>>>>> com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
>>>>>> at
>>>>>> com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708)
>>>>>> at
>>>>>> javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
>>>>>>
>>>>>>
>>>>>> This happens when the endpoint returns an XML response using a
>>>>>> JAXBElement. The element look like this (simplified):
>>>>>>
>>>>>> <RegistryObject xsi:type="ExtrinsicObjectType"
>>>>>> xmlns:ns2="http://www.w3.org/1999/xlink"
>>>>>> <http://www.w3.org/1999/xlink>
>>>>>> xmlns="urn:oasis:names:tc:ebxml-regrep:xsd:rim:4.0"
>>>>>> xmlns:ns4="urn:oasis:names:tc:ebxml-regrep:xsd:rs:4.0"
>>>>>> xmlns:ns3="http://www.w3.org/2005/08/addressing"
>>>>>> <http://www.w3.org/2005/08/addressing>
>>>>>> xmlns:ns5="urn:oasis:names:tc:ebxml-regrep:xsd:spi:4.0"
>>>>>> xmlns:ns6="urn:oasis:names:tc:ebxml-regrep:xsd:query:4.0"
>>>>>> xmlns:ns7="urn:oasis:names:tc:ebxml-regrep:xsd:lcm:4.0"
>>>>>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>>>> <http://www.w3.org/2001/XMLSchema-instance>>
>>>>>> <Slot name="urn:iso:TC211:19115:slot:geographicBoundingBox"
>>>>>> type="urn:ogc:def:dataType:ISO-19107:GM_Envelope">
>>>>>> <SlotValue xsi:type="AnyValueType">
>>>>>> <ns8:Polygon srsName="urn:ogc:def:crs:EPSG::4326"
>>>>>> xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
>>>>>> <http://schemas.xmlsoap.org/soap/envelope/>
>>>>>> xmlns:ns9="http://www.w3.org/2001/SMIL20/"
>>>>>> <http://www.w3.org/2001/SMIL20/>
>>>>>> xmlns:ns10="http://www.w3.org/2001/SMIL20/Language"
>>>>>> <http://www.w3.org/2001/SMIL20/Language>
>>>>>> xmlns:ns8="http://www.opengis.net/gml" <http://www.opengis.net/gml>>
>>>>>> <ns8:exterior>
>>>>>> <ns8:LinearRing>
>>>>>> <ns8:pos>-120.0 25.0</ns8:pos>
>>>>>> <ns8:pos>-70.0 25.0</ns8:pos>
>>>>>> <ns8:pos>-70.0 40.0</ns8:pos>
>>>>>> <ns8:pos>-120.0 40.0</ns8:pos>
>>>>>> <ns8:pos>-120.0 25.0</ns8:pos>
>>>>>> </ns8:LinearRing>
>>>>>> </ns8:exterior>
>>>>>> </ns8:Polygon>
>>>>>> </SlotValue>
>>>>>> </Slot>
>>>>>> </RegistryObject>
>>>>>>
>>>>>> The XML Schema for above is defined here
>>>>>> <http://docs.oasis-open.org/regrep/regrep-core/v4.0/cos01/xsd/rim.xsd>.
>>>>>>
>>>>>> The <SlotValue xsi:type="AnyValueType"> element allows xs:anyType.
>>>>>>
>>>>>> I have a ContextResolver as part of the jersey endpoint that has
>>>>>> a JAXBContext that includes JAXB bindings for the ns8:Polygon
>>>>>> element and the classpath contai9ns the jar containing the
>>>>>> net.opengis.gml.v_3_1_1.PolygonType class.
>>>>>>
>>>>>> During debug it seems that my ContextResolver is never called
>>>>>> because
>>>>>> com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider#getMarshaller
>>>>>> (line 140 in jersey 1.10)
>>>>>> skips the resolver because fixedMediaType is true.
>>>>>>
>>>>>> I would be very grateful for any suggestions on how to debug this
>>>>>> more and get past this problem.

-- 
Regards,
Farrukh Najmi
Web: http://www.wellfleetsoftware.com