According to The Java Language Specification, §15.8.3, "this" [JLS 2015]:

When used as a primary expression, the keyword this denotes a value that is a reference to the object for which the instance method was invoked (§15.12), or to the object being constructed....

The type of this is the class or interface type T within which the keyword this occurs....

At run time, the class of the actual object referred to may be T, if T is a class type, or a class that is a subtype of T.

The this reference is said to have escaped when it is made available beyond its current scope. Following are common ways by which the this reference can escape:

  • Returning this from a nonprivate, overridable method that is invoked from the constructor of a class whose object is being constructed (for more information, see MET05-J. Ensure that constructors do not call overridable methods).

  • Returning this from a nonprivate method of a mutable class, which allows the caller to manipulate the object's state indirectly. This situation commonly occurs in method-chaining implementations (see VNA04-J. Ensure that calls to chained methods are atomic for more information).
  • Passing this as an argument to an alien method invoked from the constructor of a class whose object is being constructed.
  • Using inner classes. An inner class implicitly holds a reference to the instance of its outer class unless the inner class is declared static.
  • Publishing by assigning this to a public static variable from the constructor of a class whose object is being constructed.
  • Throwing an exception from a constructor. Doing so may cause code to be vulnerable to a finalizer attack (see OBJ11-J. Be wary of letting constructors throw exceptions for more information).
  • Passing internal object state to an alien method, which enables the method to retrieve the this reference of the internal member object.

This rule describes the potential consequences of allowing the this reference to escape during object construction, including race conditions and improper initialization. For example, declaring a field final ordinarily ensures that all threads see the field in a fully initialized state; however, allowing the this reference to escape during object construction can expose the field to other threads in an uninitialized or partially initialized state. TSM03-J. Do not publish partially initialized objects, which describes the guarantees provided by various mechanisms for safe publication, relies on conformance to this rule. Consequently, programs must not allow the this reference to escape during object construction.

In general, it is important to detect cases in which the this reference can leak out beyond the scope of the current context. In particular, public variables and methods should be carefully scrutinized.

Noncompliant Code Example (Publish before Initialization)

This noncompliant code example publishes the this reference before initialization has concluded by storing it in a public static volatile class field. Consequently, other threads can obtain a partially initialized Publisher instance.

final class Publisher {
  public static volatile Publisher published;
  int num;

  Publisher(int number) {
    published = this;
    // Initialization
    this.num = number;
    // ...
  }
}

If an object's initialization (and consequently, its construction) depends on a security check within the constructor, the security check can be bypassed when an untrusted caller obtains the partially initialized instance (see OBJ11-J. Be wary of letting constructors throw exceptions for more information).

Noncompliant Code Example (Nonvolatile Public Static Field)

This noncompliant code example publishes the this reference in the last statement of the constructor. It remains vulnerable because the published field has public accessibility and the programmer has failed to declare it as volatile.

final class Publisher {
  public static Publisher published;
  int num;

  Publisher(int number) {
    // Initialization
    this.num = number;
    // ...
    published = this;
  }
}

Because the field is nonvolatile and nonfinal, the statements within the constructor can be reordered by the compiler in such a way that the this reference is published before the initialization statements have executed.

Compliant Solution (Volatile Field and Publish after Initialization)

This compliant solution both declares the published field volatile and reduces its accessibility to package-private so that callers outside the current package scope cannot obtain the this reference.

final class Publisher {
  static volatile Publisher published;
  int num;

  Publisher(int number) {
    // Initialization
    this.num = number;
    // ...
    published = this;
  }
}

The constructor publishes the this reference after initialization has concluded. However, the caller that instantiates Publisher must ensure that it cannot see the default value of the num field before it is initialized; to do otherwise would violate TSM03-J. Do not publish partially initialized objects. Consequently, the field that holds the reference to Publisher might need to be declared volatile in the caller.

Initialization statements may be reordered when the published field is not declared volatile. The Java compiler, however, forbids declaring fields as both volatile and final.

