Académique Documents
Professionnel Documents
Culture Documents
R. Grin
Fiabilit
R. Grin
Fiabilit
Fiabilit en Java
exceptions,
assertions et
journalisation
tudis dans cette
partie du cours
les dbuggeurs
les outils de tests dunits (comme JUnit) ou de
tests fonctionnels
R. Grin
Fiabilit
Les exceptions
R. Grin
Fiabilit
Erreurs/exceptions
On utilise les erreurs/exceptions pour traiter un
fonctionnement anormal dune partie dun code
(provoqu par une erreur ou un cas exceptionnel)
En Java, une erreur ne provoque pas larrt
brutal du programme mais la cration dun objet,
instance dune classe spcifiquement cre pour
tre associe des erreurs/exceptions
R. Grin
Fiabilit
R. Grin
Fiabilit
R. Grin
Fiabilit
Bloc try-catch
try {
Remarque : ne compile
pas si aucune instruction
. . .
du bloc try ne lance
. . .
de TrucException
}
catch(TrucException e) {
// Traitement de lexception e
. . .
}
catch(MachinException e) {
. . .
}
R. Grin
Fiabilit
Multi-catch
}
catch(Type1Exception |
Type2Exception |
Type3Exception e) {
...
}
R. Grin
Fiabilit
10
Vocabulaire (1)
R. Grin
Fiabilit
11
Vocabulaire (2)
R. Grin
Fiabilit
12
Mcanisme de traitement
des exceptions
R. Grin
Fiabilit
13
Exception leve
en dehors dun bloc try
1. La mthode retourne immdiatement ;
lexception remonte vers la mthode appelante
2. La main est donne la mthode appelante
3. Lexception peut alors ventuellement tre
attrape et traite par cette mthode appelante
ou par une des mthodes actuellement dans la
pile dexcution
R. Grin
Fiabilit
14
R. Grin
Fiabilit
15
R. Grin
Fiabilit
16
R. Grin
Fiabilit
17
R. Grin
Fiabilit
18
Exemples de traitements
dans un bloc catch
Fixer le problme et ressayer le traitement qui
a provoqu le passage au bloc catch
Faire un traitement alternatif
Retourner (return) une valeur particulire
Sortir de lapplication avec System.exit
Faire un traitement partiel du problme et
relancer (throw) la mme exception (ou une
autre exception)
R. Grin
Fiabilit
19
R. Grin
Fiabilit
20
R. Grin
Fiabilit
21
Fiabilit
22
Dclaration incorrecte
try {
int n;
n = ParseInt(args[0]);
etagere.add(livres[n]);
}
catch(NumberFormatException e) {
// Erreur
System.err.println("Mauvais emplacement " + n);
return;
}
catch {EtagerePleineException e) {
System.err.println("Etagere pleine");
return;
}
n++; // provoque une erreur la compilation
R. Grin
Fiabilit
23
Dclaration correcte
int n=0;// dclaration/initialisation hors du bloc try
try {
n = ParseInt(args[0]);
etagere.add(livres[n]);
}
catch(NumberFormatException e) {
System.err.println("Mauvais emplacement " + n);
return;
}
catch {EtagerePleineException e) {
System.err.println("Etagere pleine");
return;
}
n++; // pas derreur la compilation
R. Grin
Fiabilit
24
R. Grin
Fiabilit
25
Clause finally
R. Grin
Fiabilit
26
Clause finally
R. Grin
27
Fiabilit
28
Fiabilit
29
R. Grin
Fiabilit
30
R. Grin
Fiabilit
31
R. Grin
Fiabilit
32
R. Grin
Fiabilit
33
Fiabilit
34
Fiabilit
35
Avantages
Les ressources sont fermes la sortie du bloc
try, quoi quil arrive (comme avant)
Le code est bien plus lisible (surtout si
plusieurs ressources doivent tre fermes)
Aucune exception nest perdue (voir
transparents suivants)
R. Grin
Fiabilit
36
R. Grin
Fiabilit
37
R. Grin
Fiabilit
38
Exception perdue
Avec un try normal (sans gestion
automatique des ressources) une exception
lance dans le bloc try peut tre perdue si la
fermeture des ressources lance une autre
exception car le bloc finally lemporte
Ce comportement peut nuire la mise au point
R. Grin
Fiabilit
39
Throwable
R. Grin
Fiabilit
40
Exemple
try {
copierFichiers(in, out);
} catch(CopieException e) {
e.printStackTrace();
}
Fiabilit
41
Interface
java.lang.AutoCloseable
Les classes des ressources qui peuvent tre
gres par un try avec ressources doivent
implmenter cette interface
Contient la mthode void close()
Les connexions JDBC limplmentent, mais
pas les classes de JPA
Les classes utilises pour faire des entressorties implmentent java.io.Closeable qui
hrite de AutoCloseable
R. Grin
Fiabilit
42
R. Grin
Fiabilit
43
R. Grin
Fiabilit
44
Error
Exception
R. Grin
Fiabilit
Exceptions dfinies
par le programmeur
45
Throwable
Error
Exception
R. Grin
Fiabilit
Exceptions dfinies
par le programmeur
46
Throwable
Error
Exception
R. Grin
Fiabilit
Exceptions dfinies
par le programmeur
47
Error
Exception
RuntimeException
Exceptions contrles
Exceptions prdfinies
dans les paquetages JDK
R. Grin
Exceptions contrles
par le compilateur
Fiabilit
Exceptions dfinies
par le programmeur
48
Quelques sous-classes de
RuntimeException
NullPointerException
IndexOutOfBoundsException et sa sous-classe
ArrayIndexOutOfBoundsException
ArithmeticException
IllegalArgumentException et sa sous-classe
NumberFormatException
ClassCastException
NoSuchElementException
R. Grin
Fiabilit
49
Runtime
Exception
ClassNotFound
Exception
IOException
FileNotFoundException
EOFException
R. Grin
Interrupted
Exception
Fiabilit
50
Fiabilit
51
R. Grin
Fiabilit
52
R. Grin
Fiabilit
53
R. Grin
Fiabilit
54
R. Grin
Fiabilit
55
R. Grin
Fiabilit
56
R. Grin
Fiabilit
57
catch(IOException e) { . . .}
Fiabilit
58
R. Grin
Fiabilit
59
Exemple
Si un fichier est lu du dbut la fin, ne pas
utiliser EOFException pour reprer la fin du
fichier ; utiliser plutt la valeur spciale
renvoye par la mthode de lecture quand elle
rencontre la fin du fichier
Mais si on rencontre la fin du fichier avant
davoir lu les 10 valeurs dont on a besoin,
utiliser EOFException
R. Grin
Fiabilit
60
Exceptions et performances
Si aucune exception nest leve, limpact sur
les performances dun bloc try-catch est
ngligeable
La leve dune exception peut au contraire
avoir un impact non ngligeable sur les
performances
Une autre bonne raison de ne pas utiliser les
exceptions pour les cas normaux
R. Grin
Fiabilit
61
R. Grin
Fiabilit
62
Chanage de Throwable
Le JDK 1.4 a ajout des constructeurs la classe
Throwable qui prennent un Throwable en
paramtre, ce qui permet le chanage
dexceptions (tudi plus loin)
Les classes dexception des API auront aussi le
plus souvent des constructeurs qui permettent le
chanage dexception de plus bas niveau
Par exemple pour lier une FactureException
la IOException qui en est la cause premire
R. Grin
Fiabilit
63
Fiabilit
64
Variante de printStackTrace
La variante sans paramtre affiche la pile sur le
fichier des erreurs standard (lcran par dfaut)
Une variante prend un paramtre de type
PrintWriter pour choisir un autre flot de
sortie
Si on choisit un flot StringWriter dcor par
un PrintWriter, on peut ainsi enregistrer la
pile dans une chane de caractres pour, par
exemple, la passer un logger (notion tudie
Fiabilit
65
Exemple
catch (TrucException e ) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
pw.flush();
logger.info(sw.toString());
logger.warning("Problme : ... ");
}
R. Grin
Fiabilit
66
R. Grin
Fiabilit
67
R. Grin
Fiabilit
68
dune instance
R. Grin
Exceptions
69
R. Grin
Fiabilit
70
R. Grin
Fiabilit
71
Exemple
Lexception
contient une
public class EtagerePleineException
rfrence
extends Exception {
ltagre pleine
private Etagere etagere;
public EtagerePleineException(Etagere etagere)
{
super("Etagre pleine");
this.etagere = etagere;
}
. . .
public Etagere getEtagere() {
return etagere;
}
Noubliez pas dajouter au moins
}
le constructeur sans paramtre et
celui qui prend
R. Grin
Fiabilit un message en paramtre
72
Fiabilit
73
Fiabilit
74
Fiabilit
75
R. Grin
Fiabilit
76
Exceptions et redfinition
Soit une mthode m() de B qui redfinit une
mthode dune classe mre A
m() ne peut pas dclarer renvoyer (throws)
plus dexceptions contrles que m() de A ;
elle peut renvoyer
les mmes exceptions
des sous-classes de ces exceptions
moins dexceptions
aucune exception
R. Grin
Exceptions
77
Exceptions et redfinition
R. Grin
Fiabilit
78
Exceptions et constructeurs
R. Grin
Fiabilit
79
R. Grin
Fiabilit
80
Exemple de chanage
try {
. . .
}
catch(IOException e) {
throw new FactureException(.., e);
}
R. Grin
Fiabilit
81
HautNiveauException(String message,
Throwable cause) {
super(message, cause);
Appel du constructeur
}
de la classe
Exception
R. Grin
Fiabilit
82
R. Grin
Fiabilit
83
R. Grin
Fiabilit
84
R. Grin
Fiabilit
85
R. Grin
Fiabilit
86
Error
Les Error sont rserves aux erreurs qui
surviennent dans le fonctionnement de la JVM
Par exemple, un problme de mmoire
OutOfMemoryError, une mthode qui nest
pas trouve NoSuchMethodError
Elles ne devraient jamais arriver
Elles ne devraient jamais tre lances par le
code crit par le dveloppeur
R. Grin
Fiabilit
87
RuntimeException
Cest le bon choix si le problme ne pourra tre
rsolu (en attrapant lexception) par une des
mthodes appelantes (dans la pile dexcution)
Inutile dalourdir le code des mthodes
appelantes en les forant attraper une
exception (ou ajouter une clause throws) si
on sait quelles ne pourront rsoudre le
problme
R. Grin
Fiabilit
88
RuntimeException
R. Grin
Fiabilit
89
RuntimeException
Convient aussi si le problme est d une
mauvaise utilisation de la mthode
Exemple : passage dun paramtre invalide
IllegalArgumentException
R. Grin
Fiabilit
90
R. Grin
Fiabilit
91
Exceptions contrles
Pour les cas peu frquents mais, au contraire
des exceptions non contrles, pas inattendus
Elles correspondent des scnarios envisags
par le dveloppeur et participent donc la
logique de lapplication
Elles sont rserves aux problmes qui
pourront tre rsolus (au moins partiellement)
par une des mthodes de la pile dexcution
Par exemple, si une tagre est pleine, le code
qui a voulu ajouter un livre pourra choisir une
autre tagre
R. Grin
Fiabilit
92
R. Grin
Fiabilit
93
R. Grin
Fiabilit
94
Exceptions du JDK
ou nouveau type dexception ?
Si une exception du JDK convient, il vaut mieux
lutiliser car ces exceptions sont bien connues
des dveloppeurs
Sinon, ne pas hsiter crer un nouveau type
dexception
Ainsi, sil nexiste pas dexception du JDK au
bon niveau dabstraction pour lapplication, il
vaut mieux crer un nouveau type dexception
R. Grin
Fiabilit
95
R. Grin
Fiabilit
96
R. Grin
Fiabilit
97
Messages derreur
R. Grin
Fiabilit
98
R. Grin
Fiabilit
99
R. Grin
Fiabilit
100
R. Grin
Fiabilit
101
Les assertions
R. Grin
Fiabilit
102
Points critiques
Pour vrifier la correction dun programme il
est utile de vrifier certaines assertions des
endroits bien choisis du programme
La programmation par contrat (design by
contract) a formalis lutilisation des assertions
Le langage Eiffel en implmente une partie
R. Grin
Fiabilit
103
R. Grin
Fiabilit
104
R. Grin
Fiabilit
105
assert
le JDK 1.4 a introduit un nouveau mot-cl
assert qui permet dinsrer des assertions qui
vont lancer une erreur AssertionError
(classe du paquetage java.lang, fille de
Error) lorsquelles ne seront pas vrifies
Ces vrifications peuvent tre actives en
priode de test, et dsactives en production
R. Grin
Fiabilit
106
Syntaxe
assert assertion;
assertion est une expression boolenne
assert assertion : expression;
expression peut tre nimporte quelle
expression ; sa valeur sera affiche si assert
R. Grin
Fiabilit
107
Exemples (1)
R. Grin
if (x == 0) {
. . .
}
else {
// x doit tre gal 0 ou 1
assert x == 1 : x ;
. . .
}
Fiabilit
108
Exemples (2)
R. Grin
switch(x) {
case 1: . . .
case 0: . . .
case 1: . . .
case default: assert false : x;
}
Fiabilit
109
Compilation
Par dfaut assert nest pas reconnu par javac
Ainsi les anciennes classes qui avaient des
mthodes assert peuvent tre compiles sans
problme
javac source 1.4 . . .
reconnat assert comme mot-cl
R. Grin
Fiabilit
110
Excution
taper tels
quels !
R. Grin
Fiabilit
111
R. Grin
Fiabilit
112
R. Grin
Fiabilit
113
Limitations de assert
Pas assez puissant pour vrifier simplement
une assertion du type i t[i] > 0
Ne pas utiliser pour les pr-conditions car le
contrat ne sera pas vrifi quand les assertions
seront dsactives en production ; utiliser
plutt les exceptions pour les pr-conditions
Les assertions de type invariant de classe ne se
transmettent pas aux classes filles
R. Grin
Fiabilit
114
R. Grin
Fiabilit
115
R. Grin
Fiabilit
116
Journalisation (logging)
R. Grin
Fiabilit
117
R. Grin
Fiabilit
118
Le logging
Le logging permet de suivre/enregistrer certains
vnements qui surviennent dans une
application
Le plus souvent on veut ainsi reprer les
vnements anormaux, signe dun problme
Au contraire de assert, la journalisation
ninterrompt pas le droulement de lapplication
et lutilisateur de lapplication na souvent
mme pas connaissance de son fonctionnement
R. Grin
Fiabilit
119
R. Grin
Fiabilit
120
Support de logging
Les vnements reprs par le systme de
logging peuvent tre affichs lcran mais le
plus souvent ils sont enregistrs dans un
fichier, journal de bord de lapplication
Ce journal de bord pourra tre consult par
linformaticien en charge de lapplication pour
reprer les problmes ventuels
R. Grin
Fiabilit
121
R. Grin
Fiabilit
122
Les acteurs
Fiabilit
123
Messages de logging
R. Grin
Fiabilit
124
R. Grin
Fiabilit
125
Mthodes log
R. Grin
Fiabilit
126
logger.log(Level.WARNING, "Nombre
ngatif: {0}", n);
donnera Nombre ngatif : -5 si n a la valeur
-5
R. Grin
Fiabilit
127
Mthodes logp
La mthode log indique lemplacement du code
qui a gnr le message (la classe et la mthode)
Des optimisations du compilateur peuvent
rendre imprcises ces informations
Les mthodes logp permettent de passer en
paramtre le nom de la classe et de la mthode
R. Grin
Fiabilit
128
Mthodes logrb
R. Grin
Fiabilit
129
R. Grin
Fiabilit
130
Mthode throwing
utiliser pour signaler quune mthode se
termine en lanant une exception (throw) ; le
niveau du message est FINER
Signature :
throwing(String classe-source,
String mthode-source,
Throwable exception)
R. Grin
Fiabilit
131
R. Grin
Fiabilit
132
Fiabilit
133
Obtenir un logger
On obtient un logger par la mthode static
getLogger de la classe Logger
On lui passe un nom (ici fr.truc) ; on obtient
un nouveau logger, ou un logger existant si un
logger de ce nom a dj t cr :
Logger.getLogger("fr.truc");
R. Grin
Fiabilit
134
R. Grin
Fiabilit
135
Logger.getLogger("");
R. Grin
Fiabilit
136
Exemple
package fr.truc;
import java.util.logging.*;
public class Classe {
private static Logger logger =
Logger.getLogger("fr.truc.Classe");
public static void main(String[] args){
logger.fine("Dbut");
try { Machin.do(); }
catch (Error ex){
logger.log(Level.WARNING,
"problme Machin", ex);
}
logger.fine("Fini !"); } }
R. Grin
Fiabilit
137
Handler
Les messages de logging sont passs un
handler pour leur publication
Chaque handler a sa faon de fournir les
messages lextrieur de lapplication :
sur lcran (ConsoleHandler)
dans un fichier (FileHandler)
dans un flot (StreamHandler)
dans un socket (SocketHandler)
en mmoire (MemoryHandler)
R. Grin
Fiabilit
138
Handler
On peut associer plusieurs handlers un logger
Soit par programmation :
logger.addHandler(
new FileHandler("fichier.log"));
R. Grin
Fiabilit
139
MemoryHandler
Ne fait quenregistrer les messages en mmoire
On peut indiquer ce type de handler de passer
les messages (push) emmagasins un autre
handler, par exemple un FileHandler, dsign
au moment de la cration du handler
Les messages emmagasins ne seront transmis
que si une condition survient
La condition peut tre larrive dun message
dun niveau minimum (setPushLevel)
R. Grin
Fiabilit
140
FileHandler
Sans doute le plus utilis ; enregistre les
messages dans des fichiers
Il est possible dindiquer un, ou plusieurs
fichiers qui seront utiliss circulairement
Par dfaut le niveau est Level.ALL ; il suffit
donc de fixer le niveau du logger pour que les
messages de logging soient enregistrs
Voir la javadoc pour plus dinformations
R. Grin
Fiabilit
141
R. Grin
Fiabilit
142
R. Grin
Fiabilit
143
Explications
Si 2 fichiers (count = 2), les noms par dfaut
des fichiers sont java0.log.0 et java0.log.1
Un fichier par session (mme si le fichier nest
pas plein, compte tenu de la valeur de limit) et
les derniers messages viennent dans le fichier
java0.log.0 (et pas linverse !)
Si append a la valeur true, les messages des
nouvelles sessions sajoutent dans le fichier en
cours, jusqu ce quil soit plein (avec rptition
de len-tte XML pour chaque session)
R. Grin
Fiabilit
144
R. Grin
Fiabilit
145
Exemple
// Pour enlever la console par dfaut
LogManager.getLogManager().reset();
ConsoleHandler ch = new ConsoleHandler();
ch.setLevel(Level.FINE);
Logger logger = Logger.getLogger("truc");
logger.addHandler(ch);
logger.setLevel(Level.FINE);
R. Grin
Fiabilit
146
Classe Formatter
R. Grin
Fiabilit
147
Format de sortie
Par dfaut les sorties sur lcran sont en format
texte simple (formatteur
java.util.logging.SimpleFormatter) et
les messages dans un fichier sont en XML
(java.util.logging.XMLFormatter)
Il est possible de construire son propre format
de sortie pour SimpleFormatter (proprit
java.util.logging.SimpleFormatter.format)
R. Grin
Fiabilit
148
Format de SimpleFormatter
Avec SimpleFormatter, par dfaut, les
messages ont 2 lignes ; la 1re ligne donne la
date et la mthode qui a gnr le message et la
2me ligne est le message proprement dit
Exemple :
fvr. 12, 2012 2:01:45 PM fr..MaClasse1 m
Infos: Excution mthode m
Voir javadoc de SimpleFormatter pour plus
de dtails pour changer ce format
R. Grin
Fiabilit
149
Format de XMLFormatter
<log>
<record>
<date>2012-02-12T14:28:53</date>
<millis>1329053333320</millis>
<sequence>0</sequence>
<logger>fr..MaClasse1</logger>
<level>WARNING</level>
<class>fr.unice.grin.logging.MaClasse1</class>
<method>m</method>
<thread>1</thread>
<message>Nombre ngatif: -5</message>
</record>
...
R. Grin
Fiabilit
150
R. Grin
Fiabilit
151
R. Grin
Fiabilit
152
Filtres
Si on veut filtrer les messages avec dautres
attributs que le niveau, on peut filtrer les
LogRecord avec un filtre attach un handler
Le filtre doit tre une instance dune classe qui
implmente linterface Filter
On associe un filtre un logger, ou un
handler avec les 2 mthodes de mme signature
des classes Logger et Handler
setFilter(Filter filtre)
throws SecurityException
R. Grin
Fiabilit
153
Filtrage
R. Grin
Fiabilit
154
R. Grin
Fiabilit
155
Configuration du logging
Fiabilit
156
R. Grin
Fiabilit
157
R. Grin
Fiabilit
158
XMLFormatter
R. Grin
Fiabilit
159
R. Grin
Fiabilit
160
R. Grin
Fiabilit
161
R. Grin
Fiabilit
162
R. Grin
Fiabilit
163
Exemple de fichier de
configuration (1)
# Handlers du logger racine
handlers = java.util.logging.ConsoleHandler
# Spcifie les handlers uniquement pour le
# logger de nom "test"
test.handlers = java.util.logging.FileHandler
# Niveau minimum des messages transmis
.level = ALL
# Niveaux pour les handlers
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.FileHandler.level = ALL
R. Grin
Fiabilit
164
Exemple de fichier de
configuration (2)
# Configuration du FileHandler
java.util.logging.FileHandler.pattern =
java%u.log
# Sa taille ne dpassera pas 50000 octets
java.util.logging.FileHandler.limit = 50000
# 2 fichiers de logging
java.util.logging.FileHandler.count = 2
# Le contenu du fichier sera du XML
java.util.logging.FileHandler.formatter =
java.util.logging.XMLFormatter
R. Grin
Fiabilit
165
import java.util.logging.*;
private static Logger logger =
Logger.getLogger("fr.p1.Classe");
R. Grin
Fiabilit
166
R. Grin
Fiabilit
167