users@jersey.java.net

Re: [Jersey] Issue with Provider redirection

From: Guilhem <guilhem.legal_at_geomatys.fr>
Date: Mon, 09 Aug 2010 10:47:02 +0200

Hi paul,

i'm using jersey 1.3, I have made a little error in my previous that i
realize while creating a simple test case : my problem don't happen when
i use a non-standard MIME Type like:

application/vnd.ogc.xml

This problem happen when i use application/xml or text/xml, this is
probably a way to search.

so I create a simple case and reproduce the bug, here are my classes :

_my singleton _

package test.provider;

import com.sun.jersey.spi.resource.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import test.model.Apple;

@Path("sos")
@Singleton
public class MySingleton {

     @Context
     private volatile UriInfo uriContext;

     @GET
     public Response doGET() {
         String outputFormat =
uriContext.getQueryParameters().getFirst("output");
         if (outputFormat == null) {
             outputFormat = "text/xml";
         }
         Apple a = new Apple();
         return Response.ok(a, outputFormat).build();
     }
}


_my message body writer:_

package test.provider;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.logging.Logger;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import test.model.Apple;

@Provider
public class MyProvider<T extends Apple> implements MessageBodyWriter<T> {

     private static final Logger LOGGER = Logger.getLogger("test.provider");


     @Override
     public boolean isWriteable(Class<?> type, Type type1, Annotation[]
antns, MediaType mt) {
         System.out.println("isWritable:" +
Apple.class.isAssignableFrom(type));
         return Apple.class.isAssignableFrom(type);
     }

     @Override
     public long getSize(T t, Class<?> type, Type type1, Annotation[]
antns, MediaType mt) {
         System.out.println("get size");
         return -1;
     }

     @Override
     public void writeTo(T t, Class<?> type, Type type1, Annotation[]
antns, MediaType mt, MultivaluedMap<String, Object> mm, OutputStream
out) throws IOException, WebApplicationException {
         System.out.println("write to");
         try {
             Marshaller m =
JAXBContext.newInstance(Apple.class).createMarshaller();
             m.marshal(t, out);
         } catch (JAXBException ex) {
             LOGGER.severe("JAXB exception while writing the
capabilities File");
         }
     }

}

and a simple model object

package test.model;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Apple")
public class Apple {

     @XmlElement
     public String colour;

}

I use the system.out to see if i enter the messageBodyWriter

if i make a request :
http://localhost:8080/Test-provider/sos?output=application/xml or
http://localhost:8080/Test-provider/sos?output=text/xml or
http://localhost:8080/Test-provider/sos

==> nothing in the log

if i make a request : http://localhost:8080/Test-provider/sos?output=app/xml

==> in the log :
isWritable:true
get size
write to

So the problem here i think is relative to unrecognized mime Type.

Guilhem Legal


On 09/08/2010 08:06, Paul Sandoz wrote:
> Hi Guilhem,
>
> What version of Jersey are you using?
>
> It seems like when you use text/xml Jersey is processing and that
> results in an exception due to some JAXB error, possibly because by
> default Jersey will create a JAXBContext from the class and that may
> be lacking some additional information than if you created the
> JAXBContext.
>
> The code to process text/xml and application/xml goes through the same
> path so you should be able to override both or indeed any JAXB support
> supplied by Jersey if your own MessageBodyWriter implementation is
> registered. Would it be possible to send a simple reproducible test case?
>
> Note that you can also define your own ContextResolver<Marshaller>
> that can pool Marshaller instances per-thread (as they are not thread
> safe and reuse the existing JAXB support.
>
> Paul.
>
> On Aug 6, 2010, at 5:58 PM, Guilhem wrote:
>
>> Hello,
>>
>> I'm using jersey in a WebService to produce XML object marshalled
>> with JAXB.
>> I want to use my own JAXBContext so i create a Jersey provider to
>> handle the marshalling of my object.
>>
>> My problem is that when i use the MIME type aplication/xml, my
>> provider is well used, but when i use the MIME type text/XML
>> jersey generate his own marshaller and so failed to create the
>> JAXBContext (because it is a little hard).
>>
>>
>> here is my provider (simplified) :
>>
>> import**;
>>
>> @Provider
>> public class CapabilitiesWriter<T extends Capabilities> implements
>> MessageBodyWriter<T> {
>>
>> private static final MarshallerPool pool;
>> static {
>> MarshallerPool pool = // here i build a sort of marshaller
>> }
>>
>> @Override
>> public boolean isWriteable(Class<?> type, Type type1, Annotation[]
>> antns, MediaType mt) {
>> return Capabilities.class.isAssignableFrom(type);
>> }
>>
>> @Override
>> public long getSize(T t, Class<?> type, Type type1, Annotation[]
>> antns, MediaType mt) {
>> return -1;
>> }
>>
>> @Override
>> public void writeTo(T t, Class<?> type, Type type1, Annotation[]
>> antns, MediaType mt, MultivaluedMap<String, Object> mm, OutputStream
>> out) throws IOException, WebApplicationException {
>> Marshaller m = // here i get my marshaller;
>> m.marshal(t, out);
>> }
>>
>> }
>>
>> and in my singleton I return a Response object like this :
>>
>> @GET
>> public Response doGET() throws JAXBException {
>> String currentMIME_Type = "something"; // here i have some
>> process to choose the MIME type
>> Capabilities capa = something; // again i have
>> some process building the object
>>
>> return Response.ok(capa, currentMIME_Type).build();
>> }
>>
>>
>> if "currentMIME_Type"=application/xml allright everything is fine, i
>> enter in the method writeTo of my provider CapabilitiesWriter.
>>
>> if "currentMIME_Type"=text/xml i get a JAXB Exception at (I have 2
>> stack trace, don't know why) :
>>
>> at
>> com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:152)
>>
>> at
>> com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:294)
>>
>> at
>> com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1140)
>>
>> at
>> com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1053)
>>
>> at
>> com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1043)
>>
>> at
>> com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:406)
>>
>> at
>> com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:477)
>>
>> at
>> com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:662)
>>
>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
>> at
>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
>>
>> at
>> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
>>
>> at
>> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
>>
>> at
>> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:201)
>>
>> at
>> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:163)
>>
>> at
>> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
>>
>> at
>> org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:556)
>>
>> at
>> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
>>
>> at
>> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:402)
>>
>> at
>> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:249)
>>
>> at
>> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:267)
>>
>> at
>> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:245)
>>
>> at
>> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:260)
>>
>> at
>> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>
>> at
>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>
>> at java.lang.Thread.run(Thread.java:619)
>>
>>
>> at
>> com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
>>
>> at
>> com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:436)
>>
>> at
>> com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
>>
>> at
>> com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100)
>>
>> at
>> com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143)
>>
>> at
>> com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110)
>>
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>
>> at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>
>> at java.lang.reflect.Method.invoke(Method.java:597)
>> at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
>> at javax.xml.bind.ContextFinder.find(ContextFinder.java:376)
>> 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.getMarshaller(AbstractJAXBProvider.java:155)
>>
>> at
>> com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.getMarshaller(AbstractJAXBProvider.java:134)
>>
>> at
>> com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:145)
>>
>>
>>
>>
>> so my question is, why the MIME type change the way of using
>> provider? and how redirect all mime type to my provider?
>>
>> Thanks,
>>
>> Guilhem legal
>>
>> ---------------------------------------------------------------------
>> 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
>
>
>