-
Bug
-
Resolution: Unresolved
-
Major
-
None
-
None
-
None
If two methods in a resource have the same return type, the incorrect reader or writer might be cached and used. The cache is based on the return type and the annotations on the type. However, if executing from a Client for example, then different providers may be registered that are not used.
Example Resource
@Path("/status") public class PortalStatusRest { @Path("/jsr310") @GET @Produces(MediaType.APPLICATION_JSON) public Response jsr310Response() { JSR310Response response = new JSR310Response(); response.setServerTime(ZonedDateTime.now()); return Response.ok(response).build(); } @Path("/time") @GET @Produces(MediaType.APPLICATION_JSON) public Response trigger() { try (Client client = ClientBuilder.newBuilder().build()) { JSR310Response response = client.target("http://localhost:8080/web-app/rest/status/jsr310") .request() .get() .readEntity(JSR310Response.class); return Response.ok(response).build(); } } @Path("/time/register/1") @GET @Produces(MediaType.APPLICATION_JSON) public Response triggerRegistered1() { try (Client client = ClientBuilder.newBuilder().register(JacksonDatatypeJacksonProducer.class).build()) { JSR310Response response = client.target("http://localhost:8080/web-app/rest/status/jsr310") .request() .get() .readEntity(JSR310Response.class); return Response.ok(response).build(); } } public static class JSR310Response { private ZonedDateTime serverTime; public ZonedDateTime getServerTime() { return serverTime; } public void setServerTime(ZonedDateTime serverTime) { this.serverTime = serverTime; } } }
if you invoke the path status/time first, then when you execute status/time/register/1 the wrong writer is resolved and a failure occurs. The JacksonDatatypeJacksonProducer is not used, which it should be in this case.
JacksonDatatypeJacksonProducer.java
@Provider @Produces(MediaType.APPLICATION_JSON) public class JacksonDatatypeJacksonProducer implements ContextResolver<ObjectMapper> { private final ObjectMapper json; public JacksonDatatypeJacksonProducer() { this.json = JsonMapper.builder() .findAndAddModules() .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) .configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false) .build(); } @Override public ObjectMapper getContext(final Class<?> type) { return json; } }