Skip to content

Commit

Permalink
Fix #3771: avoid Class leak by using class name (not class) as Map ke…
Browse files Browse the repository at this point in the history
…y for cache
  • Loading branch information
cowtowncoder committed Feb 5, 2023
1 parent de62c67 commit c4445c1
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,13 @@ public class JacksonAnnotationIntrospector
* need for actual meta-annotation introspection.
*<p>
* Non-final only because it needs to be re-created after deserialization.
*<p>
* Starting with 2.15 key is {@link String} (before that was {@link Class})
* to avoid unintentional retention of third-party annotation class types.
*
* @since 2.7
*/
protected transient LRUMap<Class<?>,Boolean> _annotationsInside = new LRUMap<Class<?>,Boolean>(48, 48);
protected transient LRUMap<String,Boolean> _annotationsInside = new LRUMap<String,Boolean>(48, 48);

/*
/**********************************************************
Expand Down Expand Up @@ -112,7 +115,7 @@ public Version version() {

protected Object readResolve() {
if (_annotationsInside == null) {
_annotationsInside = new LRUMap<Class<?>,Boolean>(48, 48);
_annotationsInside = new LRUMap<>(48, 48);
}
return this;
}
Expand Down Expand Up @@ -155,11 +158,12 @@ public boolean isAnnotationBundle(Annotation ann) {
// mostly in degenerate cases where introspection used more often than
// it should (like recreating ObjectMapper once per read/write).
// But it may be more beneficial on platforms like Android (should verify)
Class<?> type = ann.annotationType();
Boolean b = _annotationsInside.get(type);
final Class<?> type = ann.annotationType();
final String typeName = type.getName();
Boolean b = _annotationsInside.get(typeName);
if (b == null) {
b = type.getAnnotation(JacksonAnnotationsInside.class) != null;
_annotationsInside.putIfAbsent(type, b);
_annotationsInside.putIfAbsent(typeName, b);
}
return b.booleanValue();
}
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/com/fasterxml/jackson/databind/util/LRUMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@
* on assumption that all use cases are for caching where persistence
* does not make sense. The only thing serialized is the cache size of Map.
*<p>
* NOTE: since Jackson 2.14, the implementation evicts the least recently used
* entry when max size is reached.
*<p>
* Since Jackson 2.12, there has been pluggable {@link LookupCache} interface which
* allows users, frameworks, provide their own cache implementations.
*<p>
* Snce Jackson 2.14, the implementation
*<ul>
*<li>Evicts the least recently used entry when max size is reached
* </li>
*<li>Is thread-safe and does NOT require external synchronization
* </li>
*</ul>
*/
public class LRUMap<K,V>
implements LookupCache<K,V>, // since 2.12
Expand Down

0 comments on commit c4445c1

Please sign in to comment.