The class Publisher must also be final; otherwise, a subclass can call its constructor and publish the this reference before the subclass's initialization has concluded.

Compliant Solution (Public Static Factory Method)

This compliant solution eliminates the internal member field and provides a newInstance() factory method that creates and returns a Publisher instance:

final class Publisher {
  final int num;

  private Publisher(int number) {
    // Initialization
    this.num = number;
  }

  public static Publisher newInstance(int number) {
    Publisher published = new Publisher(number);
    return published;
  }
}

This approach ensures that threads cannot see an inconsistent Publisher instance. The num field is also declared final, making the class immutable and consequently eliminating the possibility of obtaining a partially initialized object.

Noncompliant Code Example (Handlers)

This noncompliant code example defines the ExceptionReporter interface:

public interface ExceptionReporter {
  public void setExceptionReporter(ExceptionReporter er);
  public void report(Throwable exception);
}

This interface is implemented by the DefaultExceptionReporter class, which reports exceptions after filtering out any sensitive information (see ERR00-J. Do not suppress or ignore checked exceptions for more information).

The DefaultExceptionReporter constructor prematurely publishes the this reference before construction of the object has concluded. This occurs in the last statement of the constructor (er.setExceptionReporter(this)), which sets the exception reporter. Because it is the last statement of the constructor, this may be misconstrued as benign.

// Class DefaultExceptionReporter
public class DefaultExceptionReporter implements ExceptionReporter {
  public DefaultExceptionReporter(ExceptionReporter er) {
    // Carry out initialization
    // Incorrectly publishes the "this" reference
    er.setExceptionReporter(this);
  }

  // Implementation of setExceptionReporter() and report()
}

The MyExceptionReporter class subclasses DefaultExceptionReporter with the intent of adding a logging mechanism that logs critical messages before reporting an exception.

// Class MyExceptionReporter derives from DefaultExceptionReporter
public class MyExceptionReporter extends DefaultExceptionReporter {
  private final Logger logger;

  public MyExceptionReporter(ExceptionReporter er) {
    super(er); // Calls superclass's constructor
    // Obtain the default logger
    logger = Logger.getLogger("com.organization.Log");
  }

  public void report(Throwable t) {
    logger.log(Level.FINEST,"Loggable exception occurred", t);
  }
}

The MyExceptionReporter constructor invokes the DefaultExceptionReporter superclass's constructor (a mandatory first step), which publishes the exception reporter before the initialization of the subclass has concluded. Note that the subclass initialization consists of obtaining an instance of the default logger. Publishing the exception reporter is equivalent to setting it to receive and handle exceptions from that point on.

Logging will fail when an exception occurs before the call to Logger.getLogger() in the MyExceptionReporter subclass because dereferencing the uninitialized logger field generates a NullPointerException, which could itself be consumed by the reporting mechanism without being logged.

This erroneous behavior results from the race condition between an oncoming exception and the initialization of MyExceptionReporter. If the exception arrives too soon, it will find the MyExceptionReporter object in an inconsistent state. This behavior is especially counterintuitive because logger has been declared final, so observing an uninitialized value would be unexpected.

Premature publication of an event listener causes a similar problem; the listener can receive event notifications before the subclass's initialization has finished.

Compliant Solution

Rather than publishing the this reference from the DefaultExceptionReporter constructor, this compliant solution adds a publishExceptionReporter() method to DefaultExceptionReporter to permit setting the exception reporter. This method can be invoked on a subclass instance after the subclass's initialization has concluded.

public class DefaultExceptionReporter implements ExceptionReporter {
  public DefaultExceptionReporter(ExceptionReporter er) {
    // ...
  }

  // Should be called after subclass's initialization is over
  public void publishExceptionReporter() {
    setExceptionReporter(this); // Registers this exception reporter
  }

  // Implementation of setExceptionReporter() and report()
}

The MyExceptionReporter subclass inherits the publishExceptionReporter() method. Callers that instantiate MyExceptionReporter can use the resulting instance to set the exception reporter after initialization is complete.

