Politecnico di MilanoAdvanced Topics in Software Engineering
JML in a Nutshell
Domenico Bianculli & Alessandro Monguzzi
{bianculli, alessandro.monguzzi}@gmail.com
June 16th, 2005
Rev. 1.3
2JML
in a
Nuts
hellOutline
• What is JML?
• Syntax
• Specification cases
• Advanced topics
• Running example
• Tools
• Related works
3JML
in a
Nuts
hell
What is JML?
• Java Modeling Language
• A behavior interface specification language (BISL)describes:– modules interface– modules behaviour
• evolution of Hoare-style specification
• based on Design by Contract
5JML
in a
Nuts
hell
Syntax: annotations
• Specification written as annotation comments
• Single line://@ … specification …
• Multiline:/*@ … specification… @ … @*/
• Informal://@(* informal description *)
6JML
in a
Nuts
hell
Syntax: expressions
• Expression used in JML annotations cannot have side effects.– No use of =, +=, ++, -- …– Can only call pure methods
• Extended version of Java expressions
Expression Meaning
a ==> b a implies b
a <== b a follows from b
a <==> b a if and only if b
a <=!=> b not (a if and only if b)
\old(E) value of E in pre-state
\result result of method call
7JML
in a
Nuts
hell
• universal & existential (\forall,\exists)
/*@ \forall int x;
@ x >= 0 && x < a.lenght-1;
@ a[x-1] <= a[x];
@*/
• general quantifiers (\sum, \product, \min, \max)
• numeric quantifier(\num_of)
Syntax: quantification
declaration
range
body
8JML
in a
Nuts
hell
Preconditions
• Say what must be true when calling a method
• Introduced by requires clause
/*@requires x>= 0;
@...
@*/
public double sqrt(double x);
9JML
in a
Nuts
hell
Normal postconditions
• Say what must be true when a method returns normally(i.e. without throwing exceptions)
• Introduced by ensures clause/*@ requires x>= 0;
@ ensures x - \result * \result <= 0.0001;
@*/
public double sqrt(double x);
• Input parameters in postconditions are always evaluated in pre-statex ≡ \old(x)
10JML
in a
Nuts
hell
Exceptional postconditions
• Say what must be true when a method throws an exception of type TIntroduced by signals clause
/*@ requires x>= 0;
@ ensures x - \result * \result <= 0.0001;
@ signals (IllegalArgumentException ex)
@ ex.getMessage() != null && !(x >=0.0);
@*/
public double sqrt(double x);
11JML
in a
Nuts
hell
More on exceptional postconditions (1)
• Note that signal clause does not say which exceptions must be thrown
• It just only says “… if an exception of (sub)type T is thrown, then its predicate must hold” and not viceversa.
• The signals_only clause specifies what exceptions may be thrown, and implicitly the ones which cannot be thrown.
12JML
in a
Nuts
hell
More on exceptional postconditions (2)
• To say that an exception must be thrown in some situations, exclude that situations from other signals clauses and from all ensures clauses
/*@ requires true; @ ensures x>=0 &&… @ signals (Exception e) @ x<0 && … @*/public int foo(int x) throws Exceptions;
• More on this topic later…
13JML
in a
Nuts
hell
Semantics
• Meaning of JML method specification– A method is called in a state (pre-state)
where the precondition is satisfied; otherwise, nothing is guaranteed, including the termination of the call
– If a method is called in a proper pre-state, then there are two possible outcomes (post-state) of method’s execution: normal and exceptional
14JML
in a
Nuts
hell
Kinds of specification & specification cases
• Specification cases– Lightweight– Heavyweight
• Behaviour• Normal Behaviour• Exceptional Behaviour
15JML
in a
Nuts
hell
Heavyweight vs lightweight specs
Heavyweight
• Assumes users giving full specification
• Omitted clauses are abbreviations
• Useful for formal verification
Lightweight• Don’t assume user
is giving full specification
• Minimize annotation burden
• Omitted clauses are \not_specified
• Useful for RAC and docs
16JML
in a
Nuts
hell
Additional Clauses
diverge says that a method may not return to its caller
when allows concurrency aspects of a method
assignable lists non local variables that can be assigned in the method body; limits methods possible side effects
capture lists object refs that can be retained after the method return
duration specifies the maximum time needed to process a method call
accessible lists memory locations that methods may access
callable lists methods that can be called by the method under specification
17JML
in a
Nuts
hell
Heavyweight specs: behavior
/*@ behavior @ requires P; @ diverges D; @ assignable A; @ when W; @ ensures Q; @ signals (E1 e1) R1; @ ... @ signals (En en) Rn; @ accessible C; @ callable p(); @*/
18JML
in a
Nuts
hell
Heavyweight specs:normal behavior
• It is a behavior specification case with signals clause implicitly defined as signals (java.lang.Exception) false;
• guarantees normal termination no exception may be thrown
19JML
in a
Nuts
hell
Heavyweight specs:exceptional behavior
• It is a behavior specification case with ensures clause implicitly defined as ensures false;
• Guarantees that the method throws an exception
20JML
in a
Nuts
hell
Multiple cases specs
• Normal and exceptional spec cases may be combined
/*@ public normal_behavior @ requires !theStack.isEmpty(); @ assignable size, theStack; @ ensures @ theStack.equals(\old(theStack.trailer())) @ && \result == \
old(theStack.first()); @ also @ public exceptional_behavior @ requires theStack.isEmpty(); @ assignable \nothing; @ signals_only IllegalStateException; @*/
public Object pop();
21JML
in a
Nuts
hell
Class invariants
• Properties that must hold in all visible states of an object//@ public invariant x != null && !name.equals(“”);
• Static or Instance invariants
• Implicitly included in preconditions and normal and exceptional postconditions
• Do not hold for methods declared with clause helper
• private invariants state Rep Invariant
22JML
in a
Nuts
hell
Loop (in)variants
• Loop statements can be annotated with loop invariants and variant functions.
• Help in proving partial and total correctness of the loop statement
long sum = 0;int[] a = new int[100];int i = a.length;
/*@ mantaining -1 <= i && i <= a.length; @ mantaining sum == @ (\sum int j; i <= j && 0 <= j @ && j <= a.length; a[j]); @ decreasing i; @*/while (--i>=0)
sum += a[i];
23JML
in a
Nuts
hell
Assertions
• An assertion is a predicate that must always be true
//@ assert i>0 • w.r.t. Java 1.4+ assert JML
assertions cannot have any side-effects and can use JML expressions.
24JML
in a
Nuts
hell
History Constraints
• “Relationships that should hold for the combination of each visible state and any visible state that occurs later in the program execution”
• Used to constrain the way the values change over time
int a;//@ constraint a == \old(a);boolean[] b;//@ constraint b.lenght >= \old(b.lenght);
25JML
in a
Nuts
hell
Advanced Topics
• Model fields– Model methods and types– Fields visibility
• Abstract models
• Purity
• Data groups
• Specification inheritance
• Refinement
26JML
in a
Nuts
hell
Model fields
• Represents a field or a variable used only in specification
• Describes abstract values of objects• They can be mapped on a concrete field
using keyword represents
public class MathFoo {//@ public model epsprivate float error; //@ private represents eps <- error;}
27JML
in a
Nuts
hell
Visibility
• JML imposes visibility rules similar to Java• Keyword spec_public loosens visibility
for specs. Private spec_public fields are allowed in public specs.
private /*@ spec_public @*/ double x = 0.0;//@requires !Double.isNaN(x+dx)public void moveX(double dx){…
• Not a good practice! You are exposing internal representation!
28JML
in a
Nuts
hell
Abstract models
• JML provides a Java class library for specification purposes
• Package org.jmlspecs.model– Collections: sequence, set, bag– Algebric functions and relations– Exceptions and iterators
• Almost all are immutable objects with pure methods
• Can be used during RAC• Users can define their own models
29JML
in a
Nuts
hellPurity
• A pure method is a method without side effects (\assignable nothing)
• It is declared with the modifier pure• A class is pure if all its methods are
pure
• Only pure method are allowed in specifications
30JML
in a
Nuts
hell
Data groups
• A set of model and concrete fields to which you refer by a specific name
• A declaration of a model field automatically creates a data group with the same name of the model field
• The main purpose of a data group is to refer to the elements of this set without exposing their internal representation
• Locations members of a data group may be assigned during the executions of methods that have permission to assign to the data group
/*@ public model int size; @ public model JMLObjectSequence theStack; @ in size; @*/
31JML
in a
Nuts
hell
Specification inheritance
• A subclass inherits specifications of its superclass and of its implemented interfaces– All instance model fields– Instance method specifications– Instance invariants and instance history constraints
• Specifications of a superclass are conjuncted with new specs with the clause also
• Support behavioural notion of subtyping, accordingly to Liskov’s substitution principle:– preconditions are disjoined
– postconditions are conjoined as ∩ (old(prei) -> posti)– invariants are conjoined
32JML
in a
Nuts
hell
Refinement files
• Specifications can be separated from implementations
• Specs are written in a file Foo.java-refined
• Implementation is written in file Foo.java which contains the clause //@ refine “Foo.java-refined”
• Useful for adding specifications to existing code
33JML
in a
Nuts
hell
Example: IntSet
• Informal specification
“IntSets are unbounded sets of integers with operations to create a new empty IntSet, test whether a given integer is an element of an IntSet, and add or remove elements.”
34JML
in a
Nuts
hell
IntSet à la Liskov (1)
public interface IntSet {
public void insert(int x)//MODIFIES: this//EFFECTS: Adds x to the elements of this
public void remove(int x)//MODIFIES: this//EFFECTS: Removes x from this
public boolean isIn(int x)//EFFECTS: If x is in this returns true, else returns false.
}
Mutator
Mutator
Observer
35JML
in a
Nuts
hell
IntSet à la Liskov (2)
public class IntSetAs_list implements IntSet{…private Vector els;public IntSetAs_list(){
//EFFECTS: Initializes this to be empty.els = new Vector();
}…}
• Abstraction FunctionAF(c) = {c.els.get(i).intValue | 0 <= i < c.els.size}
• Representation Invariantc.els != null &&for all integers i (0 <= i < c.els.size => c.els.get(i) is an Integer) &&for all integers i, j | (0<= i < j < c.els.size => c.els.get(i).intValue != c.els.get(j).intValue)
36JML
in a
Nuts
hell
public interface IntSet { /*@ public model instance JMLValueSet theSet; @ public initially theSet != null && theSet.isEmpty(); @ public instance invariant theSet != null @ && (\forall JMLType e; theSet.has(e); @ e instanceof JMLInteger); @*/ /** Insert the given integer into this set. */ /*@ public normal_behavior @ assignable theSet; @ ensures theSet.equals(\old(theSet.insert(new JMLInteger(elem))));
@*/ public void insert(int elem); /** Tell if the argument is in this set. */ /*@ public normal_behavior @ ensures \result == theSet.has(new JMLInteger(elem)); @*/ public /*@ pure @*/ boolean isIn(int elem); /** Remove the given integer from this set. */ /*@ public normal_behavior @ assignable theSet; @ ensures theSet.equals( \old(theSet.remove(new
JMLInteger(elem))) ); @*/ public void remove(int elem);}
IntSet in JML (1)
Model Field
Abstract Invariant
37JML
in a
Nuts
hell
import java.util.*;//@ model import org.jmlspecs.models.*;public class IntegerSetAsList implements IntSet { private Vector els; //@ in theSet;
/*@ private invariant els != null && @ (\forall int i; 0<=i && i<els.size(); els.get(i) != null &&
@ els.get(i) instanceof Integer && @ (\forall int j=0; i<j && j<els.size(); els.get(i) != els.get(j))); @*/
//@ private represents theSet <- abstractValue();
/** Return the abstract value of this IntegerSetAsList. */ /*@
@ private pure model JMLValueSet abstractValue() { @ JMLValueSet ret = new JMLValueSet(); @ Iterator iter = els.iterator(); @ while (iter.hasNext()) { @ ret = ret.insert(new JMLInteger((Integer)
@ iter.next())); @ } @ return ret; @} @*/
IntSet in JML (2)
Abstraction Function
Rep Invariant
38JML
in a
Nuts
hell
IntSet in JML (3)
/** Initialize this set to be the empty set. *//*@ public normal_behavior @ assignable theSet; @ ensures theSet != null && theSet.isEmpty(); @*/public IntegerSetAsList() { els = new Vector();}public /*@ pure @*/ boolean isIn(int i) {
return els.contains(new Integer(i));}public void insert(int i) {
els.add(new Integer(i));}public void remove(int i) { els.remove(new Integer(i));}
39JML
in a
Nuts
hellTools
• Parsing & Typechecking
• Runtime assertion checking
• Testing
• Documentation
• Extended static checking
• Program verification
40JML
in a
Nuts
hell
jmlc
• The JML compiler
• Translates Java code with JML assertions into bytecode
• Adds runtime checks:– During execution, all assertions are
tested and any violation of an assertion produces an Error (uses jmlrac script).
41JML
in a
Nuts
helljmlunit
• Inserts support for JML within JUnit
• Writes out a JUnit test oracle for given Java files
• Specifications are used to check whether tested code runs properly Tests are only as good as the quality of the specifications!
43JML
in a
Nuts
hell
ESC/Java
• Extended Static Checker for Java• Tries to prove correctness of
specifications at compile-time, fully automatically
• Not sound: it may miss an error that is actually present
• Not complete: it may warn of errors that are impossible
• It finds a lot of potential bugs quickly:– NullPointer, ArrayIndexOutOfBounds, ClassCast…
44JML
in a
Nuts
hellLOOP
• Logic of Object Oriented Programming, project of University of Nijmegen
• Based on a formalization of Java and JML semantics in the theorem prover PVS
• LOOP compiler translates JML annotations in PVS proof obligations, to be proved interactively
45JML
in a
Nuts
hell
Related Works
• Early programming languages– Gypsy– Alphard– Euclid– CLU
• DBC based– Eiffel– SPARK– B method
• OCL from UML• Spec#
46JML
in a
Nuts
hell
Conclusions
Strenghts• Easy to learn• Source code is
the formal model– Gradual
introduction– Support for
legacy code
• Wide range of tools
Weakenesses• No support for:
– concurrency– object invariants
within callbacks– modeling alias
relationships
• Strong definition of pure methods:– many constraints