Академический Документы
Профессиональный Документы
Культура Документы
Programs
April 2016
Software Practices Laboratory
Federal University of Campina Grande
April 2016
Abstract
When correcting a nonconformance in a contract-based program, a developer may need to change the code, the
contract, or both. In this work, we present suggestions for 119 nonconformances detected by J ML O K 2 in 12
Java/JML programs. As a result of this suggestions, we found the contract as the artifact in which the most fixes
need to be applied (77%). Furthermore, the most recurrent kind of fix was add preconditions to methods and
constructors (almost 40%). This work is a step towards to understand the process of correcting nonconformances
in Java/JML programs.
List of Tables
1 Experimental units summary. Column KLOC shows the code size of each experimental unit.
Column # CC presents the total of contract clauses of each experimental unit. Column # NC
displays the number of nonconformances detected in each unit. . . . . . . . . . . . . . . . . . . . 2
2 Fixes summary. Column Artifact groups the fixes by the part (code or contract) in which the fix is
implemented. Column Kind of fix shows the kinds of fixing recommended. Column # instances
display the number of occurrences of each kind of fix. . . . . . . . . . . . . . . . . . . . . . . . . 23
3 Fixes summary for each experimental unit. Column Experimental Unit presents the name of
each unit. Column Artifact groups the fixes by the part (code or contract) in which the fix is
implemented. Column Kind of fix shows the kinds of recommended. Column # instances display
the number of occurrences of each kind of fix. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1 Introduction
According to Pei and colleagues [Pei et al. 2014a], a software bug is the manifestation of a discrepancy between
contracts and implementation: program behavior (implementation) deviates from expectations (contracts). There-
fore, the correction of a bug may involve changing code, contracts, or both.
In the present work, we investigate the problem of fixing nonconformances in the context of Java/JML pro-
grams. For this purpose, we manually suggest fixes for 119 nonconformances detected by J ML O K 2 in 12 open-
source JML projects summing up 26.2 Java KLOC and 2.7 K contract clauses (that we will refer as KCC, in this
work). Furthermore, we analyze the most common fix for solving those nonconformances and in which artifact
(code or contract) the fix is applied.
In summary, the main contribution of this work is the following:
A list of suggestions for fixing all nonconformances detected by J ML O K 2 into 12 experimental units (Sec-
tion 2.2).
1
Table 1: Experimental units summary. Column KLOC shows the code size of each experimental unit. Column
# CC presents the total of contract clauses of each experimental unit. Column # NC displays the number of
nonconformances detected in each unit.
Experimental Unit KLOC # CC # NC
Bank 0.79 126 3
Bomber 6.25 120 5
Dnivra-Jive 0.23 94 6
HealthCard 2.15 576 41
JAccounting 6.64 194 26
Javacard API 3.30 46 7
Mondex 0.65 62 2
PayCard 0.11 49 0
PokerTop 0.31 187 1
Samples 3.85 1,084 18
TheSchorrWaiteAlgorithm 0.11 16 2
TransactedMemory 1.78 150 8
Total 26.17 2,704 119
2.2.1 Bank
Invariant problem at ATM constructor
To avoid having to constantly specify that declarations (other than local variables) are non-null, JML makes
them implicitly non null by default [Leavens et al. 2013]. Since the field insertedCard is initialized with a
null value, the developer should add /*@ nullable @*/ in the field declaration, in order to avoid this invariant
error. The code with this suggestion is presented bellow:
public class ATM {
private /*@ spec_public nullable @*/ BankCard insertedCard = null;
}
2.2.2 Bomber
Invariant problem at Building constructor
2
In this case, there are two options for fixing this nonconformance: one related to the code: an initialization
of m projection x field with a new object from Point class; and one related to the contract: since the
field m projection x is not initialized into the default constructor, the developer could add a clause /*@
nullable @*/ in the field declaration. The code with this suggestion is presented bellow:
public class Building {
//Code fixing
protected Point m_projection_x = new Point();
//Contract fixing
protected /*@ nullable @*/ Point m_projection_x;
}
Postcondition problem at mod method (Common class) The developer should add a precondition checking
whether the value of y is different of zero: //@ requires y != 0. The code with this suggestion is presented
bellow:
public class Common {
//@ requires y != 0;
public static int mod(int x, int y){
// ...
}
}
3
public class FlakSmoke implements Visual {
public /*@ nullable @*/ Object getBoundingBox(){
return null;
}
}
2.2.3 Dnivra-Jive
Postcondition problem at divideComplexNumber method (package complex, class ComplexNumber)
Since the developer uses the value of 0.005 (the ghost field tolerance) to compare two double values
using the method approximatelyEqualTo from JMLDouble class, a possible way of solve this problem is
increase the value, for instance increasing to 0.01. The code with this suggestion is presented bellow:
public class ComplexNumber {
//@ public ghost static final double tolerance = 0.01;
}
4
public class QuickSort {
//@ ensures(\forall int i; 0 <= i && i < numbers.length-1; numbers[i] <= numbers[i +1]);
public void quickSort(){
//...
}
}
2.2.4 HealthCard
Precondition problem at setDesignation method (package allergies - Allergy Impl class)
The developer should remove the exceptional behavior definition from the setAllergyDesignation
(Allergies interface) method in order to avoid the precondition problem at setDesignation method. The
code removing the exceptional behavior definition is presented below:
public interface Allergies extends Common {
/*@ public normal_behavior
@ requires position >= 0 && position < AllergiesSetup.MAX_ALLERGY_ITEMS;
@ requires allergies_model.itemAt(position) != null;
@ requires designation != null && designation.length == AllergiesSetup.ALLERGY_CODE_LENGTH;
@ requires (\forall int i; 0 <= i && i < AllergiesSetup.ALLERGY_CODE_LENGTH;
@ ((byte)0x41 <= designation[i] && designation[i] <= (byte)0x5A )
@ || ((byte)0x61 <= designation[i] && designation[i] <= (byte)0x7A )
@ || ((byte)0x30 <= designation[i] && designation[i] <= (byte)0x39 ));
@ assignable allergies_model;
@ ensures (((Allergy) allergies_model.itemAt(position)).designation_model)
@ .equals(toJMLValueSequence(designation));
@*/
public void setAllergyDesignation(short position, byte[] designation)
throws RemoteException, UserException;
}
5
@ assignable allergies_model;
@ ensures allergies_model.count(null) == \old(allergies_model).count(null)+1;
@ ensures ((allergies_model.subsequence(position, AllergiesSetup.MAX_ALLERGY_ITEMS - 1)).
@ equals(\old(allergies_model).subsequence(position+1, AllergiesSetup.MAX_ALLERGY_ITEMS))
@ && allergies_model.itemAt(AllergiesSetup.MAX_ALLERGY_ITEMS - 1) == null)
@ || allergies_model.itemAt(AllergiesSetup.MAX_ALLERGY_ITEMS - 1) == null;
@*/
public void removeAllergy(short position) throws RemoteException, UserException;
}
6
need to be done every day. The constructors body without the initialization of one item of appointments is
presented below:
public class Appointments_Impl implements Appointments {
public Appointments_Impl (/*SecurityService security*/) {
super();
appointments = new Appointment[(short)AppointmentsSetup.MAX_APPOINTMENT_ITEMS];
}
}
Constraint problems at getDate, getDoctor, getHour, getID, getLocal, getType, setDate, and toString meth-
ods
The nonconformances revealed by the methods getDate, getDoctor, getHour, getID, getLocal,
getType, setDate, and toString are related to some constraints defined into Common interface; so, the
way of solving them is to add a requires clause concerning the size of the values received as parameter in the
constructor of the classes who implement this interface, according to each constraint that can be violated. An
example of precondition is presented below, for the case of the Appointment Impl class:
public class Appointment_Impl implements Appointment {
/*@
@ requires date.length == DATE_LENGTH && hour.length == HOUR_LENGTH
@ && local.length == LOCAL_CODE_LENGTH && doctor.length == DOCTOR_CODE_LENGTH;
@*/
public Appointment_Impl(byte id, byte[] date, byte[] hour, byte[] local, byte[] doctor, byte
type){ //...
}
7
Postcondition problem at getDescription method (package diagnostics - Diagnostic Impl class)
The postcondition problem can be avoided by adding a precondition to getDescription method, checking
if the value of the parameter size is in range [0, MAX BUFFER BYTES-1] - the size of buffer field, and also
checking if the value of the parameter offset is in range [0, DiagnosticsSetup.MAX DESCRIPTION -
LENGTH-1] - the size of description field. The code added by this precondition is presented below:
public interface Diagnostic {
/*@ requires size >= 0 && size < MAX_BUFFER_BYTES;
@ requires offset >= 0 && offset < DiagnosticsSetup.MAX_DESCRIPTION_LENGTH;
@*/
public byte[] getDescription(short offset, short size);
}
8
public interface Medicine {
//@ requires 0 <= appointmentID && appointmentID <= 127;
public void setAppointmentID(byte appointmentID);
}
9
public interface Treatment {
//@requires 0 <= appointmentID && appointmentID <= 127;
public void setAppointmentID(byte appointmentID);
}
10
UserException as the only kind of exception to be thrown in this method, and the method throws a ArrayIn-
dexOutOfBoundsException when there is a try to remove one element of one position from the array that
exceeds its the size when called with values greater than 50 (the value of MAX VACCINE ITEMS setup field).
The code without the exceptional behavior declaration is presented below:
public interface Vaccines extends Common {
/*@ public normal_behavior
@ requires position >= 0 && position < VaccinesSetup.MAX_VACCINE_ITEMS;
@ requires vaccines_model.itemAt(position) != null;
@ assignable vaccines_model;
@ ensures vaccines_model.count(null) == \old(vaccines_model).count(null)+1;
@ ensures ((vaccines_model.subsequence(position, VaccinesSetup.MAX_VACCINE_ITEMS - 1 ))
@ .equals(\old(vaccines_model).subsequence(position+1, VaccinesSetup.MAX_VACCINE_ITEMS))
@ && vaccines_model.itemAt(VaccinesSetup.MAX_VACCINE_ITEMS - 1) == null)
@ || vaccines_model.itemAt(VaccinesSetup.MAX_VACCINE_ITEMS - 1) == null;
@*/
public void removeVaccine (short position) throws RemoteException, UserException;
}
2.2.5 JAccounting
Evaluation problem at getCurrency method (package accounting.basic - Account class)
This nonconformance occurs because the field currency is not initialized into the default constructor of
Account class, so, a way of solving it is to initialize the field directly in its declaration. The code presenting this
initialization is presented below:
public class Account {
/*@ spec_public @*/String currency = "";
}
11
Evaluation problem at getDescription method (package accounting.basic - Account class)
This nonconformance occurs because the field description is not initialized into the default constructor
of Account class, so, a way of solving it is to initialize the field directly in its declaration. The code presenting
this initialization is presented below:
public class Account {
public String description = "";
}
Postcondition and Evaluation problems at getName method (package accounting.basic - AClass class)
A way of solving both nonconformances that can appear in this method is to add a precondition for getName,
checking if the field name is not null and not equals to the empty string. The code added by this precondition is
presented as follows:
public class AClass extends Object {
//@ requires this.name != null && !this.name.equals("");
//@ post !\result.equals("");
public String getName() {
return name;
}
}
12
- to indicate a negative value or an ASCII plus sign + to indicate a positive value.7 The code presenting the
precondition is shown below:
public class ArrayUtils extends Object {
//@ requires (\forall int i; 0 <= i && i < sarray.length; sarray[i].matches("[0-9]+"));
public static int[] stringArrayToIntArray(String sarray[]){
// ...
}
}
7 https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html
8 https://docs.oracle.com/javaee/6/api/javax/servlet/http/Cookie.html
13
//@ requires value != null;
public static Cookie getCookie(String name, String value, int seconds){
// ...
}
}
14
public class PageElements {
String pageTitle = "";
String sectionColor = "";
String sectionTitle = "";
String mainPage = "";
String searchSection = "";
}
15
2.2.6 Javacard
Invariant problem at APDU (package javacard.framework - APDU class)
To solve this problem, the developer should add a clause: /*@ nullable @*/ to the declarations of
buffer and instance fields. Another option could be initialize both fields. The code with the former
suggestion is presented below:
public final class APDU {
private /*@ nullable @*/ byte[] _buffer;
private /*@ nullable @*/ static APDU _instance;
}
2.2.7 Mondex
Invariant problem at APDU class (package javacard.framework)
This problem can be solved by the initialization of the buffer array in order to avoid the violation of one
class invariant. The code presenting the initialization of the field is presented below:
public final class APDU {
private /*@ spec_public @*/ byte[] _buffer = new byte[BUFFER_LENGTH];
}
16
PayDetails initializes this value with 0 the invariant (transaction.value > 0) is also broken. There-
fore, the developer needs to add a fix in the code: initializes the exLog array and change the invariant. After
contacting Mondex [Schmitt and Tonin 2007] developers, they suggested the following changes to solve the non-
conformance:
public class ConPurseJC extends Applet {
/*@ public invariant
@ (exLog != null) && (exLog.length > 0) && (exLog.length < (APDU.BUFFER_LENGTH / 10)) &&
@ (logIdx >= 0) && (logIdx <= exLog.length) && (balance >= 0) && (balance <= ShortMaxValue) &&
@ (nextSeq >= 0) && (nextSeq <= ShortMaxValue) && (status >= 0) && (status <= 5) &&
@ (transaction != null) && ((transaction.value > 0) ||
@ ((status == Idle) && (transaction.fromName == 0) && (transaction.toName == 0) &&
@ (transaction.value == 0) && (transaction.fromSeq == 0) && (transaction.toSeq == 0))) &&
@ ((status == Epr) ==> (transaction.value <= balance)) &&
@ ((status == Epv) ==> (transaction.value <= (ShortMaxValue - balance))) &&
@ (\forall byte i; i>=0 && i<exLog.length; exLog[i] != null);
@*/
// Code changes
private ConPurseJC(){
// ...
// exLog length must be smaller or equal than the 1/10 APDU buffer length
exLog = new PayDetails[25];
for(short i=0; i<exLog.length; i++){
exLog[i] = new PayDetails();
}
//...
}
}
2.2.8 PokerTop
Invariant problem at Dealer class
This problem can be solved by removing the comments (\\) from the lines where the fields button and pot
are initialized. The code with all fields initialized is presented below:
public Dealer() {
this.blind = new Blind(0, 0, 0);
this.button = new Button();
this.deck = new Deck();
this.pot = new Pot(0);
}
2.2.9 Samples
Package dbc
Postcondition problem at angle method (package samples.dbc - Polar class)
Since the problem in this method is apparently related to a call to JMLDouble API, a way of solving the
problem is changing the postcondition of angle method into Complex interface. The code presenting the
suggested postcondition is presented below:
public /*@ pure @*/ interface Complex {
/*@
@ ensures StrictMath.atan2(imaginaryPart(), realPart()) <= \result + tolerance ||
@ StrictMath.atan2(imaginaryPart(), realPart()) >= \result + tolerance;
@*/
double angle();
}
Postcondition problem at imaginaryPart method (package samples.dbc - Polar and Rectangular classes)
In both classes, the problem is apparently related to the call to JMLDouble API, so, a way of solving it
is changing the postcondition of imaginaryPart method into Complex interface. The code presenting the
suggested postcondition is presented below:
public /*@ pure @*/ interface Complex {
/*@
@ ensures \result + tolerance >= magnitude()*StrictMath.sin(angle()) ||
@ \result + tolerance <= magnitude()*StrictMath.sin(angle()) ||
@ Double.isNaN(\result);
@*/
double imaginaryPart();
}
17
Postcondition problem at realPart method (package samples.dbc - Rectangular class)
Since the problem in this method is apparently related to a call to JMLDouble API, a way of solving the
problem is changing the postcondition of realPart method into Complex interface. The code presenting the
suggested postcondition is presented below:
public /*@ pure @*/ interface Complex {
/*@
@ ensures \result + tolerance >= magnitude()*StrictMath.cos(angle()) ||
@ \result + tolerance <= magnitude()*StrictMath.cos(angle()) ||
@ Double.isNaN(\result);
@*/
double realPart();
}
Package list
Postcondition problem at getEntry method (package samples.list.list1 - DLList class)
This problem may be solved by adding a /*@ nullable @*/ clause in the method declaration. The code
added by this clause is shown below:
public class DLList extends E_SLList {
public /*@ nullable @*/ Object getEntry() {
// ...
}
}
18
} else if (nd1.getEntry() == nd2.getEntry()) {
if (nd1 == nd2) {
return true; // changed here
} else {
return equalsNode(nd1.getNextNode(), nd2.getNextNode());
}
} else {
return false;
}
}
}
Package misc
Postcondition problem at limit method (package samples.misc - SingleSolution class)
In order to solve this problem, the developer should add a precondition to SingleSolution constructor
restricting the parameter n to be greater than or equals to zero. The code presenting this precondition is available
below:
public abstract class SingleSolution extends LinearSearch {
//@ requires n >= 0;
//@ assignable this.n;
//@ ensures this.n == n;
public SingleSolution(int n) {
this.n = n;
}
}
Package stacks
Postcondition and Invariant problems at BoundedStack (package samples.stacks)
The two nonconformances present in this class are related to the same problem: the absence of a precondition
in the constructor that restricts the range of valid values to the parameter maxSize. The code presenting the
precondition for the constructor is presented below:
public class BoundedStack implements BoundedStackInterface {
/*@ public normal_behavior
@ requires maxSize > 0;
@ assignable MAX_SIZE, size, theStack;
@ ensures theStack.equals(new JMLObjectSequence());
@ ensures_redundantly theStack.isEmpty() && size == 0
@ && MAX_SIZE == maxSize;
@*/
public BoundedStack(int maxSize){
theItems = new Object[maxSize];
19
nextFree = 0;
this.maxSize = maxSize;
}
}
20
first = false;
} else {
ret.append(", ");
}
try {
if (theItems[k] != null) {
ret.append(theItems[k]);
} else {
ret.append("null");
}
} catch (NullPointerException e) {
ret.append("null");
}
}
ret.append("]");
return ret.toString();
}
}
2.2.10 TheSchorrWaiteAlgorithm
Postcondition problem at getChild method (HeapObject class)
Since the problem occurs because the method returns a null value, a developer might add the clause /*@
nullable @*/ in the method declaration in order to avoid the nonconformance (null is not the default). The
code added by this clause is presented as follows:
public class HeapObject {
public /*@ nullable @*/ HeapObject getChild(int pos) {
//...
}
}
2.2.11 TransactedMemory
Package JavaImplementation
Invariant problem at DPage class (package JavaImplementation)
In order to solve this nonconformance, the developer should add a precondition to DPage constructor, defining
the range of valid values to the parameters that are related to the invariants of this class. The code presenting this
precondition is shown as follows:
public class DPage{
//@ requires 0 <= tag && tag < TransactedMemory.TSIZE;
//@ requires VA <= version && version <= VC;
//@ requires 0 <= generation && generation < MAXGEN;
//@ requires 0 <= pageNumber && pageNumber < InfoSeq.SSIZE;
public DPage (boolean pageInUse, int tag, int info, int generation, int pageNumber, int version) {
//...
}
}
21
Package JavaImplementationEnums
Invariant problem at DTagData class (package JavaImplementationEnums)
In order to solve this nonconformance, the developer should add a precondition to DTagData constructor,
defining the range of valid values to the parameter size. The code with the precondition is presented below:
public class DTagData{
//@ requires size > 0;
public DTagData(boolean tagInUse, int size, boolean committed){
//...
}
}
22
2.3 Results
In Table 2 we make available a summary of all fixes suggested through the Section 2.2. According to the fix
suggested, we grouped them and display the artifact in which this fix should be applied. Column Artifact exposes
the artifact in which the fix should be implemented. Then, column Kind of fix shows the kinds of recommended
fix. Finally, column # instances display how many times this fix was proposed by the manual analysis of each
nonconformance. Moreover, Table 3 presents the fixes grouped for each experimental unit.
Table 2: Fixes summary. Column Artifact groups the fixes by the part (code or contract) in which the fix is
implemented. Column Kind of fix shows the kinds of fixing recommended. Column # instances display the
number of occurrences of each kind of fix.
Artifact Kind of fix # instances
Add precondition 47
Contract Update an existing contract clause 25
Add nullable clause 19
Initialization of field(s) 21
Code
Change the body of a method 7
Concerning the artifact, the manually suggested fixes are distributed in the following way: 91 fixes into the
contracts and 28 into the code. Most of the suggested fixes are related to add a precondition to a method or
constructor (Add precondition) with 47 occurrences. And regarding to code changes, the necessity of initialization
of some field is also recurrent (21).
Respecting the experimental units used, in nine of them the contract was the part in which more fixes were
needed, only in Mondex and PokerTop the code fix was more common. For those units, there were six cases
in which just one or two kinds of fixing was needed to solve all nonconformances: Bank, Dnivra-Jive,
Javacard, Mondex, PokerTop, and TheSchorrWaiteAlgorithm. On the other hands, the units with
the biggest numbers of nonconformances were those in which more different kinds of fixing were applied:
HealthCard (5), Samples (5), JAccounting (4).
2.4 Discussion
As presented in Section 2.3, the most common fix was add a precondition to a method or constructor. This
result it was expected by the fact of developers in general tend to be more opened in the precondition and add
restrictions into postconditions or invariants. Furthermore, previous studies [Milanez 2014], [Milanez 2015]
have already found Weak precondition as the most typical likely cause for nonconformances. As the Design by
Contract [Meyer 1997] methodology establishes rights and obligations for both clients and suppliers, the definition
of a precondition is a task that demands experience: if the precondition is so restrictive clients may be missed;
however, if it does not impose any restrictions, suppliers may be not able to deliver what they are supposed to.
Furthermore, sometimes the clients are not known when the supplier system is being developed, and the developer
needs to look for a reasonable trade-off between the level of restrictions and commitment of each part of the
system (e.g. each method or class).
In JML [Leavens et al. 2006] null is not the default [Leavens et al. 2013], because of this requirement, we have
40 suggestions related to: 19 cases where we believe that the add of /*@ nullable @*/ clause is suitable (the
Add nullable clause into Table 2) indicating to the JML compiler [Cheon and Leavens 2002] that a field or
method return may be null; and 21 cases where the initialization of some fields is apparently more applicable in
order to solve the nonconformance. Theses nonconformances related to null may have been occurred in reason of
some update into the JML language made after the development of the experimental units or because the contract-
aware compiler used into J ML O K 2 - the jmlc [Cheon and Leavens 2002]; nevertheless, it is important to solve the
problems either by adding a clause to say to the compiler that null is allowed or by assigning a value to a class
field.
Given the correction of a nonconformance may involve changing code, contracts, or both [Pei et al. 2014a],
we had some cases in which a change in the code and in the contract was needed to solve the problem. This was
the case of a nonconformance into Mondex [Schmitt and Tonin 2007] system: the nonconformance presented
in ConPurseJC class required a change in the body of ConPurseJC constructor and a change into one class
invariant. We also found some instances where it was possible change code or contract, as for instance, the
23
Table 3: Fixes summary for each experimental unit. Column Experimental Unit presents the name of each unit.
Column Artifact groups the fixes by the part (code or contract) in which the fix is implemented. Column Kind of
fix shows the kinds of recommended. Column # instances display the number of occurrences of each kind of fix.
Experimental Unit Artifact Kind of fix # instances
Contract Add nullable clause 2
Bank
Code Change the body of a method 1
Add nullable clause 2
Contract
Bomber Add precondition 2
Code Initialization of field(s) 1
Add precondition 3
Dnivra-Jive Contract
Update an existing contract clause 3
Add precondition 24
Contract Update an existing contract clause 13
HealthCard Add nullable clause 2
Change the body of a method 1
Code
Initialization of field(s) 1
Code Initialization of field(s) 12
Add precondition 7
JAccounting
Contract Add nullable clause 4
Update an existing contract clause 3
Contract Add nullable clause 5
Javacard
Code Initialization of field(s) 2
Mondex Code Initialization of field(s) 2
PokerTop Code Initialization of field(s) 1
Update an existing contract clause 6
Contract Add precondition 5
Samples Add nullable clause 2
Change the body of a method 4
Code
Initialization of field(s) 1
TheSchorrWaiteAlgorithm Contract Add nullable clause 2
Contract Add precondition 6
TransactedMemory Change the body of a method 1
Code
Initialization of field(s) 1
cases related to null values: in which add a /*@ nullable @*/ clause or initializes the field, would solve the
problem. In such cases, we looked into class comments in order to choose a suitable correction.
Notwithstanding, there were problems where a single correction was able to solve two or more nonconforman-
ces. This was the case of Common interface (HealthCard unit) constraint problems: by adding a precondition to
the constructor of Appointment Impl class, all problems were solved. Other case were the nonconformances
of evaluation and postcondition into getName from AClass (JAccounting unit) that were solved by adding a
single precondition to the method. Those cases are in accordance to software testing concepts [Sommerville 2010]:
several failures may be related to the same error - in the context of contract-based programs, the error can be in
the source code, in the contracts, or in both.
3 Related Work
In the context of contract-based programs [Guttag et al. 1993], the AutoFix [Wei et al. 2010], [Pei et al. 2011],
[Pei et al. 2014a], [Pei et al. 2014b] approach is available for Eiffel [Meyer 1987] programs. AutoFix is a tech-
nique and supporting tool that can generate corrections for faults of general-purpose software automatically. The
tool combines various program analysis techniques such as dynamic invariant inference, simple static analysis,
and fault localization and produces a collection of suggested fixes, ranked according to a heuristic measurement
24
of relevance. This tool is currently integrated into EiffelStudio Development Environment [Pei et al. 2015]. In
this work, we address the manual suggestion of fixes for the context of Java/JML programs, aiming to create a
basis for automation of the correction process.
4 Conclusions
In the present paper, we created a set of fix suggestions for the 119 nonconformances detected by J ML O K 2 in a
previous study [Milanez 2015]. For each nonconformance being corrected, we explain the thought line followed
and present a code excerpt (either source code or contract code) that is able to solve the problem. As presented in
Section 2.2, we were able to find more than one fix to some problems, so we presented the reasons for choosing
between one or another. In other cases, we detected one fix as being able to solve more than one nonconformance.
All experimental units updated with the fixes suggested in this study are available online.9
We also found that the contract is the artifact in which more changes are needed (77% of the cases) and the
most common fix was the addiction of a precondition to a method or constructor (39.5% of the cases). Moreover,
changes to code were also recurrent: the initialization of fields where the solution for 21 nonconformances.
This work is a step towards to understand the process of correcting nonconformances in Java/JML programs.
As future work, we intend to develop an approach for creating fix suggestions for this context.
References
[Beckert et al. 2007] Beckert, B., Hahnle, R., and Schmitt, P. H. (2007). Verification of Object-oriented Software:
The KeY Approach. Springer-Verlag.
[Cheon and Leavens 2002] Cheon, Y. and Leavens, G. (2002). A Runtime Assertion Checker for the Java Mod-
eling Language (JML). In SERP 2002, pages 322328. CSREA Press.
[Guttag et al. 1993] Guttag, J. V., Horning, J. J., Garl, W. J., Jones, K. D., Modet, A., and Wing, J. M. (1993).
Larch: Languages and Tools for Formal Specification. Spring-Verlag, 1st edition.
[Leavens et al. 2006] Leavens, G., Baker, A., and Ruby, C. (2006). Preliminary Design of JML: A Behavioral
Interface Specification Language for Java. SIGSOFT Softw. Eng. Notes, 31:138.
[Leavens et al. 2013] Leavens, G. T., Poll, E., Clifton, C., Cheon, Y., Ruby, C., Cok, D., Mller, P., Kiniry, J.,
Chalin, P., Zimmerman, D. M., and Dietl, W. (2013). JML Reference Manual.
[Meyer 1987] Meyer, B. (1987). Eiffel: programming for reusability and extendibility. SIGPLAN Not., 22:8594.
[Meyer 1997] Meyer, B. (1997). Object-Oriented Software Construction. Prentice Hall, 2nd edition.
[Milanez 2015] Milanez, A. (2015). A Case Study on Classifying Nonconformances in Java/JML Programs.
Technical report, Software Practices Laboratory, Federal University of Campina Grande.
[Milanez 2014] Milanez, A. F. (2014). Enhancing Conformance Checking for Contract-Based Programs. Mas-
ters thesis, Federal University of Campina Grande.
[Pei et al. 2014a] Pei, Y., Furia, C. A., Nordio, M., and Meyer, B. (2014a). Automatic program repair by fixing
contracts. In 17th International Conference on Fundamental Approaches to Software Engineering (FASE),
volume 8174 of Lecture Notes in Computer Science, pages 251268. Springer.
[Pei et al. 2015] Pei, Y., Furia, C. A., Nordio, M., and Meyer, B. (2015). Automated program repair in an inte-
grated development environment. In Proceedings of the 37th International Conference on Software Engineering
(ICSE 2015). IEEE.
[Pei et al. 2014b] Pei, Y., Furia, C. A., Nordio, M., Wei, Y., Meyer, B., and Zeller, A. (2014b). Automated fixing
of programs with contracts. IEEE Transactions on Software Engineering, 40(5):427449.
9 https://goo.gl/9TE8Hw
25
[Pei et al. 2011] Pei, Y., Wei, Y., Furia, C. A., Nordio, M., and Meyer, B. (2011). Code-based automated program
fixing. In 26th IEEE/ACM International Conference on Automated Software Engineering (ASE), pages 392
395. IEEE.
[Poll et al. 2002] Poll, E., Hartel, P., and Jong, E. (2002). A Java Reference Model of Transacted Memory for
Smart Cards. In CARDIS. USENIX Association.
[Rebelo et al. 2009] Rebelo, H., Lima, R., Cornelio, M. L., Leavens, G. T., Mota, A. C., and Oliveira, C. (2009).
Optimizing JML Features Compilation in ajmlc Using Aspect-Oriented Refactorings. In SBLP 09.
[Rodrigues 2009] Rodrigues, R. M. S. (2009). JML-Based Formal Development of a Java Card Application for
Managing Medical Appointments. Masters thesis, Universidade da Madeira.
[Schmitt and Tonin 2007] Schmitt, P. and Tonin, I. (2007). Verifying the Mondex Case Study. In IEEE Interna-
tional Conference on Software Engineering and Formal Methods, pages 4758. IEEE Press.
[Sommerville 2010] Sommerville, I. (2010). Software Engineering. Pearson.
[Wei et al. 2010] Wei, Y., Pei, Y., Furia, C. A., Silva, L. S., Buchholz, S., Meyer, B., and Zeller, A. (2010).
Automated fixing of programs with contracts. In International Symposium on Software Testing and Analysis.
26