design by contract using jmsassert. design by contract a method of separating the concerns of the...

30
Design By Design By Contract Contract Using JMSAssert

Upload: dawson-regis

Post on 29-Mar-2015

216 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Design By ContractDesign By Contract

Using JMSAssert

Page 2: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Design By ContractDesign By Contract A method of separating the concerns of the

user and implementer of the class, and giving both enough information for their tasks.

Work in this course will be done with Java, offers partial support for those concepts.

Each class and method should be documented in Javadoc style.

Page 3: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Design By ContractDesign By Contract In order to implement the principles of Design-by-

Contract in Java, we will use a free tool from Man Machine Systems names JMSAssert.

It works with Sun’s JDK 1.2 & 1.3 but not 1.4

Page 4: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Design By ContractDesign By Contract A powerful technique for writing reliable

software. Specifying the software purpose with the

implementation. Key elements:

Invariant Preconditions Postconditions

Page 5: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Design By ContractDesign By Contract Precondition – The constraints under

which the routine will function properly. Postconditions – The state of the class after

the routine execution The Contract: If you call routine R() with

the preconditions satisfied, R() will return satisfying the postconditions.

Invariant – Always holds

Page 6: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

When are condition checked?When are condition checked?

Event InvariantPre-

conditionPost-

conditionInstance Method Y Y -Constructor N Y -Private Method N Y -Static Method N Y -Instance Method Y - YConstructor Y - YPrivate Method N - YStatic Method N - Y

Method Entry

Method Exit

Page 7: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

JMS Syntax - InvariantJMS Syntax - Invariant Invariant - @inv May access all class members or its

direct/indirect bases, including private members

May appear in any JavaDoc comment Preferable in the class comment

Page 8: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

JMS Syntax - PreconditionsJMS Syntax - Preconditions Precondition - @pre JavaDoc preceding the respective method May reference class members and

arguments Multiple @pre markers are conjugated

(AND)

Page 9: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

JMS Syntax - PostconditionsJMS Syntax - Postconditions Postconditions - @post JavaDoc preceding the respective method May use $prev(expression) to access the

value at the method entry. May use $ret to denote method’s return

value Multiple @post markers are conjugated

(AND)

Page 10: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

ExampleExample

/** * @pre !isEmpty() * @post (top == $prev(top- 1)) * @post $ret == elems[top] * @post !isFull*/public synchronized Object pop() {

return elems[--top];}

Precondition

Postconditions

Page 11: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

ExampleExample

/** * @pre !isEmpty() * @post (top == $prev(top- 1)) * @post $ret == elems[top] * @post !isFull*/public synchronized Object pop() {

return elems[--top];}

Precondition

Postconditions

What is wrong in the example ?

Page 12: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

JMS Syntax - GeneralJMS Syntax - General Order has no meaning @macro – for complicated conditions Recursion – as expected, on every call Inner classes can access outer classes’

members Anonymous classes – specify invariant in

one of its methods

Page 13: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Downloads & InstallationsDownloads & Installations Download Java J2SE SDK 1.3.1 from

http://java.sun.com/downloads (~41MB)Install into C:\Program Files\jdk1.3.1_07

Download JMSAssert 1.02 from http://www.mmsindia.com (~1.2MB)Run the jmssetup-1.02.exe installation fileInstall into C:\Program Files\AMSAssert1.0

Page 14: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

JMSAssert InstallationJMSAssert Installation The following lines are added to the path:REM Next two lines are added by JMSAssert

SET CLASSPATH=%CLASSPATH%;C:\PROGRA~1\JMSASS~1.0\

bin\mmsclasses.jar;

SET PATH=%PATH%;C:\PROGRA~1\JMSASS~1.0\bin;

Copy the “classic” directory from “C:\Program Files\jdk1.3.1_07\jre\bin\” to the directory:“C:\Program Files\JavaSoft\JRE\1.3.1_07\bin\”

Page 15: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Setup Setup (cont.)(cont.)

Your JavaSoft directory should look like:

Page 16: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

JMSAssert – how does it workJMSAssert – how does it work Annotate source code with assertions Compile your code using javac (as usual) Preprocess the code using jmsassert: creates

