Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

A common misconception is that shared references to immutable objects are immediately visible across multiple threads as soon as they are updated. For example, a developer can mistakenly believe that a class containing fields that refer only to immutable objects is itself immutable and consequently thread-safe.

Section Wiki MarkupThe Java™ Programming Language, Fourth Edition \[[JPL 06|AA. Java References#JPL 06]\], "Section 14.10.2. , "Final Fields and Security" states:," of Java Programming Language, Fourth Edition [JPL 2006] states:

... you can use final fields to define immutable objects. There is a common misconception that shared access to immutable objects does not require any synchronization because the state of the object never changes. This is a misconception in general because it relies on the assumption that a thread will be guaranteed to see the initialized state of the immutable object, and that need not be the case. The problem is that, while the shared object is immutable, the reference used to access the shared object is itself shared and often mutable. Consequently, a correctly synchronized program must synchronize access to that shared reference, but often programs do not do this, because programmers do not recognize the need to do it. For example, suppose one thread creates a String object and stores a reference to it in a static field. A second thread then uses that reference to access the string. There is no guarantee, based on what we've discussed so far, that the values written by the first thread when constructing the string will be seen by the second thread when it accesses the string.

References to both immutable and mutable objects must be made visible to all the threads. Immutable objects can be shared safely among multiple threads. However, references to mutable objects can be made visible before the objects are fully constructed. TSM03-J. Do not publish partially initialized objects describes object construction and visibility issues specific to mutable objectsIt is not always the case that classes that use immutable objects are themselves immutable.

Noncompliant Code Example

This noncompliant code example publishes the helper field prematurely through the getHelper() method. Multiple threads may initialize the field, making class Foo mutable. consists of the immutable Helper class:

Code Block
bgColor#FFCCCC
// Immutable Helper
public final class FooHelper {
  private Helperfinal int helpern;

  public Helper(int getHelper(n) {
    this.n return= helpern;
  }

  // ...
}

and a mutable Foo class:

Code Block
bgColor#FFCCCC
final class Foopublic void initialize(int num) {
  private Helper helper = new Helper(num);
  }
}

// Immutable Helper
public classHelper HelpergetHelper() {
  private final intreturn nhelper;
  }

  public Helpervoid setHelper(int nnum) {
    this.nhelper = nnew Helper(num);
  }
  // ...
}

If The getHelper() method publishes the mutable helper field. Because the Helper class is immutable, it cannot be changed after it is initialized and will always be properly constructed. However, this does not prevent a thread from accessing .

Furthermore, because Helper is immutable, it is always constructed properly before its reference is made visible, in compliance with TSM03-J. Do not publish partially initialized objects. Unfortunately, a separate thread could observe a stale reference in the helper field of class Foo such that it misses observing the most recent value set by some other threadthe Foo class.

Compliant Solution (

...

Synchronization)

This compliant solution synchronizes the methods of the Foo class Foo to ensure that no thread sees a partially initialized helper. stale Helper reference:

Code Block
bgColor#CCCCFF

final class Foo {
  private Helper helper;

  public synchronized Helper getHelper() {
    return helper;
  }

  public synchronized void initializesetHelper(int num) {
    helper = new Helper(num);
  }
}

The immutable Helper class remains unchanged.

Compliant Solution (volatile)

Immutable members References to immutable member objects can be safely published made visible by declaring them volatile as described in CON00-J. Declare shared variables as volatile to ensure visibility and prevent reordering of accesses.:

Code Block
bgColor#CCCCFF

final class Foo {
  private volatile Helper helper;

  public synchronized Helper getHelper() {
    return helper;
  }

  public synchronized void initializesetHelper(int num) {
    helper = new Helper(num);
  }
}

The immutable Helper class remains unchanged.

Compliant Solution (java.util.concurrent Utilities)

This compliant solution wraps the mutable reference to the immutable Helper object within an AtomicReference wrapper that can be updated atomically:

Code Block
bgColor#CCCCFF
final class Foo {
  private final AtomicReference<Helper> helperRef =
      new AtomicReference<Helper>();

  public Helper getHelper() {
    return helperRef.get();
  }

  public void setHelper(int num) {
    helperRef.set(new Helper(num));
  }
}

The immutable Helper class remains unchanged.

Risk Assessment

The incorrect assumption that classes containing that contain only references to immutable objects are themselves immutable is misleading and can cause serious thread-safety issues.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

CON28

VNA01-J

low

Low

probable

Probable

medium

Medium

P4

L2

L3

Automated Detection

TODO

Related Vulnerabilities

Search for vulnerabilities resulting from the violation Some static analysis tools are capable of detecting violations of this rule on the CERT website.

References

Wiki Markup
\[[API 06|AA. Java References#API 06]\] 
\[[JPL 06|AA. Java References#JPL 06]\], 14.10.2. Final Fields and Security:

.

ToolVersionCheckerDescription
ThreadSafe
Include Page
ThreadSafe_V
ThreadSafe_V

CCE_SL_INCONSISTENT
CCE_CC_CALLBACK_ACCESS
CCE_SL_MIXED
CCE_SL_INCONSISTENT_COL
CCE_SL_MIXED_COL
CCE_CC_UNSAFE_CONTENT

Implemented
SonarQube
Include Page
SonarQube_V
SonarQube_V
S2886Getters and setters should be synchronized in pairs


Bibliography

[API 2014]


[JPL 2006]

Section 14.10.2, "Final Fields and Security"

Issue Tracking

Tasklist
Review List
Review List
||Completed||Priority||Locked||CreatedDate||CompletedDate||Assignee||Name||
|F|M|F|1270826173609|          |dmohindr|"Unfortunately, a separate thread -could- *can* observe a stale reference in the helper field of the Foo class."|
|T|M|F|1270826698362|1271441478121|svoboda|"This compliant solution synchronizes the methods of *class* Foo -class- " (it sounds strange with class occuring after Foo)|


...

Image Added Image Added Image AddedFIO36-J. Do not create multiple buffered wrappers on an InputStream      09. Input Output (FIO)      09. Input Output (FIO)