47
Politecnico di Milano Advanced Topics in Software Engineering JML in a Nutshell Domenico Bianculli & Alessandro Monguzzi {bianculli, alessandro.monguzzi}@gmail.com June 16th, 2005 Rev. 1.3

Politecnico di Milano Advanced Topics in Software Engineering JML in a Nutshell Domenico Bianculli & Alessandro Monguzzi {bianculli, alessandro.monguzzi}@gmail.com

Embed Size (px)

Citation preview

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

4JML

in a

Nuts

hellSyntax

• Annotations

• Expressions

• Quantification

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!

42JML

in a

Nuts

helljmldoc

• Produces HTML pages with API and JML specifications for Java classes

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

47JML

in a

Nuts

hell

References

www.jmlspec.org