+ All Categories
Home > Documents > 4 March 2004 Scoped Promises Scaling up model expression in the Fluid system Tim Halloran SSSG...

4 March 2004 Scoped Promises Scaling up model expression in the Fluid system Tim Halloran SSSG...

Date post: 31-Dec-2015
Category:
Upload: felicity-ruby-anderson
View: 217 times
Download: 1 times
Share this document with a friend
34
4 March 2004 Scoped Promises Scaling up model expression in the Fluid system Tim Halloran SSSG @promise “@borrows this” for new(* @assume “@useTypeWherePossible jav
Transcript

4 March 2004

Scoped Promises

Scaling up model expressionin the Fluid system

Tim HalloranSSSG

@promise “@borrows this” for new(**)

@assume “@useTypeWherePossible java

4 March 2004Scoped PromisesSSSG

This talk• Motivation

• Scoped promises– @promise– @assume

• Impact on tool architecture

• Related work

• Conclusions

4 March 2004Scoped PromisesSSSG

Motivation

• Problem 1: Annotation (tedious)– Anti-Example:

• Log4j’s DateFormatManager

– Last SSSG demo

• Chains of evidence…experience at scale:

• Problem 2: Team modeling (lack)– Anti-Example:

• Log4j’s BoundedFIFO

– OOPSLA demo (uniqueness assurance)

4 March 2004Scoped PromisesSSSG

public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; public DateFormatManager() { super(); \underline~configure()^; } public DateFormatManager(TimeZone timeZone) {...} public DateFormatManager(Locale locale) {...} public DateFormatManager(String pattern) {...} public DateFormatManager(TimeZone timeZone, Locale locale) {...} public DateFormatManager(TimeZone timeZone, String pattern) {...} public DateFormatManager(Locale locale, String pattern) {...} public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

• Straightforward concurrency policy– synchronized

methods protect private fields

• 8 constructors• “getter” and

“setter” methods• A utility routine configure() to maintain state invariants

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance */public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; public DateFormatManager() { super(); \underline~configure()^; } public DateFormatManager(TimeZone timeZone) {...} public DateFormatManager(Locale locale) {...} public DateFormatManager(String pattern) {...} public DateFormatManager(TimeZone timeZone, Locale locale) {...} public DateFormatManager(TimeZone timeZone, String pattern) {...} public DateFormatManager(Locale locale, String pattern) {...} public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

Step 1:Add the lock model

@lock L is this protects Instance

Declares that the object instance (this) is intended to protect all the object’s fields

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance */public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; public DateFormatManager() { super(); \underline~configure()^; } public DateFormatManager(TimeZone timeZone) {...} public DateFormatManager(Locale locale) {...} public DateFormatManager(String pattern) {...} public DateFormatManager(TimeZone timeZone, Locale locale) {...} public DateFormatManager(TimeZone timeZone, String pattern) {...} public DateFormatManager(Locale locale, String pattern) {...} public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance */public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; /** @synchronized @borrowed this */ public DateFormatManager() { super(); \underline~configure()^; } /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

Step 2:Annotate theconstructors

@synchronized @borrowed this

Constructors behave “like” a synchronized method (they do not leak aliases)

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance */public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; /** @synchronized @borrowed this */ public DateFormatManager() { super(); \underline~configure()^; } /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance */public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; /** @synchronized @borrowed this */ public DateFormatManager() { super(); \underline~configure()^; } /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} /** @borrowed this */ private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

Step 3:Annotateconfigure()

@borrowed thisThe method will not create an alias of this

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance */public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; /** @synchronized @borrowed this */ public DateFormatManager() { super(); \underline~configure()^; } /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} /** @borrowed this */ private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance */public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; /** @synchronized @borrowed this */ public DateFormatManager() { super(); \underline~configure()^; } /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} /** @borrowed this */ public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} /** @borrowed this */ private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

Step 3:AnnotategetLocale()

