From 21b1da1bea56e2b442c2e0c9a580547356268426 Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Fri, 22 Apr 2016 08:05:33 -0400 Subject: [PATCH] Kill thread local leak This commit modifies InjectorImpl to prevent a thread local leak in certain web containers. This leak can arise when starting a node client inside such a web container. The underlying issue is that the ThreadLocal instance was created via an anonymous class. Such an anonymous class has an implicit reference back to the InjectorImpl in which it was created. The solution here is to not use an anonymous class but instead just create the reference locally and set it on the thread local. Relates #17921 --- .../elasticsearch/common/inject/InjectorImpl.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/common/inject/InjectorImpl.java b/core/src/main/java/org/elasticsearch/common/inject/InjectorImpl.java index c8f80ef7fd6..ae4cd744dd0 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/InjectorImpl.java +++ b/core/src/main/java/org/elasticsearch/common/inject/InjectorImpl.java @@ -84,12 +84,7 @@ class InjectorImpl implements Injector, Lookups { if (parent != null) { localContext = parent.localContext; } else { - localContext = new ThreadLocal() { - @Override - protected Object[] initialValue() { - return new Object[1]; - } - }; + localContext = new ThreadLocal<>(); } } @@ -867,13 +862,17 @@ class InjectorImpl implements Injector, Lookups { return getProvider(type).get(); } - final ThreadLocal localContext; + private final ThreadLocal localContext; /** * Looks up thread local context. Creates (and removes) a new context if necessary. */ T callInContext(ContextualCallable callable) throws ErrorsException { Object[] reference = localContext.get(); + if (reference == null) { + reference = new Object[1]; + localContext.set(reference); + } if (reference[0] == null) { reference[0] = new InternalContext(); try {