Contracts in the Wild: A Study of Java Programs

The use of formal contracts has long been advocated as an approach to develop programs that are provably correct. However, the reality is that adoption of contracts has been slow in practice. Despite this, the adoption of lightweight contracts — typically utilising runtime checking — has progressed. In the case of Java, built-in features of the language (e.g. assertions and exceptions) can be used for this. Furthermore, a number of libraries which facilitate contract checking have arisen. In this paper, we catalogue 25 techniques and tools for lightweight contract checking in Java, and present the results of an empirical study looking at a dataset extracted from the 200 most popular projects found on Maven Central, constituting roughly 351,034 KLOC. We examine (1) the extent to which contracts are used and (2) what kind of contracts are used. We then investigate how contracts are used to safeguard code, and study problems in the context of two types of substitutability that can be guarded by contracts: (3) unsafe evolution of APIs that may break client programs and (4) violations of Liskovs Substitution Principle (LSP) when methods are overridden. We find that: (1) a wide range of techniques and constructs are used to represent contracts, and often the same program uses different techniques at the same time; (2) overall, contracts are used less than expected, with significant differences between programs; (3) projects that use contracts continue to do so, and expand the use of contracts as they grow and evolve; and, (4) there are cases where the use of contracts points to unsafe subtyping (violations of Liskov's Substitution Principle) and unsafe evolution.

[1]  Markus Lumpe,et al.  On the Application of Inequality Indices in Comparative Software Analysis , 2013, 2013 22nd Australian Software Engineering Conference.

[2]  Jens Dietrich,et al.  Components, Contracts and Vocabularies - Making Dynamic Component Assemblies more Predictable , 2009, J. Object Technol..

[3]  Michael D. Ernst,et al.  Case studies and tools for contract specifications , 2014, ICSE.

[4]  David R. Cok,et al.  OpenJML: JML for Java 7 by Extending OpenJDK , 2011, NASA Formal Methods.

[5]  Matthew J. Rutherford,et al.  An Empirical Evaluation of Assertions as Oracles , 2011, 2011 Fourth IEEE International Conference on Software Testing, Verification and Validation.

[6]  David S. Rosenblum A Practical Approach to Programming With Assertions , 1995, IEEE Trans. Software Eng..

[7]  David R. Cok,et al.  OpenJML: Software verification for Java 7 using JML, OpenJDK, and Eclipse , 2014, F-IDE.

[8]  Peter C. Chapin,et al.  A SPARK/Ada CubeSat Control Program , 2013, Ada-Europe.

[9]  Frantisek Plasil,et al.  Behavior Protocols for Software Components , 2002, IEEE Trans. Software Eng..

[10]  K. Rustan M. Leino,et al.  Dafny: An Automatic Program Verifier for Functional Correctness , 2010, LPAR.

[11]  Michael D. Ernst,et al.  An overview of JML tools and applications , 2003, Electron. Notes Theor. Comput. Sci..

[12]  Jing Li,et al.  The Qualitas Corpus: A Curated Collection of Java Code for Empirical Studies , 2010, 2010 Asia Pacific Software Engineering Conference.

[13]  Cliff B. Jones,et al.  Rigorous Development of Complex Fault-Tolerant Systems [FP6 IST-511599 RODIN project] , 2006, RODIN Book.

[14]  K. Rustan M. Leino Developing verified programs with Dafny , 2012 .

[15]  Jean-Marc Jézéquel,et al.  Making Components Contract Aware , 1999, Computer.

[16]  Manuel Fähndrich,et al.  Embedded contract languages , 2010, SAC '10.

[17]  C. A. R. Hoare Assertions: A Personal Perspective , 2002, Software Pioneers.

[18]  Lindsay Groves,et al.  Designing a verifying compiler: Lessons learned from developing Whiley , 2015, Sci. Comput. Program..

[19]  Frank Piessens,et al.  A Quick Tour of the VeriFast Program Verifier , 2010, APLAS.

[20]  John Barnes,et al.  High Integrity Ada: The Spark Approach , 1997 .

[21]  Robert W. Floyd,et al.  Assigning meaning to programs , 1967 .

[22]  Patrice Chalin,et al.  JML Runtime Assertion Checking: Improved Error Reporting and Efficiency Using Strong Validity , 2008, FM.

[23]  Lionel C. Briand,et al.  On the Effectiveness of Contracts as Test Oracles in the Detection and Diagnosis of Functional Faults in Concurrent Object-Oriented Software , 2014, IEEE Transactions on Software Engineering.

[24]  John L. Bruno,et al.  jContractor: A Reflective Java Library to Support Design by Contract , 1999, Reflection.

[25]  David R. Cok,et al.  ESC/Java2: Uniting ESC/Java and JML , 2004, CASSIS.

[26]  Jonathan P. Bowen,et al.  Ten Commandments of Formal Methods ...Ten Years Later , 2006, Computer.

[27]  Nikolai Kosmatov,et al.  Frama-C: A software analysis perspective , 2015, Formal Aspects of Computing.

[28]  Lindsay Groves,et al.  Whiley: A Platform for Research in Software Verification , 2013, SLE.

[29]  Richard C. Holt,et al.  The Turing Programming Language: Design and Definition , 1987 .

[30]  Gary T. Leavens,et al.  How the design of JML accommodates both runtime assertion checking and formal verification , 2003, Sci. Comput. Program..

[31]  K. Rustan M. Leino,et al.  Extended static checking , 1998, PROCOMET.

[32]  Jean-Christophe Filliâtre,et al.  Why3 - Where Programs Meet Provers , 2013, ESOP.

[33]  P. Naur Proof of algorithms by general snapshots , 1966 .

[34]  L. Peter Deutsch An interactive program verifier , 1973 .

[35]  César A. Muñoz,et al.  Verification of Numerical Programs: From Real Numbers to Floating Point Numbers , 2013, NASA Formal Methods.

[36]  Kent Beck,et al.  Contributing to Eclipse - principles, patterns, and plug-ins , 2003, The Eclipse series.

[37]  Amer Diwan,et al.  The DaCapo benchmarks: java benchmarking development and analysis , 2006, OOPSLA '06.

[38]  K. Rustan M. Leino,et al.  Verification of Object-Oriented Programs with Invariants , 2003, J. Object Technol..

[39]  K. Rustan M. Leino,et al.  Specification and verification , 2011, Commun. ACM.

[40]  Premkumar T. Devanbu,et al.  Assert Use in GitHub Projects , 2015, 2015 IEEE/ACM 37th IEEE International Conference on Software Engineering.

[41]  Shinichi Shiraishi,et al.  Arguing Software Compliance with ISO 26262 , 2014, 2014 IEEE International Symposium on Software Reliability Engineering Workshops.

[42]  Frank Piessens,et al.  VeriFast: A Powerful, Sound, Predictable, Fast Verifier for C and Java , 2011, NASA Formal Methods.

[43]  James C. King,et al.  A Program Verifier , 1971, IFIP Congress.

[44]  Premek Brada,et al.  Automated Versioning in OSGi: A Mechanism for Component Software Consistency Guarantee , 2009, 2009 35th Euromicro Conference on Software Engineering and Advanced Applications.

[45]  Nikolaj Bjørner,et al.  Z3: An Efficient SMT Solver , 2008, TACAS.

[46]  Steven M. German,et al.  Stanford Pascal Verifier user manual , 1979 .

[47]  Yannick Moy,et al.  Rail, Space, Security: Three Case Studies for SPARK 2014 , 2014 .

[48]  Stephen McCamant,et al.  The Daikon system for dynamic detection of likely invariants , 2007, Sci. Comput. Program..

[49]  Bertrand Meyer,et al.  How Specifications Change and Why You Should Care , 2012, ArXiv.

[50]  Michael D. Ernst,et al.  Practical pluggable types for java , 2008, ISSTA '08.

[51]  Gary T. Leavens,et al.  Static verification of ptolemyrely programs using openJML , 2014, FOAL.

[52]  Dan Grossman,et al.  How programming languages will co-evolve with software engineering: a bright decade ahead , 2014, FOSE.

[53]  Bertrand Meyer,et al.  Contracts in Practice , 2012, FM.

[54]  Jonathan P. Bowen,et al.  Ten Commandments of Formal Methods , 1995, Computer.

[55]  Arie van Deursen,et al.  Semantic Versioning versus Breaking Changes: A Study of the Maven Repository , 2014, 2014 IEEE 14th International Working Conference on Source Code Analysis and Manipulation.

[56]  Greg Nelson,et al.  Extended static checking for Java , 2002, PLDI '02.

[57]  Roderick Chapman,et al.  Are We There Yet? 20 Years of Industrial Theorem Proving with SPARK , 2014, ITP.

[58]  C. A. R. Hoare,et al.  The verifying compiler: A grand challenge for computing research , 2003, JACM.

[59]  Bertrand Meyer,et al.  Applying 'design by contract' , 1992, Computer.

[60]  Heike Wehrheim,et al.  Jass - Java with Assertions , 2001, RV@CAV.

[61]  Jens Dietrich,et al.  Component Contracts in Eclipse - A Case Study , 2010, CBSE.

[62]  Thierry Coupaye,et al.  The FRACTAL component model and its support in Java , 2006, Softw. Pract. Exp..

[63]  Gary T. Leavens,et al.  A Simple and Practical Approach to Unit Testing: The JML and JUnit Way , 2002, ECOOP.

[64]  Bertrand Meyer,et al.  Finding Implicit Contracts in .NET Components , 2002, FMCO.

[65]  Néstor Cataño,et al.  Formal Specification and Static Checking of Gemplus' Electronic Purse Using ESC/Java , 2002, FME.

[66]  Jeffrey M. Voas,et al.  Putting assertions in their place , 1994, Proceedings of 1994 IEEE International Symposium on Software Reliability Engineering.

[67]  Gary T. Leavens,et al.  Beyond Assertions: Advanced Specification and Verification with JML and ESC/Java2 , 2005, FMCO.

[68]  Bertrand Meyer,et al.  What good are strong specifications? , 2012, 2013 35th International Conference on Software Engineering (ICSE).

[69]  David S. Rosenblum,et al.  A historical perspective on runtime assertion checking in software development , 2006, SOEN.

[70]  Lauretta O. Osho,et al.  Axiomatic Basis for Computer Programming , 2013 .

[71]  Bertrand Meyer,et al.  Eiffel: A language and environment for software engineering , 1988, J. Syst. Softw..

[72]  Gregor Kiczales,et al.  Aspect-oriented programming , 2001, ESEC/FSE-9.

[73]  Jens Dietrich,et al.  Broken promises: An empirical study into evolution problems in Java programs caused by library upgrades , 2014, 2014 Software Evolution Week - IEEE Conference on Software Maintenance, Reengineering, and Reverse Engineering (CSMR-WCRE).

[74]  Donald I. Good,et al.  Mechanical proofs about computer programs , 1984, Philosophical Transactions of the Royal Society of London. Series A, Mathematical and Physical Sciences.