Stateless Bean Mutable Field
ID |
java.stateless_bean_mutable_field |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
reliability |
Description
Reports an instance field in a class annotated @Stateless that is neither static nor final and carries no container-injection annotation (@EJB, @Inject, @PersistenceContext, @PersistenceUnit, @Resource).
Rationale
A stateless session bean is pooled and reused by its container: after one client’s method call finishes, the same instance can be handed to a completely different client on the next call, and the container never clears its instance fields in between. Storing per-request data in an ordinary field therefore leaks that data to whichever client the pool assigns the instance to next.
@Stateless
public class ReservationService {
private int activeSessionId; // Bad - may leak to the next client sharing this instance
private int retryLimit = 4; // Bad - still a mutable field, even though 4 never changes today
}
Remediation
Make the field static final when it is truly a constant, delegate shared state to an injected, container-managed collaborator, move the value to a method-local variable, or switch the bean to @Stateful when per-client state is genuinely needed.
@Stateless
public class ReservationService {
private static final int RETRY_LIMIT = 4; // Good - constant
@EJB
private ReservationMetrics metrics; // Good - container-managed, safe to share
void reserve(int sessionId) {
int activeSessionId = sessionId; // Good - local to this invocation
metrics.recordReservation();
}
}