Jersey Error: MessageBodyReader not found for media type=application/json

29,684

I see you have two different provider dependencies jersey-media-moxy and jersey-media-json-jackson. I've always had a problem with Maps with MOXy. I guess they don't play well. Seems you will need to use an adapter to make it play nice, as seen here from Blaise Doughan.

That being said, I requested (in the comments above) to see your Server side configuration, as MOXy will auto configure itself, and take precedence over the jersey-media-json-jackson. Why, I'm not sure, this is just what I've always experienced. So I'm curious how the Server side didn't fail even before the response came back to the client. Unless you confgiure the JacksonFeature with the server application, in which you should have also configured it with the client. (This is only the case, because you also have MOXy dependency).

Anyway, if you don't want to go through the hassle creating adapters, as seen in the link above, just get rid of the jersey-media-moxy dependency. jersey-media-json-jackson will also auto configure it feature. You should just use one or the other.


As an aside:

@Path("/getAllNews"). Path segments should be nouns, unless they are controller resources, which normally perform some action, other than normal CRUD operations (e.g. /register). The HTTP method already consists of the verb to which each CRUD action should be performed.

  • Create - POST
  • Retriecve - GET
  • Update = PUT
  • Delete - DELETE

Just some semantics to consider :-)


UPDATE

The problem is with the New key. Jackson doesn't know how to deserialize this. Since you are willing wot switch the key and value type, just change have the toString return the name in the Term class, and it should be ok.

Share:
29,684
Cheknov
Author by

Cheknov

Updated on July 31, 2022

