Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: finished exception

...

Because the the Helper class is declared as public, it uses a private lock to handle synchronization in conformance with CON04-J. Use private final lock objects to synchronize classes that may interact with untrusted code.

Exceptions

Wiki Markup*CON26-EX1:* Security sensitive objects prior to Java SE 6 (but under the revised Java Memory Model under JSR-133 (JMM) \[[JSR-133 04|AA. Java References#JSR-133 04]\]) checked a {{volatile}} {{boolean}} flag in every method of the class to ensure that the object is unusable when it is in an uninitialized or partially-initialized state. The flag was always set in the last statement of the initializing code. This guideline may be violated if the code uses this technique for providing backward compatibility or if the caller is untrusted and consequently, may not declare the object reference as volatile.

This exception uses a volatile initialized flag. The corresponding Foo class is the same as the noncompliant code example.

Code Block
bgColor#CCCCFF

public class Helper {
  private int n;
  private volatile boolean initialized; // Defaults to false

  public Helper(int n) {
    this.n = n;
    this.initialized = true;
  }
  
  public void doSomething() {
    if (!initialized) {
      throw new SecurityException("Cannot use partially initialized instance");
    }
    // ... 
  }
  // ...
}

This ensures that even if the reference to the Helper object instance is published before its initialization is over, the instance is unusable. The instance is unusable because every method within Helper must check the flag to determine whether the initialization has finished.

Classes that prevent partially initialized objects from being used may publish partially initialized objects. This may be implemented, for example, by setting a volatile boolean flag in the last statement of the initializing code and then ensuring this flag was set before allowing the execution of any class methods.

The following compliant solution illustrates this technique:

Code Block
bgColor#CCCCFF

public class Helper {
  private int n;
  private volatile boolean initialized; // Defaults to false

  public Helper(int n) {
    this.n = n;
    this.initialized = true;
  }
  
  public void doSomething() {
    if (!initialized) {
      throw new SecurityException("Cannot use partially initialized instance");
    }
    // ... 
  }
  // ...
}

This ensures that even if the reference to the Helper object instance is published before its initialization is over, the instance is unusable. The instance is unusable because every method within Helper must check the flag to determine whether the initialization has finished. Wiki MarkupFrom SE 6 onwards, this technique is superseded by a mechanism that recommends performing any checks that might leave the code uninitialized as a result of exceptions, in a call to a private constructor or a superclass constructor. An exception thrown before the completion of {{Object}}'s constructor ensures that a subclass cannot obtain a partially initialized instance \[[SCG 09|AA. Java References#SCG 09]\]. (For more information, see the guideline [OBJ04-J. Do not allow partially initialized objects to be accessed])

Risk Assessment

Failing to synchronize access to shared mutable data can cause different threads to observe different states of the object or a partially initialized object.

...