Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: fixes with comments
Wiki Markup
Method chaining is a convenience mechanism that allows multiple method invocations on the same object to occur in a single statement.

...

 A method

...

While the methods used in method chaining may be atomic, a chain of method calls is inherently non-atomic, see CON07-J. Do not assume that a group of calls to independently atomic methods is atomic for details. Consequently methods that are involved in method chaining should not be invoked by multiple threads,

Noncompliant Code Example

Method chaining is a useful design pattern for building an object and setting its optional fields. A class that supports method chaining provides several setter methods that each return the this reference. However, in a multithreaded environment, a thread may observe shared fields to contain inconsistent values. This noncompliant code example shows the JavaBeans pattern which is not safe for multithreaded use.

Code Block
bgColor#FFcccc
 chaining implementation consists of a series of methods that return the {{this}} reference. This allows a caller to invoke methods in a chain by performing the next method invocation on the return value of the previous method in the chain.

While the methods used in method chaining may be atomic, a chain of method calls is inherently non-atomic. Consequently methods that are involved in method chaining should not be invoked by multiple threads unless the caller provides sufficient locking as illustrated in [CON07-J. Do not assume that a group of calls to independently atomic methods is atomic]. 
 

h2. Noncompliant Code Example

Method chaining is a useful design pattern for building an object and setting its optional fields. A class that supports method chaining provides several setter methods that each return the {{this}} reference.  However, in a multithreaded environment, a thread may observe shared fields to contain inconsistent values. This noncompliant code example shows the JavaBeans pattern which is not safe for multithreaded use.

{code:bgColor=#FFcccc}
final class USCurrency {
  // Change requested, denomination (optional fields)
  private int quarters = 0;
  private int dimes = 0;
  private int nickels = 0;
  private int pennies = 0;

  public USCurrency() {}

  // Setter methods 
  public USCurrency setQuarters(int quantity) { 
    quarters = quantity; 
    return this;
  } 
  public USCurrency setDimes(int quantity) { 
    dimes = quantity; 
    return this;
  }
  public USCurrency setNickels(int quantity) { 
    nickels = quantity;
    return this;
  }
  public USCurrency setPennies(int quantity) { 
    pennies = quantity;
    return this;
  }
}

// Client code:
private final USCurrency currency = new USCurrency(); 
// ...

new Thread(new Runnable() {
  @Override public void run() {    
    currency.setQuarters(1).setDimes(1);
  }
}).start();

new Thread(new Runnable() {
  @Override public void run() {    
    currency.setQuarters(2).setDimes(2);
  }
}).start();
{code}

The JavaBeans pattern uses a no-argument constructor and a series of parallel setter methods to build an object. This pattern is not thread-safe and can lead to inconsistent object state. In this example, a client that constructs a {{USCurrency}} object and starts two threads as shown may find the object to contain two quarters and one dime or one quarter and two dimes, contrary to what it expects.


h2.

...

 Compliant

...

 Solution

This compliant solution uses the variant of the Builder pattern \[[Gamma 95|AA. Java References#Gamma 95]\] suggested by Bloch \[[Bloch 08|AA. Java References#Bloch 08]\] to ensure thread safety and atomicity of object creation.  {mc} What does this mean? It can be accessible to any number of threads ~DM => The method chaining is actually constrained to the {{USCurrency.Builder}} class which is only accessible 

...

from a single thread.

...

Code Block
bgColor#ccccff
 {mc}


{code:bgColor=#ccccff}
final class USCurrency {
  private final int quarters;
  private final int dimes;
  private final int nickels;
  private final int pennies;

  public USCurrency(Builder builder) {
    this.quarters = builder.quarters;
    this.dimes = builder.dimes;
    this.nickels = builder.nickels;
    this.pennies = builder.pennies;
  }

  // Static class member 
  public static class Builder {
    private int quarters = 0;
    private int dimes = 0;
    private int nickels = 0;
    private int pennies = 0;

    public static Builder newInstance() {
      return new Builder();
    } 

    private Builder() {}
    
    // Setter methods 
    public Builder setQuarters(int quantity) { 
      this.quarters = quantity; 
      return this;
    } 
    public Builder setDimes(int quantity) { 
      this.dimes = quantity; 
      return this;
    }
    public Builder setNickels(int quantity) { 
      this.nickels = quantity;
      return this;
    }
    public Builder setPennies(int quantity) { 
      this.pennies = quantity;
      return this;
    }

    public USCurrency build() {
      return new USCurrency(this);
    }
  }
}

  // Client code: 
private volatile USCurrency currency;
// ...

new Thread(new Runnable() {
  @Override public void run() {    
    currency = USCurrency.Builder.newInstance().setQuarters(1).setDimes(1).build();
  }
}).start();

new Thread(new Runnable() {
  @Override public void run() {    
    currency = USCurrency.Builder.newInstance().setQuarters(2).setDimes(2).build();
  }
}).start();
{code}

The {{Builder.newInstance()}} factory method is called with the _required_ arguments (if any) to obtain a {{Builder}} object. The _optional_ parameters are set using the setter methods of the builder. The object construction concludes with the invocation of the {{build()}} method. This also makes the class {{Currency}} immutable, and consequently, thread-safe.

...



Note that the {{currency}} field cannot be declared as final because it is set to a new immutable object from the threads. It is declared as volatile in compliance with [CON09-J. Ensure visibility of shared references to immutable objects].

...



If input needs to be validated, ensure that the values are defensively copied prior to the validation (see [FIO00-J. Defensively copy mutable inputs and mutable internal components] for more information). The builder class does not violate [SCP03-J. Do not expose sensitive private members of the outer class from within a nested class] because it maintains a copy of the variables defined in the scope of the containing class. These take precedence and as a result, do not break encapsulation.


h2.

...

 Risk Assessment

...



Using method chaining in multithreaded environments without performing external locking can lead to non-deterministic behavior.

...

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

CON30- J

low

probable

medium

P4

L3

Automated Detection

TODO

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

...



|| Rule || Severity || Likelihood || Remediation Cost || Priority || Level ||
| CON30- J | low | probable | medium | {color:green}{*}P4{*}{color} | {color:green}{*}L3{*}{color} |

h3. Automated Detection

TODO

h3. Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the [CERT website|https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+FIO38-J].

h2. References

\[[API 06|AA. Java References#API 06]\] 
\[[Bloch 08|AA. Java References#Bloch 08]\] Item 2: "Consider a builder when faced with many constructor parameters"

...



----
[!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_left.png!|CON29-J. Do not execute interdependent tasks in a bounded thread

...

 pool]      [!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_up.png!|11. Concurrency (CON)]      [!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_right.png!|CON31-J. Avoid client-side locking when using classes that do not commit to their locking strategy]