@borrowed this@borrowed thisThe method will not create an alias of this

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance */public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; /** @synchronized @borrowed this */ public DateFormatManager() { super(); \underline~configure()^; } /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} /** @borrowed this */ public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} /** @borrowed this */ private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance */public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; /** @synchronized @borrowed this */ public DateFormatManager() { super(); \underline~configure()^; } /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} /** @borrowed this */ public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} /** @borrowed this */ public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} /** @borrowed this */ private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

Step 3:AnnotategetTimeZone()

@borrowed thisThe method will not create an alias of this

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance */public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; /** @synchronized @borrowed this */ public DateFormatManager() { super(); \underline~configure()^; } /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(Locale locale, String pattern) {...} /** @synchronized @borrowed this */ public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} /** @borrowed this */ public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} /** @borrowed this */ public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} /** @borrowed this */ private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

org.apache.log4j.lf5.util.

DateFormatManager

Success!

That is, if the user didn’t already wipe our tool from the hard disk

4 March 2004Scoped PromisesSSSG

What is the bigger problem?

Annotation tedium is a symptom…• Problem: Chains of evidence is

incremental– “safe defaults” — correct Java is never wrong– Promises define precise models

• Cut-points on Java module interfaces to allow modular program analysis for assurance of model-code consistency

– User is faced with tedious promise expression

• Our Solution: @promise (+ tools)– Redo DateFormatManager demo

4 March 2004Scoped PromisesSSSG

org.apache.log4j.lf5.util.

DateFormatManager

Using @promise

4 March 2004Scoped PromisesSSSG

/** @lock L is this protects Instance * @promise “@snychronized” for new(**)public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; public DateFormatManager() { super(); \underline~configure()^; } public DateFormatManager(TimeZone timeZone) {...} public DateFormatManager(Locale locale) {...} public DateFormatManager(String pattern) {...} public DateFormatManager(TimeZone timeZone, Locale locale) {...} public DateFormatManager(TimeZone timeZone, String pattern) {...} public DateFormatManager(Locale locale, String pattern) {...} public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

@promise• Creates virtual

promises on all constructors

• @promise acts as a mechanism to place model promises on targeted declarations

• Better captures intent that should apply to “all” declarations– Changes the default

/** @lock L is this protects Instance * @promise “@snychronized” for new(**)public class DateFormatManager { private TimeZone _timeZone = null, Locale _locale = null; private String _pattern = null, DateFormat _dateFormat = null; /** @synchronized */ public DateFormatManager() { super(); \underline~configure()^; } /** @synchronized */ public DateFormatManager(TimeZone timeZone) {...} /** @synchronized */ public DateFormatManager(Locale locale) {...} /** @synchronized */ public DateFormatManager(String pattern) {...} /** @synchronized */ public DateFormatManager(TimeZone timeZone, Locale locale) {...} /** @synchronized */ public DateFormatManager(TimeZone timeZone, String pattern) {...} /** @synchronized */ public DateFormatManager(Locale locale, String pattern) {...} /** @synchronized */ public DateFormatManager(TimeZone timeZone, Locale locale, ...) {...} public synchronized TimeZone getTimeZone() {...} public synchronized void setTimeZone(TimeZone timeZone) {...} public synchronized Locale getLocale() {...} public synchronized void setLocale(Locale locale) {...} public synchronized String getPattern() {...} public synchronized void setPattern(String pattern) {...} public synchronized DateFormat getDateFormatInstance() {...} public synchronized void setDateFormatInstance(DateFormat ...) {...} public String format(Date date) {...} public String format(Date date, String pattern) {...} public Date parse(String date) throws ParseException {...} public Date parse(String date, String pattern) throws ... {...} private synchronized void configure() { _dateFormat = SimpleDateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, getLocale()); _dateFormat.setTimeZone(getTimeZone()); if (_pattern != null) ((SimpleDateFormat) _dateFormat).applyPattern(_pattern); }}

4 March 2004Scoped PromisesSSSG

Target pattern examplesPattern Example Description

Types * All top level types (type declarations)

edu.cmu.**:* All top level types in any sub-package of “edu.cmu”

edu.cmu.**:* All types in any sub-package of “edu.cmu”

constructors

