Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: replaced superfluous method definitions with comments

...

Code Block
bgColor#ccccff
// Class DefaultExceptionReporter
public class DefaultExceptionReporter implements ExceptionReporter {
  public DefaultExceptionReporter(ExceptionReporter er) {
    // Carry out initialization 
  }

  // Registers this exception reporter. 
  // Should be called after constructing a new ExceptionReporter object
  public final setAsExceptionReportersetExceptionReporter(ExceptionReporter er) {
    er.setExceptionReporter(this);
  }

  // publicImplementation voidof report(Throwable exception) { /* default implementation */ }
}

Noncompliant Code Example (inner class)

Wiki Markup
It is possible for the {{this}} reference to implicitly get leaked outside the scope \[[Goetz 02|AA. Java References#Goetz 02]\]. Consider inner classes that maintain a copy of the {{this}} reference of the outer object. In thisThis noncompliant code example, the constructor for uses a different implementation of class {{DefaultExceptionReporter}}. The constructor uses an anonymous inner class to publish a {{filter()}} method. 

Code Block
bgColor#FFcccc
public class AnotherExceptionReporterDefaultExceptionReporter implements ExceptionReporter {
  public AnotherExceptionReporterDefaultExceptionReporter(ExceptionReporter er) {
    er.setExceptionReporter(new AnotherExceptionReporterDefaultExceptionReporter(er) {
        public void report(Throwable t) {
          filter(t);
        }}
      }
    );
  }

  public void filter(Throwable t) { 
    // FiltersDefault sensitiveimplementations exceptionsof 
  }

  public void report(Throwable exception) { 
    // Default implementation 
  }
setExceptionReporter() and report()
}

The problem occurs because the this reference of the outer class is published by the inner class so that other threads can see it. If the class is subclassed, the issue described in the previous noncompliant code example resurfaces.

...

Code Block
bgColor#ccccff
public class AnotherExceptionReporterDefaultExceptionReporter implements ExceptionReporter {
  private final AnotherExceptionReporterDefaultExceptionReporter defaultER;

  private AnotherExceptionReporterDefaultExceptionReporter(ExceptionReporter excr) {
    defaultER = new AnotherExceptionReporter(excr) {
      public void report(Throwable t) {
        filter(t);
      } 
defaultER = new  };DefaultExceptionReporter(excr) {
  }
  
  public staticvoid AnotherExceptionReporter newInstancereport(ExceptionReporterThrowable excrt) {
    AnotherExceptionReporter der = new AnotherExceptionReporterfilter(excrt);
      excr.setExceptionReporter(der.defaultER);} 
    return der};
  }
 
  public static voidDefaultExceptionReporter filternewInstance(ThrowableExceptionReporter texcr) { 
    //DefaultExceptionReporter Filtersder sensitive= exceptionsnew DefaultExceptionReporter(excr);
  }

  public void report(Throwable exception) { excr.setExceptionReporter(der.defaultER);
    return der;
  }
  // Default implementations implementationof 
setExceptionReporter() and }report()
}

Because the constructor is private, untrusted code cannot create instances of the class, prohibiting the this reference from escaping. Using a public static factory method to create new instances also protects against publication of partially initialized objects (CON26-J. Do not publish partially initialized objects).

...