Skip to content

Commit dcf523d

Browse files
committed
Merge branch '2.17' into 2.18
2 parents 588b21e + 9d31ec7 commit dcf523d

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

release-notes/CREDITS-2.x

+6
Original file line numberDiff line numberDiff line change
@@ -1765,3 +1765,9 @@ Kyrylo Merzlikin (kirmerzlikin@github)
17651765
Miguel Mendes Ruiz (migmruiz@github)
17661766
* Reported #4428: `ByteBuddy` scope went beyond `test` in version 2.17.0
17671767
(2.17.1)
1768+
1769+
Oddbjørn Kvalsund (oddbjornkvalsund@github)
1770+
* Reported, contributed fix for #4430: Use `ReentrantLock` instead of `synchronized`
1771+
in `DeserializerCache` to avoid deadlock on pinning
1772+
(2.17.1)
1773+

release-notes/VERSION-2.x

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Project: jackson-databind
1313
#4428: `ByteBuddy` scope went beyond `test` in version 2.17.0
1414
(reported by Miguel M-R)
1515
(fix by Joo-Hyuk K)
16+
#4430: Use `ReentrantLock` instead of `synchronized` in `DeserializerCache`
17+
to avoid deadlock on pinning
18+
(reported, fix contributed by Oddbjørn K)
1619
#4435: Cannot deserialize value of type `java.math.BigDecimal` from
1720
String ".05": not a valid representation
1821
(reported by @EAlf91)

src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.fasterxml.jackson.databind.deser;
22

33
import java.util.HashMap;
4+
import java.util.concurrent.locks.ReentrantLock;
45

56
import com.fasterxml.jackson.annotation.JsonFormat;
67
import com.fasterxml.jackson.databind.*;
@@ -52,6 +53,12 @@ public final class DeserializerCache
5253
protected final HashMap<JavaType, JsonDeserializer<Object>> _incompleteDeserializers
5354
= new HashMap<JavaType, JsonDeserializer<Object>>(8);
5455

56+
57+
/**
58+
* We hold an explicit lock while creating deserializers to avoid creating duplicates.
59+
*/
60+
private final ReentrantLock _incompleteDeserializersLock = new ReentrantLock();
61+
5562
/*
5663
/**********************************************************
5764
/* Life-cycle
@@ -246,7 +253,9 @@ protected JsonDeserializer<Object> _createAndCacheValueDeserializer(Deserializat
246253
* limitations necessary to ensure that only completely initialized ones
247254
* are visible and used.
248255
*/
249-
synchronized (_incompleteDeserializers) {
256+
try {
257+
_incompleteDeserializersLock.lock();
258+
250259
// Ok, then: could it be that due to a race condition, deserializer can now be found?
251260
JsonDeserializer<Object> deser = _findCachedDeserializer(type);
252261
if (deser != null) {
@@ -269,6 +278,8 @@ protected JsonDeserializer<Object> _createAndCacheValueDeserializer(Deserializat
269278
_incompleteDeserializers.clear();
270279
}
271280
}
281+
} finally {
282+
_incompleteDeserializersLock.unlock();
272283
}
273284
}
274285

0 commit comments

Comments
 (0)