-
Bug
-
Resolution: Done
-
Critical
-
4.5.5.Final
-
None
Under high contention during startup, we observe:
Caused by: javax.ws.rs.ProcessingException: java.lang.NullPointerException: Cannot invoke "java.util.Map.put(Object, Object)" because "cache" is null at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:251) at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:88) at org.jboss.resteasy.specimpl.AbstractBuiltResponse.readEntity(AbstractBuiltResponse.java:256) at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:163) at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.lambda$getResponseTypeExtractor$6(ClientInvocation.java:613) at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.lambda$asyncSubmit$10(ClientInvocation.java:756) at org.jboss.resteasy.client.jaxrs.engines.jetty.JettyClientEngine$2.complete(JettyClientEngine.java:198) at org.jboss.resteasy.client.jaxrs.engines.jetty.JettyClientEngine$2.onSuccess(JettyClientEngine.java:184) ... 24 more Caused by: java.lang.NullPointerException: Cannot invoke "java.util.Map.put(Object, Object)" because "cache" is null at org.jboss.resteasy.core.MediaTypeMap.getPossible(MediaTypeMap.java:584) at org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl.resolveMessageBodyReader(ResteasyProviderFactoryImpl.java:576) at org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl.getClientMessageBodyReader(ResteasyProviderFactoryImpl.java:568) at org.jboss.resteasy.core.interception.jaxrs.ClientReaderInterceptorContext.resolveReader(ClientReaderInterceptorContext.java:54) at org.jboss.resteasy.core.interception.jaxrs.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:130) at org.jboss.resteasy.core.interception.jaxrs.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:75) at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:214)
ResteasyProviderFactoryImpl holds a ConcurrentMap with MediaTypeMap values.
MediaTypeMap maintains a cache:
if (useCache) { // don't care about variable volatility. Really rare to add entries post boot Map<CachedMediaTypeAndClass, List<T>> cache = classCache; if (classCache == null) { cache = new HashMap<>(); classCache = cache; } cache.put(cacheEntry, cached); }
Note in particular, classCache is read twice. If the first read yields a null value, but a competing thread writes before the second read, you may end up storing into a null map. I appreciate that this code probably wants to be fast rather than cache perfectly, but this is not thread-safe in a way that may crash rather than simply under-perform.
- is related to
-
RESTEASY-2683 NPE in ApacheHttpClient43Test because cache is null in MediaTypeMap
- Resolved