Unreachable Anonymous ScopedValue
ID |
java.scoped_value_anonymous_instance |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
reliability |
Description
Reports a ScopedValue.newInstance() call that appears directly as the first argument of a
ScopedValue.where(..) call — the instance is created anonymously and never stored anywhere.
A where(..) whose first argument is a name — a field or a local, however that local was
itself initialised — is the documented fix and is not reported.
Rationale
A ScopedValue is the key used to retrieve its own bound value with get(). Creating the
instance anonymously inside where(..) throws that key away the moment the binding is created:
no variable holds a reference to it, so nothing inside the bound task — nor anywhere else in the
program — has any way to call get() on it. The binding still runs without error; the value it
carries is simply unreachable forever.
public void routeShipment() {
ScopedValue.where(ScopedValue.newInstance(), "NORTH-DOCK-7").run(() -> {
packShipment(); // no way to retrieve "NORTH-DOCK-7" here -- the key was never stored
});
}
Remediation
Assign the ScopedValue instance to a stable reference — typically a static final field —
before using it in a binding:
private static final ScopedValue<String> WAREHOUSE_CODE = ScopedValue.newInstance();
public void routeShipment() {
ScopedValue.where(WAREHOUSE_CODE, "NORTH-DOCK-7").run(() -> {
packShipment();
});
}
void packShipment() {
System.out.println("Dispatching from warehouse " + WAREHOUSE_CODE.get());
}