new(**) All constructors (in any type)

Foo:new() All no-argument constructors in “Foo”

methods *(int, **) All methods (in any type) with an “int” first arg

int Foo:*(*) All methods returning “int” in “Foo” with one arg

!private *() All non-private methods with no arguments

fields List * All fields (in any type) of type list

“|” “&” and “!” create expressions: “new(**) | *(**)” “new(**) & !(new())”

4 March 2004Scoped PromisesSSSG

Scope of @promise• Target patterns are limited, in static

scope, by where the @promise appears– Type declaration Javadoc: That type

• I.e., target only pattern matches within the static scope of the type declaration

– JSR-175 “package.java”: That pkg and sub-pkgs

• Target pattern matches within all compilation units within that package and all sub-packages.

“Luke, there is another location for scoped promises”

4 March 2004Scoped PromisesSSSG

JSR-175 @promise example:non-null array return values

• From my proposal (null value assurance):

• Josh Bloch: no method returning an array reference should ever return null– @promise can do this: (in

/org/netbeans/package.java)

package org.netbeans.modules.debugger;public interface CallStackProducer extends CallStackRoot { ... public /*@not-null*/ Location[] getCallStack(); ...}

package org.netbeans;/** @promise “@return not-null” for *[+] *(**) */

4 March 2004Scoped PromisesSSSG

The 2nd (bigger) problem…

• Problem 2: Team modeling (lack)– Anti-Example:

• Log4j’s BoundedFIFO• OOPSLA demo

4 March 2004Scoped PromisesSSSG

Trouble with BoundedFIFO

• When uniqueness assurance (Boyland) was “turned-on” BoundedFIFO could not be be assured

– A call to java.lang.System.arraycopy() was made passing an unshared field as the data source

– Uniqueness assurance wants arraycopy() to promise that its first parameter is “borrowed”

org.apache.log4j.helpers.

BoundedFIFO

4 March 2004Scoped PromisesSSSG

The offending source code

/** * @lock BufLock is this protects Instance * @promise "@borrowed this" for new(**) | *(**) * @promise "@synchronized" for new(**) * @promise "@requiresLock BufLock" for *(**) & !(resize(**)) */public class BoundedFIFO { /** @unshared @aggregate [] into Instance */ LoggingEvent[] buf; ... synchronized public void resize(int newSize) { ... System.arraycopy(buf, first, tmp, 0, len1); ... }}

org.apache.log4j.helpers.

BoundedFIFO

4 March 2004Scoped PromisesSSSG

Our current tool solution

• We avoid direct annotation of library code via a scheme called an XML promise

• The XML promise for arraycopy():

org.apache.log4j.helpers.

BoundedFIFO

4 March 2004Scoped PromisesSSSG

org.apache.log4j.helpers.

BoundedFIFO

That is, if the user didn’t already wipe our tool from the hard disk

Success!/** * @lock BufLock is this protects Instance * @promise "@borrowed this" for new(**) | *(**) * @promise "@synchronized" for new(**) * @promise "@requiresLock BufLock" for *(**) & !(resize(**)) */public class BoundedFIFO { /** @unshared @aggregate [] into Instance */ LoggingEvent[] buf; ... synchronized public void resize(int newSize) { ... System.arraycopy(buf, first, tmp, 0, len1); ... }}

4 March 2004Scoped PromisesSSSG

What is the bigger problem?

Library annotation is a symptom…• Problem: Chains of evidence is

modular and relies upon interface specification– User is faced with modeling design intent in

unfamiliar parts of a software system– We have no scheme to enable modeling by

a team of developers

• Our Solution: @assume (+ tools)@assume has been controversial (even among the “extended” Fluid team)

4 March 2004Scoped PromisesSSSG

Fixing BoundedFIFO

/** * @lock BufLock is this protects Instance * @promise "@borrowed this" for new(**) | *(**) * @promise "@synchronized" for new(**) * @promise "@requiresLock BufLock" for *(**) & !(resize(**)) * @assume “@borrowed arg0” * for “System.arraycopy(Object, int, Object, int, int)” */public class BoundedFIFO { /** @unshared @aggregate [] into Instance */ LoggingEvent[] buf; ... synchronized public void resize(int newSize) { ... System.arraycopy(buf, first, tmp, 0, len1); ... }}

