title: MessageBodyReader not found for media type=application/json
body: <p>I have wrote a JAX-RS server and client both use Jersey. I want to sent a collection of my entities to client and I made this steps:</p>
  
  <ol>
  <li>Made entity extends Serializable</li>
  <li>Wrote a custom provider and extended it to support a collections</li>
  <li>Copy-paste entity and provider to client side</li>
  </ol>
  
  <p>I make a request, it sucessfully handled on the server side by client receives an error:</p>
  
  <pre><code>org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=interface java.util.List, genericType=java.util.List&lt;model.HotelsEntity&gt;.
  org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:225)
  org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:149)
  org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124)
  org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:853)
  org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:812)
  org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:377)
  org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:813)
  org.glassfish.jersey.client.JerseyInvocation.access$600(JerseyInvocation.java:90)
  org.glassfish.jersey.client.JerseyInvocation$3.call(JerseyInvocation.java:693)
  org.glassfish.jersey.internal.Errors.process(Errors.java:315)
  org.glassfish.jersey.internal.Errors.process(Errors.java:297)
  org.glassfish.jersey.internal.Errors.process(Errors.java:228)
  org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
  org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:689)
  org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:405)
  org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:301)
  service.HotelService.getHotels(HotelService.java:30)
  actions.HotelAction.perform(HotelAction.java:42)
  MainServlet.processResponse(MainServlet.java:33)
  MainServlet.doPost(MainServlet.java:22)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
  </code></pre>
  
  <p>Server: </p>
  
  <pre><code>    @GET
  @Produces(MediaType.APPLICATION_JSON)
  public Response getHotelsList(@QueryParam("startDate") String startDate,
                                @QueryParam("endDate") String endDate) {
      List&lt;HotelsEntity&gt; list = hotelService.getAll();
      return ResponseFactory.response(Response.Status.OK, list);
  }
  </code></pre>
  
  <p>Client:</p>
  
  <pre><code>    GenericType&lt;List&lt;HotelsEntity&gt;&gt; genericType = new GenericType&lt;List&lt;HotelsEntity&gt;&gt;(){};
      WebTarget target = client.target(preparePath());
      List&lt;HotelsEntity&gt; hotels = target.request(MediaType.APPLICATION_JSON_TYPE).get(genericType);
  </code></pre>
  
  <p>Provider:</p>
  
  <pre><code>public class JsonProvider&lt;T&gt; implements MessageBodyReader&lt;T&gt;, MessageBodyWriter&lt;T&gt; {
  
  @Override
  public boolean isReadable(Class&lt;?&gt; type, Type genericType, Annotation[] annotations, MediaType mediaType) {
      return MediaType.APPLICATION_JSON.equals(mediaType.getType()) &amp;&amp;
              MediaType.APPLICATION_JSON.equals(mediaType.getSubtype());
  }
  
  @Override
  public T readFrom(Class&lt;T&gt; type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap&lt;String, String&gt; httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
      Gson gson = createGson();
      Reader reader = new InputStreamReader(entityStream, Charset.forName(Constants.UTF_8));
      return gson.fromJson(reader, genericType);
  }
  
  @Override
  public boolean isWriteable(Class&lt;?&gt; type, Type genericType, Annotation[] annotations, MediaType mediaType) {
      return MediaType.APPLICATION_JSON.equals(mediaType.getType()) &amp;&amp;
              MediaType.APPLICATION_JSON.equals(mediaType.getSubtype());
  }
  
  @Override
  public long getSize(T t, Class&lt;?&gt; type, Type genericType, Annotation[] annotations, MediaType mediaType) {
      return -1;
  }
  
  @Override
  public void writeTo(T t, Class&lt;?&gt; type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap&lt;String, Object&gt; httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
      Gson gson = createGson();
      JsonElement element = gson.toJsonTree(entityStream);
      Writer writer = null;
      try {
          writer = new OutputStreamWriter(entityStream, Charset.forName(Constants.UTF_8));
          gson.toJson(element, writer);
      } finally {
          if (writer != null) {
              writer.flush();
          }
      }
  }
  
  private Gson createGson() {
      return new GsonBuilder().setPrettyPrinting().create();
  }
  </code></pre>
  
  <p>}</p>
  
  <pre><code>@Provider
  public class JsonCollection extends JsonProvider&lt;Collection&lt;? extends HospitalityEntity&gt;&gt; {}
  
  @Entity
  @Table(name = "hotels", schema = "", catalog = "mydb")
  public class HotelsEntity implements HospitalityEntity{
  private int idHotel;
  private String name;
  private String region;
  private String description;
  
  @Id
  @Column(name = "id_hotel")
  public int getIdHotel() {
      return idHotel;
  }
  
  public void setIdHotel(int idHotel) {
      this.idHotel = idHotel;
  }
  
  @Basic
  @Column(name = "name")
  public String getName() {
      return name;
  }
  
  public void setName(String name) {
      this.name = name;
  }
  
  @Basic
  @Column(name = "region")
  public String getRegion() {
      return region;
  }
  
  public void setRegion(String region) {
      this.region = region;
  }
  
  @Basic
  @Column(name = "description")
  public String getDescription() {
      return description;
  }
  
  public void setDescription(String description) {
      this.description = description;
  }
  
  
  @Override
  public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
  
      HotelsEntity that = (HotelsEntity) o;
  
      if (idHotel != that.idHotel) return false;
      if (description != null ? !description.equals(that.description) : that.description != null) return false;
      if (name != null ? !name.equals(that.name) : that.name != null) return false;
      if (region != null ? !region.equals(that.region) : that.region != null) return false;
  
      return true;
  }
  
  @Override
  public int hashCode() {
      int result = idHotel;
      result = 31 * result + (name != null ? name.hashCode() : 0);
      result = 31 * result + (region != null ? region.hashCode() : 0);
      result = 31 * result + (description != null ? description.hashCode() : 0);
      return result;
  }
  }
  </code></pre>