Java Java Modeling Language (JML) Arnaud LANOIX Université Nancy 2 Master1 GL Langage de Programmation Orientée Objet développé par Sun Projet OAK (1991), Java (1995),...Java 1.5 (2004) http://java.sun.com/ Langage interprété = la JVM (Java Virtual Machine est multi-plateforme (windows, linux, macosx, etc.) nono@mia : javac Program.java la compilation produit un fichier Program.class (Bytecode) nono@mia : java Fichier exécution / interprétation du Bytecode par la JVM Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 1 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 2 / 52 Java (suite) Qu est-ce que JML? Repose sur les concepts dela programmation Objet : Encapsulation des données : public, private, protected Héritage : Class A extends B {... Polymorphisme notion de classes (Définition du type objets) et d instances de classes (Objets) Personne moi = new Personne("Arnaud", "Lanoix") ; Nombreux cours de Java disponible sur le Web : http://www.loria.fr/~lanoix/loo-java/ Java Modeling Language = langage de modélisation formelle associé au langage de programmation Java Inspiré par Effeil : conception par contrat Auteur de départ : Gary T. Leavens, 1999 Exprime des propriétés sur les classes Java : invariants, pré-/postconditions, etc. Supporté par différents outils : JML Runtime Assertion Checker, JMLUnit, ESC/java2, etc. Site de référence : http://www.jmlspecs.org Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 3 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 4 / 52 Invariants, Pré-/Postconditions Conception par Contrat logique d Hoare : pré/-postconditions des programmes Invariant = propriété toujours vraie quelque soit l état du système Précondition = propriété vraie avant l invocation d une méthode Postcondition = propriété vraie après à la terminaison d une méthode Design by Contract : introduit dans le langage Eiffel Contrat entre le système qui invoque une méthode et la méthode qui est invoquée : invariant : {precondition method() {postcondition L environnement appelant s engage à remplir les préconditions d une méthode lors de l invocation de celle-ci La méthode s engage à établir ses postconditions lorsqu elle est invoquée La méthode et l environnement s engagent également à maintenir l invariant de la classe Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 5 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 6 / 52
Un premier exemple Un premier exemple Sqrt.java /** * @param double x réel positif * @result double racine carrée de x */ @ requires x >= 0.0 ; @ ensures x == \result * \result ; public static double sqrt(double x) { Sqrt.java /** * @param double x réel positif * @result double racine carrée de x */ @ requires x >= 0.0 ; @ ensures x == \result * \result ; public static double sqrt(double x) { Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 8 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 8 / 52 Un premier exemple Un premier exemple Sqrt.java /** * @param double x réel positif * @result double racine carrée de x */ @ requires x >= 0.0 ; @ ensures x == \result * \result ; public static double sqrt(double x) { Sqrt.java /** * @param double x réel positif * @result double racine carrée de x */ @ requires x >= 0.0 ; @ ensures x == \result * \result ; public static double sqrt(double x) { Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 8 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 8 / 52 Un premier exemple (explication) Annotations JML requires x >= 0.0 ; Précondition assurant que le paramètre x est bien un réel positif ensures x == \result * \result ; Postcondition assurant que le résultat \result est bien la racine carrée de x à eps \result : identifie le résultat d une méthode Une spécification JML s exprime par un programme Java annoté : les annotations JML sont écrites au niveau du code Java les annotations JML se placent dans des blocs de commentaires Java spécifiques sur une seule ligne commencant par //@ dans un bloc délimité par les annotations JML sont cohérentes avec la syntaxe Java. un programme Java annoté continue à fonctionner normalement : compilation, exécution, etc. Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 9 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 10 / 52
Clauses de spécification Expression des prédicats JML Une modélisation JML est composée de clauses (des prédicats) décrivant la classe ou les méthodes : Spécifications de types : partie statique du modèle initially predicat JML invariant predicat JML constraints predicat JML Spécifications de méthodes : partie dynamique du modèle requires predicat JML diverges predicat JML assignable predicat JML ensures predicat JML signals predicat JML Les prédicats JML predicat JML sont exprimées à l aide des attributs (variables) et des paramètres des méthodes de la classe java annotée d appel à des méthodes pures des opérateurs du langage Java opérateurs arithmétiques opérateurs booléens d opérateurs spécifiques à JML nouveau opérateurs arithmétiques nouveau opérateurs booléens opérateurs avant/après opérateurs de typage Objet Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 11 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 12 / 52 Méthodes pures Opérateurs arithmétiques Une méthode qui ne modifie aucun attribut est dite pure et peuvent être utilisée dans les prédicats JML. Les prédicats JML ne doivent pas changer l état du système : pas d effet de bord Les méthode de consultation des classes de l API Java sont considérées comme pures On peut déclarer qu une méthode est pure à l aide du modificateur pure : class C { int val ; //@ invariant getval() >= 0 ; //@ ensures \result == val ; public pure */ int getval() {return val ; Opérateurs binaires Symbole Fonction Champ d application + addition entiers ou réels - soustraction entiers ou réels * multiplication entiers ou réels / division réelle réels / division entière entiers % reste de la division entière entiers Opérations généralisées : \sum, \product, \min, \max, \num of Symbole (\sum int x ; x >= 1 & x <= 10 ; x + 3) 1 x 10 Fonction x N x + 3 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 14 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 15 / 52 Opérateurs arithmétiques Opérateurs booléens Opérateurs binaires Symbole Fonction Champ d application + addition entiers ou réels - soustraction entiers ou réels * multiplication entiers ou réels / division réelle réels / division entière entiers % reste de la division entière entiers Opérations généralisées : \sum, \product, \min, \max, \num of Symbole (\sum int x ; x >= 1 & x <= 10 ; x + 3) 1 x 10 Fonction x N x + 3 Opérateurs logiques Symbole Fonction & ET logique OU logique ^ OU logique exclusif! négation logique ==> Implication <==> Equivalence Opérateurs relationnels Symbole Fonction > supérieur >= supérieur ou égal < inférieur <= inférieur ou égal == égal!= différent Quantification universelle Symbole (\forall Type v ; predicat1(v) ; predicat2(v)) Fonction v.(v Type predicat1(v) predicat2(v)) Quantification existentielle Symbole (\exists Type v ; predicat1(v) ; predicat2(v)) Fonction v.(v Type predicat1(v) predicat2(v)) Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 15 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 16 / 52
Opérateurs booléens Opérateurs avant/après Opérateurs logiques Symbole Fonction & ET logique OU logique ^ OU logique exclusif! négation logique ==> Implication <==> Equivalence Opérateurs relationnels Symbole Fonction > supérieur >= supérieur ou égal < inférieur <= inférieur ou égal == égal!= différent Certaines clauses font référence à l état avant et à l état après l exécution d une méthode (prédicat avant-après) \result fait référence au résultat de la méthode (état après) \old(x) permet de faire référence à la valeur de x à l état d avant x représente la valeur de x après l exécution de la méthode Quantification universelle Symbole (\forall Type v ; predicat1(v) ; predicat2(v)) Fonction v.(v Type predicat1(v) predicat2(v)) Quantification existentielle Symbole (\exists Type v ; predicat1(v) ; predicat2(v)) Fonction v.(v Type predicat1(v) predicat2(v)) \not modified(x) est une expression booléenne qui indique que x n a pas été modifié lors de l exécution de la méthode (i) si x est un type simple, x == \old(x) (ii) si x est un objet, x.equals(\old(x)) Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 16 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 17 / 52 Opérateurs de typage Objet Spécifications de types \type(maclasse) retourne le type décrit par la spécification de la classe MaClasse \typeof(monobjet) retourne le type de l objet monobjet < : permet de savoir si un type est un sous-type (héritage) d un autre //@ \typeof(o) < : \type(personne) est vrai si le type de l objet o est un sous-type de la classe Personne, c.a.d. que o est une instance d une sous-classe de Personne Propriétés portant sur les attributs de la classe. Contraintes initiales : clause initially propriété qui doit être établies à la création de l objet Invariant de classe : clause invariant propriété portant sur les attributs de la classe qui doit être vraie dans tous les états visibles du système Etat visible = état atteint après l exécution d une méthode Contraintes historiques : clause constraint propiété entre un état visible et l état visible précédent qui doit être vraie dans tous les états du système = invariant dynamique une clause constraints ne doit pas être vérifiée après un constructeur de classe s exprime grâce à des prédicats avant/après : \old(x) <= x Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 18 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 19 / 52 Spécifications de types Spécifications de types Propriétés portant sur les attributs de la classe. Contraintes initiales : clause initially propriété qui doit être établies à la création de l objet Invariant de classe : clause invariant propriété portant sur les attributs de la classe qui doit être vraie dans tous les états visibles du système Etat visible = état atteint après l exécution d une méthode Contraintes historiques : clause constraint propiété entre un état visible et l état visible précédent qui doit être vraie dans tous les états du système = invariant dynamique une clause constraints ne doit pas être vérifiée après un constructeur de classe s exprime grâce à des prédicats avant/après : \old(x) <= x Propriétés portant sur les attributs de la classe. Contraintes initiales : clause initially propriété qui doit être établies à la création de l objet Invariant de classe : clause invariant propriété portant sur les attributs de la classe qui doit être vraie dans tous les états visibles du système Etat visible = état atteint après l exécution d une méthode Contraintes historiques : clause constraint propiété entre un état visible et l état visible précédent qui doit être vraie dans tous les états du système = invariant dynamique une clause constraints ne doit pas être vérifiée après un constructeur de classe s exprime grâce à des prédicats avant/après : \old(x) <= x Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 19 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 19 / 52
Spécifications de comportements Spécifications de comportements Propriétés relatives aux comportements autorisés des méthodes. Préconditions : clause requires condition qui doit être remplie par le système et les paramètres de la méthode pour que la méthode puisse être appelée Divergence : clause diverges condition sous laquelle la méthode peut ne pas terminer, i.e. boucles infinies, etc. Champs modifiés : clause assignable liste des attributs qui sont modifiés par l exécution de la méthode Postcondition normale : clause ensures condition que la méthode s engage à établir lorsqu elle termine normalement (c.a.d. sans lever d exception). Prédicats avant/après Propriétés relatives aux comportements autorisés des méthodes. Préconditions : clause requires condition qui doit être remplie par le système et les paramètres de la méthode pour que la méthode puisse être appelée Divergence : clause diverges condition sous laquelle la méthode peut ne pas terminer, i.e. boucles infinies, etc. Champs modifiés : clause assignable liste des attributs qui sont modifiés par l exécution de la méthode Postcondition normale : clause ensures condition que la méthode s engage à établir lorsqu elle termine normalement (c.a.d. sans lever d exception). Prédicats avant/après Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 20 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 20 / 52 Spécifications de comportements Spécifications de comportements Propriétés relatives aux comportements autorisés des méthodes. Préconditions : clause requires condition qui doit être remplie par le système et les paramètres de la méthode pour que la méthode puisse être appelée Divergence : clause diverges condition sous laquelle la méthode peut ne pas terminer, i.e. boucles infinies, etc. Champs modifiés : clause assignable liste des attributs qui sont modifiés par l exécution de la méthode Postcondition normale : clause ensures condition que la méthode s engage à établir lorsqu elle termine normalement (c.a.d. sans lever d exception). Prédicats avant/après Propriétés relatives aux comportements autorisés des méthodes. Préconditions : clause requires condition qui doit être remplie par le système et les paramètres de la méthode pour que la méthode puisse être appelée Divergence : clause diverges condition sous laquelle la méthode peut ne pas terminer, i.e. boucles infinies, etc. Champs modifiés : clause assignable liste des attributs qui sont modifiés par l exécution de la méthode Postcondition normale : clause ensures condition que la méthode s engage à établir lorsqu elle termine normalement (c.a.d. sans lever d exception). Prédicats avant/après Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 20 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 20 / 52 Exemple : gestionnaire de cours Exemple : modélisation Objet (exemple vu en B) Une classe Etudiant 2 attributs : nom et prenom 1 constructeur : Etudiant(nom, prenom) etc. Un cours a max des places disponibles. Un étudiant (nom, prénom) peut s inscrire à cours. Seul un étudiant encore jamais inscrit peut s inscrire. Un étudiant inscrit peut passer l examen. S il réussi l examen, il obtient le diplôme ; sinon, il est collé. Un étudiant collé peut repasser une fois l examen avant d être définitivement refusé. 1 méthode : tostring() Une classe Cours 5 attributs : max, inscrits, colles, refuses et diplomes 1 constructeur : Cours(maxi) 5 méthodes : nouvel etudiant(etudiant), test reussi(etudiant), test rate colle(etudiant), test rate refuse(etudiant), tostring() Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 21 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 22 / 52
Exemple : modélisation Objet Une classe Etudiant 2 attributs : nom et prenom 1 constructeur : Etudiant(nom, prenom) 1 méthode : tostring() Une classe Cours 5 attributs : max, inscrits, colles, refuses et diplomes 1 constructeur : Cours(maxi) 5 méthodes : nouvel etudiant(etudiant), test reussi(etudiant), test rate colle(etudiant), test rate refuse(etudiant), tostring() Etudiant.java public class Etudiant { private String nom ; private String prenom ; Etudiant(String nom, String prenom) { this.nom = nom ; this.prenom = prenom ; public String tostring() { return prenom + " " + nom ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 22 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 24 / 52 Etudiant.java (JML) public class Etudiant { private spec public non null */ String nom ; private spec public non null */ String prenom ; Etudiant(String nom, String prenom) { this.nom = nom ; this.prenom = prenom ; public String tostring() { return prenom + " " + nom ; Etudiant.java (JML) public class Etudiant { private spec public non null */ String nom ; private spec public non null */ String prenom ; @ invariant!nom.equals("") &!prenom.equals("") ; Etudiant(String nom, String prenom) { this.nom = nom ; this.prenom = prenom ; public String tostring() { return prenom + " " + nom ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 24 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 24 / 52 Cours.java import java.util.* ; public void nouvel etudiant(etudiant etudiant) { inscrits.add(etudiant) ; public class Cours { private int max ; private HashSet inscrits ; private HashSet colles ; private HashSet refuses ; private HashSet diplomes ; Cours(int maxi) { max = maxi ; inscrits = new HashSet(max) ; colles = new HashSet(max) ; refuses = new HashSet(max) ; diplomes = new HashSet(max) ; public void test rate refuse(etudiant etudiant) { refuses.add(etudiant) ; public String tostring() { Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 26 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 28 / 52
Cours.java (JML) import java.util.* ; public class Cours { private spec public */ int max ; private spec public */ HashSet inscrits ; private spec public */ HashSet colles ; private spec public */ HashSet refuses ; private spec public */ HashSet diplomes ; @ invariant max > 0 ; @ invariant inscrits.size() <= max ; @ invariant (\forall Etudiant e ; colles.contains(e) ; @ inscrits.contains(e)) ; Cours.java (JML) import java.util.* ; public class Cours { private spec public */ int max ; private spec public */ HashSet inscrits ; private spec public */ HashSet colles ; private spec public */ HashSet refuses ; private spec public */ HashSet diplomes ; @ invariant max > 0 ; @ invariant inscrits.size() <= max ; @ invariant (\forall Etudiant e ; colles.contains(e) ; @ inscrits.contains(e)) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 30 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 30 / 52 Cours.java (JML) import java.util.* ; public class Cours { private spec public */ int max ; private spec public */ HashSet inscrits ; private spec public */ HashSet colles ; private spec public */ HashSet refuses ; private spec public */ HashSet diplomes ; @ invariant max > 0 ; @ invariant inscrits.size() <= max ; @ invariant (\forall Etudiant e ; colles.contains(e) ; @ inscrits.contains(e)) ; Cours.java (JML) import java.util.* ; public class Cours { private spec public */ int max ; private spec public */ HashSet inscrits ; private spec public */ HashSet colles ; private spec public */ HashSet refuses ; private spec public */ HashSet diplomes ; @ invariant max > 0 ; @ invariant inscrits.size() <= max ; @ invariant (\forall Etudiant e ; colles.contains(e) ; @ inscrits.contains(e)) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 30 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 30 / 52 Cours.java (JML) import java.util.* ; public class Cours { private spec public */ int max ; private spec public */ HashSet inscrits ; private spec public */ HashSet colles ; private spec public */ HashSet refuses ; private spec public */ HashSet diplomes ; @ invariant max > 0 ; @ invariant inscrits.size() <= max ; @ invariant (\forall Etudiant e ; colles.contains(e) ; @ inscrits.contains(e)) ; @ initially inscrits.isempty() ; @ initially colles.isempty() ; @ initially refuses.isempty() ; @ initially diplomes.isempty() ; @ requires maxi > 0 ; Cours(int maxi) { max = maxi ; inscrits = new HashSet(max) ; colles = new HashSet(max) ; refuses = new HashSet(max) ; diplomes = new HashSet(max) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 30 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 32 / 52
@ initially inscrits.isempty() ; @ initially colles.isempty() ; @ initially refuses.isempty() ; @ initially diplomes.isempty() ; @ requires maxi > 0 ; Cours(int maxi) { max = maxi ; inscrits = new HashSet(max) ; colles = new HashSet(max) ; refuses = new HashSet(max) ; diplomes = new HashSet(max) ; @ initially inscrits.isempty() ; @ initially colles.isempty() ; @ initially refuses.isempty() ; @ initially diplomes.isempty() ; @ requires maxi > 0 ; Cours(int maxi) { max = maxi ; inscrits = new HashSet(max) ; colles = new HashSet(max) ; refuses = new HashSet(max) ; diplomes = new HashSet(max) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 32 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 32 / 52 @ requires!inscrits.contains(etudiant) ; @ requires!diplomes.contains(etudiant) ; @ requires!refuses.contains(etudiant) ; @ requires inscrits.size() < max ; @ ensures inscrits.contains(etudiant) ; public void nouvel etudiant(etudiant etudiant) { inscrits.add(etudiant) ; @ ensures diplomes.contains(etudiant) ; @ requires!inscrits.contains(etudiant) ; @ requires!diplomes.contains(etudiant) ; @ requires!refuses.contains(etudiant) ; @ requires inscrits.size() < max ; @ ensures inscrits.contains(etudiant) ; public void nouvel etudiant(etudiant etudiant) { inscrits.add(etudiant) ; @ ensures diplomes.contains(etudiant) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 34 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 34 / 52 @ requires!inscrits.contains(etudiant) ; @ requires!diplomes.contains(etudiant) ; @ requires!refuses.contains(etudiant) ; @ requires inscrits.size() < max ; @ ensures inscrits.contains(etudiant) ; public void nouvel etudiant(etudiant etudiant) { inscrits.add(etudiant) ; @ ensures diplomes.contains(etudiant) ; @ requires!inscrits.contains(etudiant) ; @ requires!diplomes.contains(etudiant) ; @ requires!refuses.contains(etudiant) ; @ requires inscrits.size() < max ; @ ensures inscrits.contains(etudiant) ; public void nouvel etudiant(etudiant etudiant) { inscrits.add(etudiant) ; @ ensures diplomes.contains(etudiant) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 34 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 34 / 52
@ requires!inscrits.contains(etudiant) ; @ requires!diplomes.contains(etudiant) ; @ requires!refuses.contains(etudiant) ; @ requires inscrits.size() < max ; @ ensures inscrits.contains(etudiant) ; public void nouvel etudiant(etudiant etudiant) { inscrits.add(etudiant) ; @ ensures diplomes.contains(etudiant) ; @ requires!inscrits.contains(etudiant) ; @ requires!diplomes.contains(etudiant) ; @ requires!refuses.contains(etudiant) ; @ requires inscrits.size() < max ; @ ensures inscrits.contains(etudiant) ; public void nouvel etudiant(etudiant etudiant) { inscrits.add(etudiant) ; @ ensures diplomes.contains(etudiant) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 34 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 34 / 52 @ requires!colles.contains(etudiant) ; @ ensures colles.contains(etudiant) ; @ requires colles.contains(etudiant) ; @ ensures!colles.contains(etudiant) ; @ ensures refuses.contains(etudiant) ; public void test rate refuse(etudiant etudiant) { refuses.add(etudiant) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 36 / 52 @ requires!colles.contains(etudiant) ; @ ensures colles.contains(etudiant) ; @ requires colles.contains(etudiant) ; @ ensures!colles.contains(etudiant) ; @ ensures refuses.contains(etudiant) ; public void test rate refuse(etudiant etudiant) { refuses.add(etudiant) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 36 / 52 @ requires!colles.contains(etudiant) ; @ ensures colles.contains(etudiant) ; @ requires colles.contains(etudiant) ; @ ensures!colles.contains(etudiant) ; @ ensures refuses.contains(etudiant) ; public void test rate refuse(etudiant etudiant) { refuses.add(etudiant) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 36 / 52 @ requires!colles.contains(etudiant) ; @ ensures colles.contains(etudiant) ; @ requires colles.contains(etudiant) ; @ ensures!colles.contains(etudiant) ; @ ensures refuses.contains(etudiant) ; public void test rate refuse(etudiant etudiant) { refuses.add(etudiant) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 36 / 52
@ requires!colles.contains(etudiant) ; @ ensures colles.contains(etudiant) ; @ requires colles.contains(etudiant) ; @ ensures!colles.contains(etudiant) ; @ ensures refuses.contains(etudiant) ; public void test rate refuse(etudiant etudiant) { refuses.add(etudiant) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 36 / 52 @ requires!colles.contains(etudiant) ; @ ensures colles.contains(etudiant) ; @ requires colles.contains(etudiant) ; @ ensures!colles.contains(etudiant) ; @ ensures refuses.contains(etudiant) ; public void test rate refuse(etudiant etudiant) { refuses.add(etudiant) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 36 / 52 JML Runtime Assertion Checker (RAC) public String tostring() { return "Inscrits = " + inscrits + ", Diplomes = " + diplomes + ", Colles = " + colles + ", Refuses = " + refuses ; Outil de base de JML qui compile un code Java enrichi pour la vérification des différentes annotations JML introduites (ligne de commande) jml : type-checker pour les assertions JML jmlc : compilateur JML/Java bytecode Java enrichi par les assertions JML jmlrac : exécuteur Java peut soulève des exceptions spécifiques aux différentes clauses JML Outils disponibles dans le package JMLSpecs ici : http://www.jmlspecs.org Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 38 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 39 / 52 Exceptions RAC Méthode test rate colle annotée JMLAssertionError JMLPreconditionError JMLEntryPreconditionError JMLInternalPreconditionError JMLPostconditionError JMLNormalPostconditionError JMLInternalNormalPostconditionError JMLExitNormalPostconditionError JMLExceptionalPostconditionError JMLInternalExceptionalPostconditionError JMLExitExceptionalPostconditionError JMLInvariantError JMLHistoryConstraintsError JMLEvaluationError @ requires!colles.contains(etudiant) ; @ ensures colles.contains(etudiant) ; Les assertions invariant, requires, ensures,...vont être transformées en test et en levée d exceptions Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 40 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 42 / 52
Méthode test rate colle : principe du RAC Méthode test rate colle : principe du RAC throws JMLAssertionError { if (!(inscrits.contains(etudiant) /* requires */ &!colles.contains(etudiant))) { throw new JMLExitPreconditionError() ; if (!colles.contains(etudiant)) { /* ensures */ throw New JMLExitNormalPostconditionError() ; throws JMLAssertionError { if (!(inscrits.contains(etudiant) /* requires */ &!colles.contains(etudiant))) { throw new JMLExitPreconditionError() ; if (!colles.contains(etudiant)) { /* ensures */ throw New JMLExitNormalPostconditionError() ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 44 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 44 / 52 Méthode test rate colle : principe du RAC Méthode test rate colle : principe du RAC throws JMLAssertionError { if (!(inscrits.contains(etudiant) /* requires */ &!colles.contains(etudiant))) { throw new JMLExitPreconditionError() ; if (!colles.contains(etudiant)) { /* ensures */ throw New JMLExitNormalPostconditionError() ; throws JMLAssertionError { if (!(inscrits.contains(etudiant) /* requires */ &!colles.contains(etudiant))) { throw new JMLExitPreconditionError() ; if (!colles.contains(etudiant)) { /* ensures */ throw New JMLExitNormalPostconditionError() ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 44 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 44 / 52 Méthode test rate colle : principe du RAC Méthode test rate colle : principe du RAC throws JMLAssertionError { if (!(inscrits.contains(etudiant) /* requires */ &!colles.contains(etudiant))) { throw new JMLExitPreconditionError() ; if (!colles.contains(etudiant)) { /* ensures */ throw New JMLExitNormalPostconditionError() ; public void test rate colle(etudiant etudiant) throws JMLAssertionError { if (!(inscrits.contains(etudiant) /* requires */ &!colles.contains(etudiant))) { throw new JMLExitPreconditionError() ; if (!colles.contains(etudiant)) { /* ensures */ throw New JMLExitNormalPostconditionError() ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 44 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 44 / 52
Méthode test rate colle : principe du RAC public void test rate colle(etudiant etudiant) throws JMLAssertionError { if (!(inscrits.contains(etudiant) /* requires */ &!colles.contains(etudiant))) { throw new JMLExitPreconditionError() ; if (!colles.contains(etudiant)) { /* ensures */ throw New JMLExitNormalPostconditionError() ; Exemple : Main.java public class Main { public static void main(string args[]) { Cours GL = new Cours(3) ; Etudiant pascal = new Etudiant("Fontaine", "Pascal") ; Etudiant nono = new Etudiant("Lanoix", "Arnaud") ; Etudiant john = new Etudiant("Doe", "John") ; Etudiant totoro = new Etudiant("", "Totoro") ; Etudiant tao = new Etudiant("Kawai", "Tao") ; Etudiant tolkien = new Etudiant("Tolkien", "J.R.R") ; GL.nouvel etudiant(pascal) ; GL.nouvel etudiant(nono) ; GL.nouvel etudiant(john) ; GL.nouvel etudiant(tolkien) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 44 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 46 / 52 Exemple : Main.java public class Main { public static void main(string args[]) { Cours GL = new Cours(3) ; Etudiant pascal = new Etudiant("Fontaine", "Pascal") ; Etudiant nono = new Etudiant("Lanoix", "Arnaud") ; Etudiant john = new Etudiant("Doe", "John") ; Etudiant totoro = new Etudiant("", "Totoro") ; Etudiant tao = new Etudiant("Kawai", "Tao") ; Etudiant tolkien = new Etudiant("Tolkien", "J.R.R") ; GL.nouvel etudiant(pascal) ; GL.nouvel etudiant(nono) ; GL.nouvel etudiant(john) ; GL.nouvel etudiant(tolkien) ; Exemple : Main.java public class Main { public static void main(string args[]) { Cours GL = new Cours(3) ; Etudiant pascal = new Etudiant("Fontaine", "Pascal") ; Etudiant nono = new Etudiant("Lanoix", "Arnaud") ; Etudiant john = new Etudiant("Doe", "John") ; Etudiant totoro = new Etudiant("", "Totoro") ; Etudiant tao = new Etudiant("Kawai", "Tao") ; Etudiant tolkien = new Etudiant("Tolkien", "J.R.R") ; GL.nouvel etudiant(pascal) ; GL.nouvel etudiant(nono) ; GL.nouvel etudiant(john) ; GL.nouvel etudiant(tolkien) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 46 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 46 / 52 Exemple : Main.java public class Main { public static void main(string args[]) { Cours GL = new Cours(3) ; Etudiant pascal = new Etudiant("Fontaine", "Pascal") ; Etudiant nono = new Etudiant("Lanoix", "Arnaud") ; Etudiant john = new Etudiant("Doe", "John") ; Etudiant totoro = new Etudiant("", "Totoro") ; Etudiant tao = new Etudiant("Kawai", "Tao") ; Etudiant tolkien = new Etudiant("Tolkien", "J.R.R") ; GL.nouvel etudiant(pascal) ; GL.nouvel etudiant(nono) ; GL.nouvel etudiant(john) ; GL.nouvel etudiant(tolkien) ; System.out.println("*** Before : " + GL) ; GL.test rate refuse(pascal) ; GL.test reussi(nono) ; GL.test rate colle(pascal) ; GL.test rate colle(john) ; GL.test reussi(tao) ; GL.test rate colle(tolkien) ; GL.test rate refuse(john) ; GL.nouvel etudiant(john) ; GL.test reussi(nono) ; GL.test rate colle(pascal) ; GL.test reussi(tolkien) ; GL.test rate refuse(pascal) ; System.out.println("*** After : " + GL) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 46 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 48 / 52
System.out.println("*** Before : " + GL) ; GL.test rate refuse(pascal) ; GL.test reussi(nono) ; GL.test rate colle(pascal) ; GL.test rate colle(john) ; GL.test reussi(tao) ; GL.test rate colle(tolkien) ; GL.test rate refuse(john) ; GL.nouvel etudiant(john) ; GL.test reussi(nono) ; GL.test rate colle(pascal) ; GL.test reussi(tolkien) ; GL.test rate refuse(pascal) ; System.out.println("*** After : " + GL) ; System.out.println("*** Before : " + GL) ; GL.test rate refuse(pascal) ; GL.test reussi(nono) ; GL.test rate colle(pascal) ; GL.test rate colle(john) ; GL.test reussi(tao) ; GL.test rate colle(tolkien) ; GL.test rate refuse(john) ; GL.nouvel etudiant(john) ; GL.test reussi(nono) ; GL.test rate colle(pascal) ; GL.test reussi(tolkien) ; GL.test rate refuse(pascal) ; System.out.println("*** After : " + GL) ; Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 48 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 48 / 52 Exemple : compilation / exécution Java Exemple : compilation / exécution Java nono@mia : javac *.java nono@mia : javac *.java nono@mia : java Main nono@mia : java Main *** Before : Inscrits = [Pascal Fontaine, Arnaud Lanoix, John Doe, Tao Kawai, J.R.R Tolkien], Diplomes = [], Colles = [], Refuses = [] *** After : Inscrits = [John Doe], Diplomes = [Arnaud Lanoix, Tao Kawai, J.R.R Tolkien], Colles = [J.R.R Tolkien], Refuses = [John Doe, Pascal Fontaine] *** Before : Inscrits = [Pascal Fontaine, Arnaud Lanoix, John Doe, Tao Kawai, J.R.R Tolkien], Diplomes = [], Colles = [], Refuses = [] *** After : Inscrits = [John Doe], Diplomes = [Arnaud Lanoix, Tao Kawai, J.R.R Tolkien], Colles = [J.R.R Tolkien], Refuses = [John Doe, Pascal Fontaine] Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 49 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 49 / 52 Exemple : compilation / exécution Java Exemple : compilation / exécution JML RAC nono@mia : javac *.java nono@mia : java Main *** Before : Inscrits = [Pascal Fontaine, Arnaud Lanoix, John Doe, Tao Kawai, J.R.R Tolkien], Diplomes = [], Colles = [], Refuses = [] *** After : Inscrits = [John Doe], Diplomes = [Arnaud Lanoix, Tao Kawai, J.R.R Tolkien], Colles = [J.R.R Tolkien], Refuses = [John Doe, Pascal Fontaine] nono@mia : jmlc *.java typechecking Cours.java typechecking Etudiant.java typechecking Main.java nono@mia : jmlrac Main Exception in thread "main" org.jmlspecs.jmlrac.runtime.jmlinvarianterror : by method Etudiant.<init>post<File "Etudiant.java", line 9, character 13> regarding specifications at File "Etudiant.java", line 6, character 34 when Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 49 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 50 / 52
Exemple : compilation / exécution JML RAC Exemple : compilation / exécution JML RAC nono@mia : jmlc *.java typechecking Cours.java typechecking Etudiant.java typechecking Main.java nono@mia : jmlrac Main Exception in thread "main" org.jmlspecs.jmlrac.runtime.jmlinvarianterror : by method Etudiant.<init>post<File "Etudiant.java", line 9, character 13> regarding specifications at File "Etudiant.java", line 6, character 34 when nono@mia : jmlc *.java typechecking Cours.java typechecking Etudiant.java typechecking Main.java nono@mia : jmlrac Main Exception in thread "main" org.jmlspecs.jmlrac.runtime.jmlinvarianterror : by method Etudiant.<init>post<File "Etudiant.java", line 9, character 13> regarding specifications at File "Etudiant.java", line 6, character 34 when Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 50 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 50 / 52 Exemple : compilation / exécution JML RAC Exemple : méthode test reussi corrigée nono@mia : jmlc *.java typechecking Cours.java typechecking Etudiant.java typechecking Main.java nono@mia : jmlrac Main Exception in thread "main" org.jmlspecs.jmlrac.runtime.jmlinvarianterror : by method Etudiant.<init>post<File "Etudiant.java", line 9, character 13> regarding specifications at File "Etudiant.java", line 6, character 34 when @ ensures diplomes.contains(etudiant) ; if(colles.contains(etudiant)) { Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 50 / 52 Arnaud LANOIX (Université Nancy 2) Java Modeling Language (JML) Master1 GL 52 / 52