org.apache.log4j.helpers.

BoundedFIFO

(aside) Apache Bug 26224

4 March 2004Scoped PromisesSSSG

@assume• Answers: If a model existed in

(unfamiliar) code is my code consistent with this model?

• Allows local expression of non-local models– Avoiding programmer modeling of unfamiliar

code but precisely capturing assumptions about the rest of the system

– Tool creates a highly-focused TODO list of assumed properties for action by other programmers java.lang.System: arraycopy() assumed “@borrowed arg0”

Assurance Help Wanted Board: (1 item)

4 March 2004Scoped PromisesSSSG

Scope of @assume• Promise visibility is limited, in static

scope, by where the @assume appears– Type declaration Javadoc: That type

• I.e., You only “see” the promise assumed within the type however, the promise target is not restricted

– JSR-175 “package.java”: That pkg and sub-pkgs

• Promise is visible within all compilation units within that package and all sub-packages. Again, the promise target is not restricted

4 March 2004Scoped PromisesSSSG

@assume: Enforcing a standard

• Consider, a type use advice assurance:

• This is not useful in practice– It is not followed universally

• 1,374 violations (for ArrayList and LinkedList) found in the J2SDK, Ant, Tomcat, Eclipse, NetBeans (Halloran)

– The promise is idiosyncratic (? Collection)

• Use of @assume (JSR-175) makes this useful

package java.util;/** @useTypeWherePossible java.util.List */class ArrayList extends AbstractList implements List, RandomAccess, ... {...}

package edu.cs.cmu.fluid;/** @assume “@useTypeWherePossible java.util.List” for “java.util.List+” */

4 March 2004Scoped PromisesSSSG

Impact on tool architecture• @promise and @assume are, by design, (mostly)

transparent to analysis code:– All bindings must provide “from” AST location– All links to promises a result depends upon must be

reported

• @promise creates virtual promises in the AST

• @assume “makes” virtual promises visible only within its static scope (defined by annotation location)– Tacit assumption: analyses are not whole-program

• “if you give @assume semantics over *both* the scope of the promise *and* the scope of the analysis that checks uses, then you will get the (secondary) unsoundness for a non-modular analysis” (Boyland) – concrete example next slide…

4 March 2004Scoped PromisesSSSG

Broke @assume example(whole-program @useTypeWherePossible)

• Analysis result: stuff should be declared of type List– Change results in compiler error due to use in Sneaky

• Problem: Analysis that checks uses is whole-program• Solution: Make modular (limit to private fields & local

variables) or forbid use of the promise in an @assume

/** @assume “@useTypeWherePossible java.util.List” for “java.util.ArrayList” */class Nice { static public ArrayList stuff = new ArrayList(); public void add(Object o) { stuff.add(o); }}

class Sneaky { public void m() { Nice.stuff.ensureCapacity(1000); }}

4 March 2004Scoped PromisesSSSG

Related work• Promises (Chan, Boyland, Scherlis)

• Aspect Oriented Programming– Loosely: promise≈advice / target≈pointcut– AspectJ (Kiczales, Lamping, Mendhekar, et al.)– Statically executable advice (Lieberherr, et al.)

• JML (Leavens, et al.)– @refine composition focused (Larch traits)– @assume caller obligation (@requiresLock)

• ESC/Java (Leino, Nelson, et al.)• Modular but model expression is not incremental• @assume @axiom Trusted direction to theorem prover

• Programming languages/Specification languages (ideas)

4 March 2004Scoped PromisesSSSG

Conclusion• Presented two scoped promises

– @promise: avoiding tedious annotation (cut-paste)– @assume: supporting modeling by a team of developers

• Concrete solutions toward making chains of evidence practical for developers and teams of developers

• A general mechanism available to current and future chains of evidence assurances– Transparent to their implementation– Avoids ad hoc per-assurance solutions


Recommended