From 4f3ac8dc4e25acf4693f3c5b025a5918d0da326a Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 6 Jun 2024 09:38:11 -0700 Subject: [PATCH 1/3] Revert "Fix #4561 (revert #4430) (#4562)" This reverts commit b89886a5bf0e8292e4d2db0d45c5ca3422638d9d. --- release-notes/VERSION-2.x | 5 ----- .../databind/deser/DeserializerCache.java | 19 +++++++++++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index c838c78339..53ee3f82a3 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -8,11 +8,6 @@ Project: jackson-databind - -2.17.2 (not yet released) - -#4561: Issues using jackson-databind 2.17.1 with Reactor - (reported by @wdallastella) - 2.17.1 (04-May-2024) #4428: `ByteBuddy` scope went beyond `test` in version 2.17.0 diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java index 1c633fde8a..0282af7213 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java @@ -1,6 +1,7 @@ package com.fasterxml.jackson.databind.deser; import java.util.HashMap; +import java.util.concurrent.locks.ReentrantLock; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.*; @@ -52,6 +53,12 @@ public final class DeserializerCache protected final HashMap> _incompleteDeserializers = new HashMap>(8); + + /** + * We hold an explicit lock while creating deserializers to avoid creating duplicates. + */ + private final ReentrantLock _incompleteDeserializersLock = new ReentrantLock(); + /* /********************************************************** /* Life-cycle @@ -242,10 +249,12 @@ protected JsonDeserializer _createAndCacheValueDeserializer(Deserializat DeserializerFactory factory, JavaType type) throws JsonMappingException { - // Only one thread to construct deserializers at any given point in time; - // limitations necessary to ensure that only completely initialized ones - // are visible and used. - synchronized (_incompleteDeserializers) { + /* Only one thread to construct deserializers at any given point in time; + * limitations necessary to ensure that only completely initialized ones + * are visible and used. + */ + _incompleteDeserializersLock.lock(); + try { // Ok, then: could it be that due to a race condition, deserializer can now be found? JsonDeserializer deser = _findCachedDeserializer(type); if (deser != null) { @@ -268,6 +277,8 @@ protected JsonDeserializer _createAndCacheValueDeserializer(Deserializat _incompleteDeserializers.clear(); } } + } finally { + _incompleteDeserializersLock.unlock(); } } From d327c164a82a051dc54ea33e8d506a466606c442 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 6 Jun 2024 09:39:03 -0700 Subject: [PATCH 2/3] Keep release-notes change --- release-notes/VERSION-2.x | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 53ee3f82a3..c838c78339 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -8,6 +8,11 @@ Project: jackson-databind - +2.17.2 (not yet released) + +#4561: Issues using jackson-databind 2.17.1 with Reactor + (reported by @wdallastella) + 2.17.1 (04-May-2024) #4428: `ByteBuddy` scope went beyond `test` in version 2.17.0 From 23862eccf83a36a977a103ab7ba704c280ab5e63 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 6 Jun 2024 09:42:55 -0700 Subject: [PATCH 3/3] javadoc/comment cleanup --- .../databind/deser/DeserializerCache.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java index 0282af7213..d3591af73d 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java @@ -56,6 +56,9 @@ public final class DeserializerCache /** * We hold an explicit lock while creating deserializers to avoid creating duplicates. + * Guards {@link #_incompleteDeserializers}. + * + * @since 2.17 */ private final ReentrantLock _incompleteDeserializersLock = new ReentrantLock(); @@ -169,10 +172,9 @@ public JsonDeserializer findValueDeserializer(DeserializationContext ctx // If not, need to request factory to construct (or recycle) deser = _createAndCacheValueDeserializer(ctxt, factory, propertyType); if (deser == null) { - /* Should we let caller handle it? Let's have a helper method - * decide it; can throw an exception, or return a valid - * deserializer - */ + // Should we let caller handle it? Let's have a helper method + // decide it; can throw an exception, or return a valid + // deserializer deser = _handleUnknownValueDeserializer(ctxt, propertyType); } } @@ -211,9 +213,8 @@ public boolean hasValueDeserializerFor(DeserializationContext ctxt, DeserializerFactory factory, JavaType type) throws JsonMappingException { - /* Note: mostly copied from findValueDeserializer, except for - * handling of unknown types - */ + // Note: mostly copied from findValueDeserializer, except for + // handling of unknown types JsonDeserializer deser = _findCachedDeserializer(type); if (deser == null) { deser = _createAndCacheValueDeserializer(ctxt, factory, type); @@ -249,10 +250,9 @@ protected JsonDeserializer _createAndCacheValueDeserializer(Deserializat DeserializerFactory factory, JavaType type) throws JsonMappingException { - /* Only one thread to construct deserializers at any given point in time; - * limitations necessary to ensure that only completely initialized ones - * are visible and used. - */ + // Only one thread to construct deserializers at any given point in time; + // limitations necessary to ensure that only completely initialized ones + // are visible and used. _incompleteDeserializersLock.lock(); try { // Ok, then: could it be that due to a race condition, deserializer can now be found?