rspec/rules/S5164/java/rule.adoc
Fred Tingaud 16f6c0aecf
Inline adoc when include has no additional value (#1940)
Inline adoc files when they are included exactly once.

Also fix language tags because this inlining gives us better information
on what language the code is written in.
2023-05-25 14:18:12 +02:00

99 lines
2.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

== Why is this an issue?
``++ThreadLocal++`` variables are supposed to be garbage collected once the holding thread is no longer alive. Memory leaks can occur when holding threads are re-used which is the case on application servers using pool of threads.
To avoid such problems, it is recommended to always clean up ``++ThreadLocal++`` variables using the ``++remove()++`` method to remove the current threads value for the ``++ThreadLocal++`` variable.
In addition, calling ``++set(null)++`` to remove the value might keep the reference to ``++this++`` pointer in the map, which can cause memory leak in some scenarios. Using ``++remove++`` is safer to avoid this issue.
=== Noncompliant code example
[source,java]
----
public class ThreadLocalUserSession implements UserSession {
private static final ThreadLocal<UserSession> DELEGATE = new ThreadLocal<>();
public UserSession get() {
UserSession session = DELEGATE.get();
if (session != null) {
return session;
}
throw new UnauthorizedException("User is not authenticated");
}
public void set(UserSession session) {
DELEGATE.set(session);
}
public void incorrectCleanup() {
DELEGATE.set(null); // Noncompliant
}
// some other methods without a call to DELEGATE.remove()
}
----
=== Compliant solution
[source,java]
----
public class ThreadLocalUserSession implements UserSession {
private static final ThreadLocal<UserSession> DELEGATE = new ThreadLocal<>();
public UserSession get() {
UserSession session = DELEGATE.get();
if (session != null) {
return session;
}
throw new UnauthorizedException("User is not authenticated");
}
public void set(UserSession session) {
DELEGATE.set(session);
}
public void unload() {
DELEGATE.remove(); // Compliant
}
// ...
}
----
=== Exceptions
Rule will not detect non-private ``++ThreadLocal++`` variables, because ``++remove()++`` can be called from another class.
== Resources
* https://www.baeldung.com/java-memory-leaks[Understanding Memory Leaks in Java]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Call the "remove()" on "XXX".
'''
== Comments And Links
(visible only on this page)
=== on 25 Jul 2019, 18:38:21 Tibor Blenessy wrote:
For reference, issue in spring-cloud \https://github.com/spring-cloud/spring-cloud-sleuth/issues/27
endif::env-github,rspecator-view[]