// Class MyExceptionReporter derives from DefaultExceptionReporter
public class MyExceptionReporter extends DefaultExceptionReporter {
  private final Logger logger;

  public MyExceptionReporter(ExceptionReporter er) {
    super(er); // Calls superclass's constructor
    logger = Logger.getLogger("com.organization.Log");
  }
  // Implementations of publishExceptionReporter(), 
  // setExceptionReporter() and report()
  // are inherited
}

This approach ensures that the reporter cannot be set before the constructor has fully initialized the subclass and enabled logging.

Noncompliant Code Example (Inner Class)

Inner classes maintain a copy of the this reference of the outer object. Consequently, the this reference could leak outside the scope [Goetz 2002]. This noncompliant code example uses a different implementation of the DefaultExceptionReporter class. The constructor uses an anonymous inner class to publish an exception reporter.

public class DefaultExceptionReporter implements ExceptionReporter {
  public DefaultExceptionReporter(ExceptionReporter er) {
    er.setExceptionReporter(new ExceptionReporter() {
        public void report(Throwable t) {
          // report exception
        }
        public void setExceptionReporter(ExceptionReporter er) {
          // register ExceptionReporter
        }
    });
  }
  // Default implementations of setExceptionReporter() and report()
}

Other threads can see the this reference of the outer class because it is published by the inner class. Furthermore, the issue described in the noncompliant code example for handlers will resurface if the class is subclassed.

Compliant Solution

Use a private constructor and a public static factory method to safely publish the exception reporter from within the constructor [Goetz 2006a]:

public class DefaultExceptionReporter implements ExceptionReporter {
  private final ExceptionReporter defaultER;

  private DefaultExceptionReporter(ExceptionReporter excr) {
    defaultER = new ExceptionReporter() {
      public void report(Throwable t) {
        // Report exception
      }
      public void setExceptionReporter(ExceptionReporter er) {
        // Register ExceptionReporter
      }
    };
  }

  public static DefaultExceptionReporter newInstance(
                ExceptionReporter excr) {
    DefaultExceptionReporter der = new DefaultExceptionReporter(excr);
    excr.setExceptionReporter(der.defaultER);
    return der;
  }
  // Default implementations of setExceptionReporter() and report()
}

Because the constructor is private, untrusted code cannot create instances of the class; consequently, the this reference cannot escape. Using a public static factory method to create new instances also protects against untrusted manipulation of internal object state and publication of partially initialized objects (see TSM03-J. Do not publish partially initialized objects for additional information).

Noncompliant Code Example (Thread)

This noncompliant code example starts a thread inside the constructor:

final class ThreadStarter implements Runnable {
  public ThreadStarter() {
    Thread thread = new Thread(this);
    thread.start();
  }

  @Override public void run() {
    // ...
  }
}

The new thread can access the this reference of the current object [Goetz 2002], [Goetz 2006a]. Notably, the Thread() constructor is alien to the ThreadStarter class.

Compliant Solution (Thread)

This compliant solution creates and starts the thread in a method rather than in the constructor:

final class ThreadStarter implements Runnable {
  public void startThread() {
    Thread thread = new Thread(this);
    thread.start();
  }

  @Override public void run() {
    // ...
  }
}

Exceptions

TSM01-J-EX0: It is safe to create a thread in the constructor, provided the thread is not started until after object construction is complete, because a call to start() on a thread happens-before any actions in the started thread [JLS 2015].

Even though this code example creates a thread that references this in the constructor, the thread is started only when its start() method is called from the startThread() method [Goetz 2002], [Goetz 2006a].

final class ThreadStarter implements Runnable {
  Thread thread;

  public ThreadStarter() {
    thread = new Thread(this);
  }

  public void startThread() {
    thread.start();
  }

  @Override public void run() {
    // ...
  }
}

TSM01-J-EX1: Use of the ObjectPreserver pattern [Grand 2002] described in TSM02-J. Do not use background threads during class initialization is safe and is permitted.