Comments

  • Cheknov
    Cheknov almost 2 years

    i'm trying to implement a small REST API using Jersey as framework, in principle the code worked fine but when I try to do a 'GET' of a hash table, I get the following error:

    nov 23, 2014 4:27:40 PM org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor aroundReadFrom
    GRAVE: MessageBodyReader not found for media type=application/json, type=interface java.util.Map, genericType=java.util.Map<upf.dad.proyecto.New, upf.dad.proyecto.Term>.
    1440 [DefaultQuartzScheduler_Worker-3] ERROR org.quartz.core.JobRunShell - Job DEFAULT.testJob3 threw an unhandled Exception: 
    org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=interface java.util.Map, genericType=java.util.Map<upf.dad.proyecto.New, upf.dad.proyecto.Term>.
        at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:230)
        at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154)
        at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
        at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851)
        at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:810)
    )
        at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:313)
        at upf.dad.proyecto.HotTopicDetector.News(HotTopicDetector.java:110)
        at upf.dad.proyecto.ScheduledTestJob3.execute(ScheduledTestJob3.java:11)
    1440 [DefaultQuartzScheduler_Worker-3] ERROR org.quartz.core.ErrorLogger - Job (DEFAULT.testJob3 threw an exception.
    org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=interface java.util.Map, genericType=java.util.Map<upf.dad.proyecto.New, upf.dad.proyecto.Term>.]
        at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
    Caused by: org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=interface java.util.Map, genericType=java.util.Map<upf.dad.proyecto.New, upf.dad.proyecto.Term>.
        at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:230)
        at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154)
        at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
        at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851)
        at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:810)
        at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:368)
        at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:846)
        at org.glassfish.jersey.client.JerseyInvocation.access$600(JerseyInvocation.java:91)
        at org.glassfish.jersey.client.JerseyInvocation$3.call(JerseyInvocation.java:705)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
        at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:701)
        at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:417)
        at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:313)
        at upf.dad.proyecto.HotTopicDetector.News(HotTopicDetector.java:110)
        at upf.dad.proyecto.ScheduledTestJob3.execute(ScheduledTestJob3.java:11)
        at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
        ... 1 more
    

    This is the problematic line:

        Client client = ClientBuilder.newClient();
    
        WebTarget targetGetAllNews = client.target("http://localhost:15000").path("news/getAllNews");
    
    
        Map<New, Term> NewsAll = targetGetAllNews.request(
                 MediaType.APPLICATION_JSON_TYPE).get(new GenericType<Map<New, Term>>(){});
    

    and this is how I implemented the service:

    @GET
    @Path("/getAllNews")
    @Produces(MediaType.APPLICATION_JSON)
    public Map<New, Term> getAllNews() {
        return NewsCrawler.getNewAndTerm();
    }
    

    pom.xml (maven dependencies)

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>upf.dad.proyecto</groupId>
    <artifactId>JAXRS-proyecto</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
    <!-- Rome RSS and Atom utilities @ http://rometools.github.io/rome/ -->        
    <dependency>
            <groupId>rome</groupId>
            <artifactId>rome</artifactId>             
            <version>1.0</version>
    </dependency>
    
    <!-- jsoup HTML parser library @ http://jsoup.org/ -->         
    <dependency>             
            <groupId>org.jsoup</groupId>             
            <artifactId>jsoup</artifactId>             
            <version>1.8.1</version>               
    </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.twitter4j</groupId>
            <artifactId>twitter4j-core</artifactId>
            <version>4.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.12</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-jdk-http</artifactId>
            <version>2.12</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
            <version>2.12</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.12</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.13</version>
        </dependency>
    </dependencies>
    </project>
    

    Server side configuration:

    public class NewsCrawlerRestServer {
    
    public static void main(String[] args) throws IOException {
    
        URI baseUri = UriBuilder.fromUri("http://localhost/").port(15000).build();
        ResourceConfig config = new ResourceConfig(NewsCrawlerServices.class, HotTopicDetectorServices.class);
        config.register(JacksonFeature.class);
        HttpServer server = JdkHttpServerFactory.createHttpServer(baseUri, config);
        System.out.println("Server started...");
    
        }
    }
    

    Error registering Jackson in the client:

    org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: javax.ws.rs.ProcessingException: Error reading entity from input stream.]
            at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
            at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
        Caused by: javax.ws.rs.ProcessingException: Error reading entity from input stream.
            at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:866)
            at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:810)
            at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:368)
            at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:846)
            at org.glassfish.jersey.client.JerseyInvocation.access$600(JerseyInvocation.java:91)
            at org.glassfish.jersey.client.JerseyInvocation$3.call(JerseyInvocation.java:705)
            at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
            at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
            at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
            at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
            at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:701)
            at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:417)
            at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:313)
            at upf.dad.proyecto.HotTopicDetector.News(HotTopicDetector.java:112)
            at upf.dad.proyecto.ScheduledTestJob3.execute(ScheduledTestJob3.java:11)
            at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
            ... 1 more
        Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class upf.dad.proyecto.New]
            at com.fasterxml.jackson.databind.deser.DeserializerCache._handleUnknownKeyDeserializer(DeserializerCache.java:580)
            at com.fasterxml.jackson.databind.deser.DeserializerCache.findKeyDeserializer(DeserializerCache.java:170)
            at com.fasterxml.jackson.databind.DeserializationContext.findKeyDeserializer(DeserializationContext.java:404)
            at com.fasterxml.jackson.databind.deser.std.MapDeserializer.createContextual(MapDeserializer.java:232)
            at com.fasterxml.jackson.databind.DeserializationContext.handleSecondaryContextualization(DeserializationContext.java:572)
            at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:386)
            at com.fasterxml.jackson.databind.ObjectReader._findRootDeserializer(ObjectReader.java:1380)
            at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1228)
            at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:677)
            at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:777)
            at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:264)
            at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:234)
            at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154)
            at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
            at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851)
    

    New Class:

    package upf.dad.proyecto;
    
    import java.util.Date;
    
    public class New {
    
    private String tittle;
    private String description;
    private Date date;
    private String link;
    
    public New(){
    
    }
    
    public New(String t, String d, Date date, String l){
        this.tittle = t;
        this.description = d;
        this.date = date;
        this.link = l;
    }
    
    public String getTittle() {
        return tittle;
    }
    
    public void setTittle(String tittle) {
        this.tittle = tittle;
    }
    
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    public Date getDate() {
        return date;
    }
    
    public void setDate(Date date) {
        this.date = date;
    }
    
    public String getLink() {
        return link;
    }
    
    public void setLink(String link) {
        this.link = link;
    }
    
    @Override
    public String toString() {
        return "New [tittle=" + tittle + ", description=" + description
                + ", date=" + date + ", link=" + link + "]";
    }
    
    
    }
    

    Term class:

    package upf.dad.proyecto;
    
    public class Term {
    
    private String word;
    
    public Term(){
    
    }
    
    public Term(String word){
        this.word = word;
    
    }
    
    public String getWord(){
        return word;
    }
    
    public void setWord(String _word){
        word = _word;
    }
    
    @Override
    public String toString() {
        return "Termino =" + word + "]";
    }
    }
    

    can someone help me please to return the map?

  • Cheknov
    Cheknov over 9 years
    Thanks for your answer, I updated the post with the required information. As you can see, to return the map I use the Jackson as JSON provider adding the dependency to the pom.xml file and registering it in the ResourceConfig object before starting the HttpServer but still not working...
  • Paul Samsotha
    Paul Samsotha over 9 years
    Try registering it with the client also, since the problem is on the client side (since the problem is with the client) i.e. client.register(...). Since you have the MOXy still, the client may be implicitly registered with MOXy.
  • Cheknov
    Cheknov over 9 years
    thanks for the help, again, I updated the post with the error I get when I register the client...I have been considering also use the adapter, but I do not know how to implement it.
  • Paul Samsotha
    Paul Samsotha over 9 years
    please show the New and Term class. I created my own to test and it worked fine.
  • Cheknov
    Cheknov over 9 years
    You can see the classes requested, thanks. Could you give an example of how to use GenericEntity?
  • Paul Samsotha
    Paul Samsotha over 9 years
    I see the problem. Keys in JSON are supposed to be Strings. If you want to use an object, 1) You need to create a custom serializer that will serialize and deserializer the object to a String 2) it'll look funky in JSON
  • Paul Samsotha
    Paul Samsotha over 9 years
    Are you sure you meant for the New to be the key, and not the other way around? Term only has one field, which will be easier to represent as a key. New has four fields, which is an awkward key
  • Cheknov
    Cheknov over 9 years
    I can change the order without any problem, that would solve the problem?
  • Paul Samsotha
    Paul Samsotha over 9 years
    No you still need a serializer/deserializer, but it's pretty easy. I just suggested switching the order, because trying to represent 4 fields as a json key just looks weird. I'll put together something. Give me a few minutes
  • Paul Samsotha
    Paul Samsotha over 9 years
    So it actually looks like just using the Term type for the key makes it work. But the actual text in the json is the toString So you can just have it return the name. No need for any serializers
  • Cheknov
    Cheknov over 9 years
    So, If I change the toString method to return only the name, will work? I get the same first error: GRAVE: MessageBodyReader not found for media type=application/json, type=interface java.util.Map, genericType=java.util.Map etc. by just changing the toString method like this: public String toString() {return word;}
  • Paul Samsotha
    Paul Samsotha over 9 years
    Did you register the client with the JacksonFeature. You should get rid of the MOXy dependency if you're not going to use it. The Jackson module should autoconfigure itself. But the MOXy will take precedence
  • Cheknov
    Cheknov over 9 years
    Yes, I closed Eclipse, I have reopened and no longer returns an error. Thank you very much!