contract files (*.jms) and a Startup.jms file. *.jms files contain java code for the assertions. Execute using: jmsjava Startup <filename>to check assertions.

jmsjava makes sure method assertions are called before/after the method invocation.

Page 17: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

JMS ExecutionJMS Execution “jmsassert” – generates help text “jmsassert –s <filename.java>” – generate

assertions for a class file “jmsassert –r –s .” – generate assertions for

all class files in the directory and sub-dirs. (use for packages)

“javac <filename.java>” – compile “jmsjava Startup <main>” - execute and check

assertions

Page 18: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Annotate source with assertions

MyStack.java

Stack Demo Stack Demo filesfiles

Execution Execution processprocess

Page 19: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Annotate source with assertions

Preprocess to generate assertion

filesjmsassert –s <file.java>

MyStack.java

Startup.jms

default_MyStack.jmsdefault_MyStack_StackEnum.jms

Stack Demo Stack Demo filesfiles

Execution Execution processprocess

Page 20: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Annotate source with assertions

Preprocess to generate assertion

filesjmsassert –s <file.java>

Compile Java file

javac <file.java<

MyStack.java

Startup.jms

default_MyStack.jmsdefault_MyStack_StackEnum.jms

MyStack.classMyStack$StackEnum.classMyStack$StackEnum.classStackTest.class

Stack Demo Stack Demo filesfiles

Execution Execution processprocess

Page 21: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

Annotate source with assertions

Preprocess to generate assertion

filesjmsassert –s <file.java>

Compile Java file

javac <file.java<

Execute using jmsjava

MyStack.java

Startup.jms

default_MyStack.jmsdefault_MyStack_StackEnum.jms

MyStack.classMyStack$StackEnum.classMyStack$StackEnum.classjmsjava Startup <classname> StackTest.class

Stack Demo Stack Demo filesfiles

Execution Execution processprocess

Page 22: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

NotesNotes Execute these steps form the command line! Make sure your CLASSPATH environment

variable contains the current directory.Add “CLASSPATH=%CLASSPATH%;.” to autoexec.bat.

Page 23: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

An Example (MyStack)An Example (MyStack) A stack with invariants, pre conditions and post

conditions: MyStack.java A main file: StackTest.java Compile all .java files (using javac) Generate JMSAssert triggers by:jmsassert –s MyStack.java

Run and test assertions byjmsjava Startup StackTest

You can always run your test program in byjava StackTest

Page 24: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

MyStack.java (#1)MyStack.java (#1)/**

@inv (top >= 0 && top < max)

*/

class MyStack {

private Object[] elems;

private int top, max;

Page 25: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

MyStack.java (#2)MyStack.java (#2).

/**

@pre (sz > 0)

@post (max == sz && elems != null)

*/

public MyStack(int sz) {

max = sz;

elems = new Object[sz];

}

Page 26: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

MyStack.java (#3)MyStack.java (#3)

/**

@pre !isFull()

@post (top == $prev (top) + 1) && elems[top-1] == obj

*/

public void push(Object obj) {

elems[top++] = obj;

}

Page 27: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

MyStack.java (#4)MyStack.java (#4)

/**

@pre !isEmpty()

@post (top == $prev (top) - 1) && $ret == elems[top]

*/

public Object pop() {

return elems[--top];

}

Page 28: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

MyStack.java (#5)MyStack.java (#5)

/**

@post ($ret == (top == max))

*/

public boolean isFull()

{

return top == max;

}

Page 29: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

MyStack.java (#6)MyStack.java (#6)

/**

@post ($ret == (top == 0))

*/

public boolean isEmpty()

{

return top == 0;

}

} // End MyStack

Page 30: Design By Contract Using JMSAssert. Design By Contract A method of separating the concerns of the user and implementer of the class, and giving both enough

StackTest.javaStackTest.java

class StackTest {

public static void main(String[] args) {

MyStack s = new MyStack(2); // Can push at most 2 elements

s.push(new Integer(1));

s.push(new Integer(23));

s.push(new Integer(0)); // Precondition violation here!

}

}