Risk Assessment

Allowing the this reference to escape can result in improper initialization and runtime exceptions.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

TSM01-J

Medium

Probable

High

P4

L3

Automated Detection

ToolVersionCheckerDescription
Parasoft Jtest
2023.1
CERT.TSM01.CTREDo not let "this" reference escape during construction

Bibliography

[Goetz 2002]


[Goetz 2006a]

Section 3.2, "Publication and Escape"

[Grand 2002]

Chapter 5, "Creational Patterns, Singleton"

[JLS 2015]§15.8.3, "this"

Issue Tracking

100%

Review List

  1. handler

    "Inner classes implicitly hold a reference to the instance of the outer class, unless the inner class is declared as static." => Change inner classes to "An inner class implicitly holds ... "

    Priority MEDIUM
    svoboda
    Apr 02, 2010
  2. handler

    "Note that this code also violates CON32-J. Protect accessible mutable static fields from untrusted code" => Not sure if I agree because the class is package-private and inaccessible to untrusted code

    Priority MEDIUM
    rcs
    Apr 02, 2010
  3. handler

    "A Runnable object's constructor may construct a Thread object around itself, as long as the thread is not actually started in the Runnable object's constructor." => I still think this info is redundant.

    Priority MEDIUM
    rcs_mgr
    Apr 08, 2010



