Les exceptions [Topic tuto] - Java - Programmation
Marsh Posté le 10-06-2005 à 12:16:06
Jubijub a écrit :
|
c'est quoi la différence ?
Marsh Posté le 10-06-2005 à 13:58:04
tu wrappes l'exception dans une exception de layer plus haut
et tu expliques quand on arrête la chaîne.
Marsh Posté le 10-06-2005 à 15:09:10
nraynaud a écrit : tu wrappes l'exception dans une exception de layer plus haut |
je pense qu'il t'en voudrais pas si tu participais à la rédaction de son topic ...
Marsh Posté le 10-06-2005 à 15:14:00
ouais, c'est vrai ca, on wrappe quand et comment ? paske je trouve on passe la moitié du temps a wrapper les exceptions
Marsh Posté le 10-06-2005 à 15:20:27
benou a écrit : je pense qu'il t'en voudrais pas si tu participais à la rédaction de son topic ... |
je suis développeur .net moi mossieur
Marsh Posté le 10-06-2005 à 15:40:49
la chance !!
Marsh Posté le 10-06-2005 à 15:42:19
nraynaud a écrit : je suis développeur .net moi mossieur |
dit il alors qu'il sait meme pas faire un .ToString()
Marsh Posté le 10-06-2005 à 15:45:26
chrisbk a écrit : dit il alors qu'il sait meme pas faire un .ToString() |
oué, pas trop l'habitude du dispatching statique
Marsh Posté le 10-06-2005 à 15:46:41
regardé comment il tente de noyer le poisson sous du voca (d'autant plus que son histoire de dispatching il l'a decouverte y'a 2min alors qu'il planche sur le sujet depuis ce matin )
t'es rien qu'un gros mauvais
Marsh Posté le 10-06-2005 à 15:47:43
chrisbk a écrit : il planche sur le sujet depuis ce matin |
ça fait longtemps que le sujet était parti à la poubelle !
Marsh Posté le 10-06-2005 à 16:33:10
t'as oublié de causer des exceptions checked et unchecked
Marsh Posté le 10-06-2005 à 16:47:50
sauf celle qui derive de runtime, noob
Marsh Posté le 10-06-2005 à 16:51:57
sté koi la connerie ?
edit: tiens, on voit plus les posts effacés ?
Marsh Posté le 10-06-2005 à 16:52:34
bin lis le topic, andouillette de veau
Marsh Posté le 10-06-2005 à 16:54:09
han j'y crois pas comment il renie sa nullité
Marsh Posté le 10-06-2005 à 16:54:37
tu vaux guere plus qu'un nraynaud des mauvais jours
Marsh Posté le 10-06-2005 à 16:56:16
chrisbk a écrit : han j'y crois pas comment il renie sa nullité |
si c'était le cas, j'aurais pas avoué ma betise avant l'effacement
bref
Marsh Posté le 10-06-2005 à 16:57:39
chrisbk a écrit : bin lis le topic, andouillette de veau |
ben je lis, résidu de fausse couche
lorill a écrit : j'ai effacé pour pas induire les lecteurs futurs en erreur |
dis plutot pour pas qu'on voie que l'auteur d'un logiciel apprécié et reconnu est en fait une bleusaille absolue
(t'as effacé normalement ? parce que je devrais voir quand meme ton post )
Marsh Posté le 10-06-2005 à 16:58:47
bon, toujours est il que tchoupi a oublié de parler des unchecked exceptions
Marsh Posté le 10-06-2005 à 16:59:05
Harkonnen a écrit : ben je lis, résidu de fausse couche |
oué bin desolé j'avais pas vu que la manoeuvre d'effacement que lorillmicrocouilles avait fait ce paltoquet clamait qu'il n'y avait que des exceptions checked en java trop grave la tehon sa race
Marsh Posté le 10-06-2005 à 17:01:43
chrisbk a écrit : ce paltoquet clamait qu'il n'y avait que des exceptions checked en java |
hannn ptain, c'tespèce de n00b
c'est sur ce topic qu'il aurait du aller
Marsh Posté le 10-06-2005 à 17:02:54
voir meme cui la
http://forum.hardware.fr/forum2.ph [...] ash_post=0
Marsh Posté le 10-06-2005 à 17:06:08
chrisbk a écrit : voir meme cui la |
non mais clair ptain
faudrait même carrément qu'il change de forum, et qu'il aille sur celui ci
Marsh Posté le 10-06-2005 à 17:07:52
chrisbk a écrit : tu vaux guere plus qu'un nraynaud des mauvais jours |
mais lâche moi, je suis malade, submergé d'informations et dans un environnement hostile bordel
Marsh Posté le 10-06-2005 à 17:12:14
bon nraynal, avoue, l'auteur de Lucane, c'est toi hein ? nan parce que tu me feras pas croire que c'est l'autre bleusaille-qui-sort-des-conneries-plus-grosses-que-lui qui a pondu ce soft
Marsh Posté le 10-06-2005 à 22:05:38
ReplyMarsh Posté le 10-06-2005 à 23:01:56
lorill a écrit : |
pourtant ta copine m'a certifié que tu était plutôt du genre à finir rapidement et complètement
Marsh Posté le 10-06-2005 à 23:08:27
c'est quand que tu passes a strasbourg acheter un costard pour uriel déja ?
Marsh Posté le 10-06-2005 à 23:35:50
bon, les frontières de propagation des exceptions, ce sont en général les systèmes de passage de messages.
Une petite explication :
une exception remonte la pile du thread où elle s'est déclenchée, typiquement en se faisant wrapper au fil de l'eau de manière de plus en plus compréhensible de l'utilisateur.
Sauf que dans la vraie vie, l'utilsateur n'est pas un thread qui exécute des fonctions, et qui régulièrement se mangerait une exception dans le menton qui lui pêterait 2 dents. En général, le thread qui lance l'exception n'est pas celui qui a demandé l'action de plus haut niveau (on a souvent : un thread délégué au réseau, un thread délégué à l'UI, un thread délégué à du calcul asychrone etc.), on demande à d'autres threads de faire un truc pendant qu'on fait autre chose et on surveille une file de messages.
On peut donc souvent voir l'application comme une collection de threads qui s'envoient des messages (2-3 dans une application cliente typique, des dizaines quand on attaque un serveur d'application J2EE). Les applications en ligne de commande non-interactives sont dans une catégorie à part.
Or donc, dans ce modèle, on ne peut pas se permettre de casser la boucle principale (prendre un message/le traiter etc.) parce qu'elle ne sert pas qu'à l'opération foireuse, mais aussi à des dizaines de trucs innocents, donc pas question de laisser filer les exceptions jusqu'en haut de la pile, il faut les arrêter dans la boucle, passer un message représentant une erreur aux voisins que ça intéresse, et reprendre le cycle "prendre un message/le traiter".
Il existe aussi un autre grand paradigme : les threads jetables. Par exemple, le thread qui va faire une compression ZIP pendant que qu'une barre de progression est affichée (en réalité le thread graphique est beaucoup plus utile que ça dans cette situation : il va aussi faire de la peinture lors des ocultations de fenêtre, traiter les évènements des boutons etc.). Ce thread est destiné à mourir en fin de traitement ; s'il survient une exception, comme les autres, il va simplement passer un message au thread d'affichage et mourir.
Celui qui reçoit le message d'erreur, en général ne relancera pas l'exception (souvent, le message signifiant l'erreur d'ailleur ne la contiendra pas) mais aura un traitement "réel" de l'erreur, qui sera intégré au niveau business. Un serveur web lancera probablement un 500 et un paté dans les logs, chrisbk lancera un sujet sur les églises en cat Ada, une application sur le bureau ouvrira probablement une fenêtre d'erreur, un serveur d'application rollbackera avant de faire sa galette dans les logs et d'envoyer chier la file des messages JMS etc.
Un exception notable à ce principe est la délégation d'exécution, par exemple en RMI, on délègue l'appel d'une méthode à un autre système, mais on reprend l'exception distante éventuelle à son propre compte. De même pour les exception issues d'un appel par introspection ou un wrapping d'un autre langage par RMI.
voilou sur les frontières d'exécution.
Marsh Posté le 10-06-2005 à 23:37:57
t'as oublié le costard
Marsh Posté le 10-06-2005 à 23:40:14
lorill a écrit : c'est quand que tu passes a strasbourg acheter un costard pour uriel déja ? |
arrêt de te frotter à ma jambe comme ça !
Et merde ! trop tard, il a salopé mon futal !
Marsh Posté le 10-06-2005 à 12:00:02
Ceci est un premier jet....c'est donc très perfectible.
A noter, on peut trouver des conneries aussi
PLAN :
I - Documentation
II - Une exception c'est quoi ?
III - A quoi ca sert ?
IV - Comment traiter une exception ?
V - Comment les utiliser ?
VI - Comment lire un stacktrace ?
VII - Les exceptions classiques ?
Convention :
les liens hypertextes sont formattés comme ceci
I - Documentation
Le tutorial de Sun propose une section très complète sur les exceptions
Java Tutorial - Essentials concepts - Exceptions (en anglais)
II - Une exception c'est quoi ?
Simplement, une exception est un méchanisme pour faire "remonter" les problèmes qui surviennent dans un programme.
Dans une application, 2 types de problemes peuvent survenir :
- les problèmes graves, qui rendent l'environnement Java instable : ce sont des problèmes irrécupérables
- les problèmes mineurs, qui n'affectent pas l'environnement. Ce sont des problemes raisonnablement prédictibles, qui si on code correctement, NE DOIVENT PAS entrainer l'arret du programme
Avant de donner un exemple, je dois encore préciser que les exceptions sont utilisables par le programmeur pour notifier les erreurs, et que c'est un méchanisme très puissant et très propre de programmation.
Une exception est un objet java, qui encapsule :
- le stacktrace, qui est la liste des dernières méthodes appellées avant que l'exception se produise. C'est en général ce truc rouge qui s'affiche dans la console quand une erreur arrive.
Exemple :
J'expliquerai plus tard comment lire un stacktrace.
- éventuellement, un objet String contenant un message d'erreur
III - A quoi ca sert ?
Prenons un exemple :
Une partie de votre programme doit lire un fichier. Il est parfaitement possible qu'un fichier n'existe pas ou plus, ou qu'il soit illisible, ou verrouillé, pour X raisons. Un programme de ce type doit donc toujours savoir quoi faire si le fichier n'est pas lisible. C'est une erreur raisonnablement prévisible, et il n'y a pas de raison qu'elle entraine l'arret de l'application. De plus, le problème est relativement cloisonné, et n'affecte pas le reste de l'application. Par exemple il vaut mieux, si l'évènement arrive, proposer de chercher un autre fichier.
Les exceptions permettent :
1) de canaliser les erreurs
2) de déterminer quelle partie de l'application doit traiter l'erreur, et donc comment la traiter
IV - Comment traiter une exception ?
Je développerai ce point plus tard, mais pour le moment, il faut juste savoir qu'une méthode toto() peut être déclarée comme "jetant une exception", ce qui veut dire qu'elle est susceptible de générer une exception.
A partir de là, toute méthode appellant toto() a le choix entre :
- prendre en charge l'exception
- la "propager" au niveau supérieur, c'est à dire se contenter de la relancer (concept de la patate chaude)
Exemple : la méthode baba() appelle la méthode bibi() qui appelle la méthode bobo() qui jette une exception.
- bibi peut catcher l'exception de bobo, ou la relancer
- ce qu'on doit faire dans baba dépend de bibi : si bibi a catché l'exception, baba n'a rien à faire. Sinon bibi a propagé, baba doit catcher l'exception. Si baba relance l'exception, ce sera aux méthode appelant baba() de catcher l'exception.
Si personne ne catche une exception, et qu'elle est propagée tout le temps, elle va sauter à la tete de l'utilisateur, ce qui n'est évidement pas propre.
En imagé, une exception c'est comme une petite bombe : soit on la désamorce ("on la catche" ), soit on la refile au voisin (on la "propage" ). Si personne la désamorce, elle pète à la gueule de l'utilisateur.
==> il faut donc toujours catcher une exception à un moment ou à un autre
Catcher une exception :
Prenons l'exemple de bibi() qui appelle bobo() qui jette une exception
Il y a plusieurs règles à observer :
Le catch & bury c'est ça :
Il est très très très très rare d'avoir à faire ça pour une raison valable...traitez toujours vos exception : logs, remonté du message, procédure pour réinitialiser votre modèle, etc...
V - Comment les utiliser ?
Utiliser le méchanisme des exception est certes un peu contraignant (il faut décider où "catcher" l'exception, gérer un finally eventuel, etc...) mais en contrepartie, c'est un méchanisme très souple est très propre pour gérer la remontée d'un problème.
Prenons un exemple
Vous construisez une application de gestion de timbres. Chaque timbre dispose d'une cote, que vous souhaitez renseigner.
Vous proposez un écran de saisie d'un nouveau timbre. Vous DEVEZ controler que les données saisies sont correctes. Par exemple, une cote étant un prix, elle ne peut être négative.
Dans votre modèle, vous avez un objet Timbre, avec un attribut cote de type double, et un setCote(double cote) et getCote();
Conceptuellement, votre modèle doit garantir son intégrité, c'est à dire que Timbre doit garantir que les informations qu'on lui fournit sont cohérentes.
On peut soit utiliser une Exception existante, soit créer la sienne propre.
par exemple, la méthode setCote(double cote) pourrait ressembler à ceci :
Imaginons qu'on utilise une exception customizée appellée InvalidPriceException
Le message d'erreur permet de préciser l'exception.
N'utilisez les exceptions que pour une bonne raison. Parfois un if/else peut remplacer une exception. La limite est floue est sujette à débat. Posez vous la question : est-ce que sémantiquement, c'est une erreur au sens de mon application ?
Parfois vous serez obligé d'utiliser une exception, parce que java vous l'impose (méthode du package Java.IO, parsing, etc...).
VI - Comment lire un stacktrace ?
Au secours !!!! J'ai une exception et je comprends pas pourquoi.
Un stacktrace est composé comme suit :
- La première ligne donne le type de l'exception, et le message d'erreur lié
- 1 à n lignes représentant la pile d'appel des méthodes : c'est écrit dans l'ordre décroissant : la dernière méthode appellée est écrite en haut, la première en bas de la liste. Si la source est disponible, la ligne affiche également le fichier java et la ligne où figure la méthode concernée. Si vous utilisez un IDE, un clic sur la ligne vous amène généralement au lieu concerné.
- éventuellement, le thread où s'est passé l'exception
Prenons le programme suivant (il est débile, mais c'est pour le test)
Note : l'exception ici renvoyée est une fille de RuntimeException, qui a de ce fait n'a pas forcément à etre catché. Pour les RuntimeException, le catch est facultatif. Les NullPointerException font aussi partie de cette famille.
Imaginons le stacktrace suivant :
On voit :
- que c'est une java.lang.IllegalArgumentException (on peut donc commencer par aller voir la javadoc de l'exception pour comprendre ce qu'elle signifie, ca aide bcp à trouver le contexte)
- la pile contient 2 appels. D'après le source, on voit que le main a été appellé, puis la méthodeInutile .
- le dernier appel étant méthodeInutile(), il y a de fortes chances que la source de l'exception soit là.
En examinant son code, on voit qu'effectivement elle est susceptible de lancer une exception. En regardant le code, on voit que si le param est une string vide ("" ), l'exception est lancée.
On peut donc affirmer que la methodeInutile a reçu "" comme paramètre. En obervant l'appel, on se rend compte que c'est la cas (ici c'est hardcodé, mais si c'était dynamique, il faudrait alors trouver pourquoi la String est vide)
Un peu plus dur
Comment s'y retrouver ?
La pile est énorme ici.
Première chose, regarder les packages :
y'a du java.lang, y'a du com.PouetPouet, y'a du org.apache, et y'a du com.ibm ...on peut espérer que le problème ne vienne pas des outils utilisés, et que ca vient de notre code. On peut déjà restreindre à com.PouetPouet.
Il suffit alors de suivre les appels du plus récent au plus ancien. Attention, la lecture est ici obscurcie du fait d'une hiérarchie de classe (y'a le type Struts + 3 surtypes en dessous)...
VII - Les exceptions classiques ?
La NullPointerException (appellée "NPE" )
Cette exception, très fréquente, indique que l'on a tenté d'accéder à une méthode ou un champs d'un objet ayant une valeur nulle.
Par exemple :
user vaut null. On essaye d'appeller une méthode sur un objet à null. Ca va générer une nullPointerException.
Comment la résoudre :
Imaginons :
Si cette ligne renvoit une NPE, ca peut etre :
- parce que user est null
- parce que le profile est null
- parce que la profile family est nulle
- parce que la superFamily est nulle
Il vous faudra donc tester patiemment pour trouver lequel est nul.
---------------
Jubi Photos : Flickr - 500px