23 Comments

    • Needs a reference to CON26-J, preferrably in the introduction
    1. Publishing this from the constructor of an object under construction
    2. Publishing this such that pieces of code beyond its current scope can obtain its reference
    • I'd rather this list not include "publishing"...can you replace these items with items that don't use 'publish'? (eg passing this as a parameter to a method while this is being constructed).
    • I trust the 1st Compliant Solution (which uses a static volatile pub variable) does not violate CON26-J.
    • The 3rd NCCE needs a lot of work:
    • Needs a better nickname than 'constructor'. All these NCCEs are about constructors.
    • I think I'd rather ExceptionReporters was called something else, like DefaultExceptionReporter.
    • Needs to explain that setExceptionReporter() does the dirty deed of 'publishing' the exception reporter so that it does get invoked when an exception is thrown.
    • The 1st CS does not remove publication from the ExceptionReporter ctor.
    • Finally, the thread NCCE/CS. I'm not sure why giving a new Thread 'this' inside the ctor is safe. Does Thread make some guarantee not to touch the 'this' object it is given before start() is invoked?
      • Added xref to CON26
      • "An object that is published when it should not have been is said to have escaped." [Goetz 06].
      • It did violate it. I've added another CS. Please check.
      • Can you point out the name of the NCE? And what changes would you like to see?
      • Changed the nickname
      • Changed to DefaultExceptionReporter. But this is different from EXC01-J. Use a class dedicated to reporting exceptions now.
      • Reworded a bit
      • Now the new CS removes the this escape
      • "A call to start() on a thread happens-before any actions in the started thread." [JLS 05]. So there should be no problem in giving this because no one will be able to do anything using it anyway.
  1. The partially constructed NCE is a CS for this guideline. If a caller violates CON26 it is not the problem for this guideline.

  2. David, the link to OBJ08-J. Avoid using finalizers is not very useful here because untrusted code will not comply with it. The problem is that untrusted code can add a finalizer. We can keep the link but then we should point out that this should not happen inadvertently by trusted code. (The link to OBJ04 is only about untrusted code)

    1. I think you should xref OBJ08-J whenever you talk about using finalizers, in order to say "don't try this at home". I think it still applies even if you are referring to untrusted code (which doesn't have the same restrictions as the code we expect devs to write.)

      I only have two other comments with the rule as it is now:

      • In the 'handlers' CS, what is the point of having MyExceptionReporter.setReporter(), when DefaultExceptionReporter.setExceptionReporter() is public and final? People should just call the latter and ignore the former.
      • The ThreadStart CS still violates this rule even though it may be safe. (Remember that we can forbid safe code if we think it worthwhile.) To explain why the code does not violate the rule you either have to defer to Goetz or study the internal workings of the Thread class. Better to construct the thread in the startThread() method; that's easier to enforce.
      1. Sorry there was a race condition between updating my comment and you answering. We can keep the xref but we should point out that it is for trusted code and inadvertent escaping of this.

        • The NCE talks about a subclass's initialization not finishing before the reporter gets set. The CS must therefore, use the subclass. The point is to secure the subclass until its initialization is over. You could also make setExceptionReporter() in DefaultExceptionReporter nonfinal but it is not required. So after all, people = subclass in this case and they are calling the right method. (ok, I see what you mean, it can be omitted but the text should state clearly what is happening)
        • The rule does not prohibit against creating threads in constructors but about starting them. Your strategy might be safer, however, from my understanding, it may be a false positive to detect this as a violation. It is a corner case and explains the point well. If you'd like we can create the thread in the method and start it too (and this will become the new CS). But then, the current CS should be listed as an exception because it does not violate this rule. With the exception we can add - even though this is safe, we recommend not creating the thread in the constructor for maintainability reasons.
      2. I've addressed my own comments in the rule.

  3. The '(volatile field and publish after initialization)' code technically violates the rule. The code is safe as written, but you can't safely subclass Publisher with a nontrivial constructor. The ThreadStarter class in EX1 has the same problem.

    You could fix both code snippets by making the class final.

    1. Good point. I've made the class in CS(volatile field and publish after initialization) final.

      I am not sure if EX1 needs to be final (though it is better to declare classes not designed for inheritance final anyway). Even if a subclass invoked the superclass's constructor, the this reference does not escape because the thread cannot be started unless the subclass's initialization is over. If the thread calls the superclass method (that starts the thread) from its constructor, then you lose. But, starting threads from constructors with this as a runnable argument is already banned by the CS in this guideline.

  4. The last CS in MSC16-J. Address the shortcomings of the Singleton design pattern starts a thread from a private constructor which appears to be an exception to the last NCE/CS pair in this guideline.

    1. So it does. Addressed in that rule.

  5. In EXC01-J, setExceptionReporter() is a static method (that sets a default value), not a member function. (A member function that serves as a wrapper to a static function is an acceptable workaround.)

  6. I'm looking at the list in this section and thinking some of this material might be more appropriate for the introduction.

  7. In the inner class sections, both noncomplient and complient examples, it says filter() method is published. However, the method is not directly exposed but ExceptionReporter.report() is, implementing filter() method call. It makes possible to use filter() method functionality but still it is not published. Correct me if I'm wrong, please.

    1. Good catch.

      The object being published is the new DefaultExceptionReporter. This example happens to show a reporter that invokes a filter() method. I've reworded to clarify.

  8. In both Noncompliant Code Example (Inner Class) and its Compliant Solution, it is unknown where the filter() method is coming from.

    1. It's also irrelevant, so I took filter() out of the inner function. It's not necessary to understand the good / bad parts of the code samples.

  9. while the "Compliant Solution (Public Static Factory Method)" is a valid way to safely do complex initialization of a class before it is available to other classes, this example does not showcase any reason to use this solution.  this CS would be just as valid without the factory.

    1. True. The main point is that:

         this.num = number;
      

      must be executed before:

          published = this;
      

      .

      1. must be executed before:

        must be executed before and in a way which properly publishes this.num to any other threads.

  10. Automated Detection?

    Sonar:

    none for reference escape, but one for thread start in constructor:

    findbugs:SC_START_IN_CTOR

  11. I have changed the Noncompliant Code Example (Inner Class) and the corresponding Compliant Solution. The original versions performed recursive invocations of the constructor (DefaultExceptionReporter) causing a StackOverflowError. I have replaced the recursive call to the constructor by an instantiation of an anonymous class implementing ExceptionReporter.

    1. Good catch, thanks!