Archive

Posts Tagged ‘fr’

Présentation Coder propre en ligne :)

février 20, 2014 1 commentaire

Presque un an après les quelques confs sur le sujet, j’ai enfin pondu la version oueb présentable, par là : Coder Propre

Un bon bout de temps me direz vous ? En effet, mais le hic était que la présentation initiale était « zen ». Autrement dit, des diapos minimalistes, avec très peu de contenu afin de préserver autant que possible le discours. A priori ça avait plutôt bien marché, mais par contre, traduire ça en présentation à lire, galère… Sans compter que le bébé était en impress.js, soit pas quelque chose qui ait prévu dès le début d’avoir des notes associées…

Bref, pour la prochaine fois, je me dis que peut être je ferai le tout direct en diapos. Certes, ça rend moins bien qu’une présentation JS avec des transitions minimalistes et sympas. Mais bon, c’est ensuite bien plus simple à mettre en ligne, surtout quand on se dit que cela pourrait être utile pour plus tard à l’auditoire.

A propos, si vous en faisiez parti, ne soyez pas surpris si le contenu diffère un peu de la présentation : le format m’a fait réaliser quelques coupes. Des bouts qui étaient à priori confus et que je tentais d’éclaircir par le verbiage l’ont été à la hache.

Bref, tout retour bienvenu, comme d’hab, et voyons si j’ai le courage de m’atteler à une présentation du Domain Driven Design, la suite logique, AMHA, de la présentation de l’an passé 🙂

++

Publicités
Étiquettes : , ,

Enseignants en informatique… enseignez l’informatique !

janvier 27, 2014 3 commentaires
Billet d’humeur qui dormait depuis longtemps sur mon disque, écrit avec passion et qui m’a bien apaisé… Puisse t il en faire autant pour vous !
 
Récemment encore, une soutenance. Projet de l’étudiant ? Faire du développement. Réaction des professeurs ? Allons, tu es bon, tu devrais viser chef de projet.
 
Ca a à tout l’air d’une boutade ? Que nenni, école après école, même rengaine.
 
Attention, scoop : il existe des formations pour être chef. Si si. On appelle cela des formations en management. Ceux qui désirent être chefs y vont en général. Et voici un autre scoop : la plupart des étudiants en informatique ne veulent pas être chefs. Si si. Je ne sais pas bien pourquoi chaque école d’ingénieur, ou presque, reprend le mantra du « tu seras chef, jeune ingénieur », mais il se trouve que certains étudiants sont plutôt attirés par les connotations scientifiques et techniques du mot ingénieur. Genre résoudre des problèmes, progresser, apporter des solutions innovantes, plutôt qu’encadrer.
 
Pas d’inquiétude, j’entends déjà les arguments habituels : nous leur apprenons à apprendre. Ils sont intelligents et s’adaptent : ils ont les bases, la suite est aisée. 
 
Les enfants de 10 ans aussi ont les bases du langage. Ils savent lire, écrire, compter même. Ils peuvent reproduire des choses déjà vues. Pourraient ils pour autant rédiger un acte notarié ? Comprendre une notice technique ? Ecrire un roman qui présente un intérêt pour le lecteur ? Bien qu’il y ait des exceptions, dans l’immense majorité des cas la réponse est non.
 
Figurez vous qu’en informatique c’est pareil. Connaître et avoir vaguement pratiqué les bases d’un langage ne suffit pas. Connaître les bases d’un langage ne permet pas de développer correctement en utilisant ce langage, ni même de se qualifier d’informaticien. En toute franchise, apprendre un langage est devenu trivial de nos jours. Plein de personnes, de tous horizons, le font de leur propre initiative, sur le temps libre, aisément, sans encadrement scolaire. C’est facile à faire, après tout, on a tous déjà appris un langage… Ces personnes sont elles pour autant des informaticiens ? Des personnes hautement qualifiées ? J’en doute. 
 
En fait, en pratique, c’est même quasiment l’inverse : les premiers jets dans un langage sont généralement primitifs et guère attrayant. Pire encore, passé le cap initial requiert de l’approfondissement, de la réflexion, de la pratique. Combien font cette démarche ? Combien d’entreprises ont elles les moyens ou l’envie de les y accompagner ? D’ailleurs, figurez vous, les entreprises en général ont une perception proche de celle des écoles d’ingénieur : faut devenir chef. Pour ça, pas besoin d’être bon informaticien, mais plutôt de suivre les ordres et reproduire l’existant. Rien ne permettant ou favorisant l’apprentissage nécessaire et, pire, la mise en pratique résultante.
 
J’en fais trop me direz vous, qu’y a t il de bien compliqué à l’informatique, à la programmation ? Quelques pistes, en vrac, à titre d’illustrations…
 
Etre informaticien, c’est connaître les différentes façons de résoudre un même problème, avec à chaque fois les forces et faiblesses respectives. Vous voulez accéder à des données en base ? Plusieurs possibilités. Utilisation d’une classe pour chaque table, représentant simplement les données, puis avoir des utilitaires pour peupler ces classes. Utiliser des classes encapsulant une bonne partie de la logique d’accès, voir exposant des types évolués. Avoir un modèle objet riche, avec héritage, composition, au plus proche des besoins, que l’on adaptera ensuite à la représentation en base. Avoir un stockage des données sans représentation commune avec l’usage qui en est fait, avec un mécanisme de récupération et construction des structures utilisées. Combien d’élèves connaissent ces approches ? Combien en connaissent les forces et faiblesses ? Combien d’enseignants ? Attention, cela n’a rien d’un secret jalousement gardé. Là encore, internet donne tout ça. Des livres existent sur le sujet (« Patterns of Enterprise Architecture » de Martin Fowler par exemple).
 
Mais en fait, l’informatique, c’est bien plus que cela. Etre informaticien, c’est savoir comment écrire son code pour qu’il soit lisible, juste et aisément modifiable. C’est éviter de faire une usine de gaz quand on veut simplement moudre le grain. Faire simple est l’ultime sophistication disait Léonard de Vinci (un ingénieur avant l’heure pour la peine, plutôt reconnu comme bonhomme). Faire simple est nécessaire en informatique : le code va vivre, sera maintenu par différentes personnes, devra répondre à des besoins non anticipés. Et faire simple s’apprend. Non des commentaires toutes les lignes n’aident pas. Non mille lignes de code à la suite n’aident pas. Oui on évite la double négation. Oui on fait du « fail fast »…
 
Mais en fait, l’informatique, c’est bien plus que cela. Pour limiter les risques, le code doit être testé. Et pas de façon artisanale sauce pré histoire, avec ses doigts et un gourdin, mais avec des outils automatisant la chose, exécutant les tests à chaque changement, de façon transparente. Ca parait fou, mais aujourd’hui c’est la norme pour les informaticiens soucieux de leur travail. Pourtant je n’ai pas encore vu un seul étudiant ayant appris la chose pendant ses cours. Je ne suis même pas certain que 20% des enseignants connaissent les notions de tests unitaires et intégration continue. 
 
Mais en fait, l’informatique, c’est bien plus que cela. Parce qu’en fait, généralement, on écrit pas du code. On reprend l’existant, on le modifie. C’est d’un coup bien plus compliqué. Il faut rentrer dedans, comprendre son fonctionnement. Il faut connaitre les outils disponibles : debugger (des élèves ingénieurs ne connaissaient pas), outils d’inspection du code (hiérarchie des classes, références vers une classe, appelant d’une méthode). Il faut connaitre les subtilités des langages, qui ont sans doute été utilisées de ci de là, souvent pour des pièces critiques de l’architecture (réflection, invocation dynamique, mixins, proxy…). Il faut connaitre les patterns classiques (factory, decorator). Et après il faut aller modifier tout cela. Faire plus propre que cela ne l’était (cas général) ou rester au même niveau que l’existant (l’exception). Cela a même un nom : le refactoring. Là encore, le nom est inconnu pour bien des étudiants et enseignants… Quand aux méthodes et outils associés, n’en parlons pas.
 
Mais en fait, l’informatique, c’est bien plus que cela. Le code n’est qu’une partie du tout. Il y a la construction du livrable. Le processus de déploiement. L’environnement de recette. Il y a les différentes versions au cours du temps. De son propre logiciel ou de ses dépendances. Ou même, en production, différentes versions au même instant afin de faire du canary release. Il y a la mise à jour sans interruption de service. Il y a le besoin d’avoir des informations de contexte en cas de bug, les informations permettant d’identifier le problème. Il y a la possibilité de savoir qui a fait quoi quand pour comprendre l’historique du problème, ses raisons, pour ensuite le corriger ainsi que tout le mal fait entre temps. 
 
Mais, en fait, l’informatique c’est bien plus que cela. Il y a les milles spécificités de l’environnement retenu. Du système d’exploitation, des serveurs, du réseau, des systèmes embarqués. Du web. Des sockets. Ces détails de l’environnement technique utilisé qui nécessitent toutes les connaissances ci dessus pour en tirer le meilleur. Mais cet environnement technique qui est un monde à lui tout seul, à nouveau. Avec ces bonnes pratiques, ces rouages essentiels, son histoire.
 
Mais en fait, l’informatique, c’est bien plus que cela. C’est déterminer ce que veut l’utilisateur, quand, pourquoi. C’est se mettre d’accord sur la solution, sa mise en oeuvre, en proposant le meilleur de ce qui a été énuméré jusqu’ici. Savoir que son environnement peut proposer telle fonctionnalité aisément ou que telle autre sera très longue et couteuse à atteindre. C’est trouver ce qui est déjà existant pour ne pas réinventer la roue. C’est livrer tout cela à l’utilisateur, s’assurer que ça lui convient, que ça fonctionne, que ça répond aux attentes. C’est s’assurer que la solution s’intègre bien avec son environnement, avec l’existant, les évolutions dans les habitudes et outils. Avec toujours un donneur d’ordre, des utilisateurs et des informaticiens. Dans les délais, le moins cher possible, correctement, le tout sur fond de communication permanente.
 
Au risque de me répéter, l’informatique, c’est, en fait, bien plus que cela. En fait, c’est tout cela, et bien plus plus, tout le temps, sans cesse en changement. Avec des gens qui réinventent la roue, des intérêts personnels, commerciaux, des à priori et beaucoup de choses non étayées. Des intervenants par millions. Aussi, aller de l’avant, c’est savoir se concentrer sur ses vrais problèmes. C’est avoir les bases nécessaires pour distinguer le bon grain de l’ivraie. C’est savoir déceler dans ce magma bouillonnant la perle qui résout votre problème. C’est savoir de ne pas suivre la mode du moment, comprendre les implications de ce qu’on lit, tout en sachant se remettre en cause. C’est oser de démarquer, se justifier. C’est se remettre en cause et remettre en cause l’existant, sans cesse, pour avancer, le tout dans un terrible brouillard confus d’intérêts, de bruits et de beuglards contradictoires. C’est se forger sa vérité dans tout ça, pour son contexte et ses besoins.
 
Aussi, je pense qu’enseigner l’informatique c’est comprendre que les bases ne sont pas suffisantes. C’est comprendre que l’informatique est bien plus, un métier à part entière, capable de remplir largement les quarante années à venir d’un étudiant. C’est comprendre que former des gens à même d’être compétents dans un tel métier est une chose difficile. C’est comprendre qu’en France, malheureusement, la plupart du temps, l’informatique c’est bien moins que cela, que ces compétences ne sont pas présentes, pas prisées. Qu’il va falloir changer les habitudes afin de produire réellement de la valeur ajoutée. Quitte à bouleverser quelques hiérarchies et à recentrer l’enseignement informatique sur… l’informatique.
 
J’espère sincèrement que des enseignants ont lu ces lignes. Elles sont pour eux. Pour que leurs discours et leurs enseignements soient plus en accord avec mon quotidien d’informaticien. Pour que l’enseignement évolue enfin. Clairement, c’est un acte isolé, mais néanmoins murement réfléchi, présent depuis mes débuts professionnels. Et j’espère que, petit à petit, l’enseignement de l’informatique en France changera pour le meilleur. Si cette contribution aide à cela, alors cela me va. A vrai dire, pour avoir donné des conférences sur le « code propre » et avoir refusé les offres d’enseigner qui ont suivi, le fond de ma pensée est qu’il serait temps que les enseignants en informatique enseignent vraiment l’informatique. Et je suis plus que volontaire pour aider, mais pas pour faire leur travail à leur place : je n’ai déjà pas assez de temps pour … l’informatique !
Étiquettes : , ,

Patates et exceptions

mai 30, 2013 1 commentaire

On a vu précédement pourquoi les exceptions vérifiées sont une mauvaise idée (que je vous conseille de lire en préambule), voyons à présent comment bien gérer les exceptions.

Rassurez vous, c’est tout simple : faut voir ça comme le jeu de la patate chaude. Par défaut, on sait pas quoi en faire et faut juste refiler le bébé le plus vite possible aux autres. Facile non ?

Bon, on est joueur, on va faire ça en trois parties :
1. Passer la patate efficacement
2. Savoir mettre le feu à la patate
3. l’art de bien attraper la patate

1. Passer la patate efficacement

Comme vous le savez, bien jouer à la patate chaude implique, surtout, de ne pas avoir à s’occuper de la patate. Si on ne l’a pas, on risque pas de se rater lors de la relance. En Java, c’est pareil. Si on ne sait pas quoi faire d’une exception, le mieux est de la laisser filer. On ne l’attrape (catch) pas, rien, nada.

Bien sûr, on a ces merveilles d’exceptions vérifiées (Checked exception), celles qui vous forcent à les catcher. On en fait quoi alors ? C’est tout simple, on en fait des RuntimeException, par exemple :

try {
	// code lançant des exceptions vérifiées
} catch (MonExceptionVerifiee e){
	throw ExceptionUtils.wrap(e);
}

avec :

public class ExceptionUtils {
	
	public static RuntimeException wrap(Throwable t){
        if (e instanceof RuntimeException) {
            return (RuntimeException) e;
        } else {
            return new RuntimeException(e);
        }
	}
}

Du coup l’appelant n’à rien à attraper et l’exception sera traitée à plus haut niveau. La vie est belle non ?

Certes, par rapport aux exceptions vérifiées, l’appelant en sait moins sur les façons dont votre méthode est susceptible de mal tourner. Mais, ça n’a rien d’inéluctable : le mot clé throws, indiquant les exceptions lancées par une méthode, marche tout autant pour des exceptions vérifiées que nous vérifiées. Aussi, rien ne vous empêche d’écrire:

public Foo bar() throws BarException{
	// ..
}

avec

public BarException extends RuntimeException {
	// ..
}

Vu que BarException étend RuntimeException, vous ne serez pas obligé de catcher à chaque throw, par contre votre IDE préféré devrait vous indiquer son existence à la moindre occasion.

Par contre, par pitié, n’indiquez pas que vous êtes susceptibles de jeter n’importe quelle exception, genre:

public Bad doBad() throws Throwable

ainsi que la variante

public Bad doBad() throws Exception

En effet, là vous vous contentez d’indiquer que le code est susceptible de mal tourner, d’avoir des bugs et ainsi de suite. Or c’est le cas de tout bout de code. Du coup n’importe quelle application se doit de gérer le cas de l’exception inattendue, celle due à un bug bien idiot. Aussi, en indiquant « throws Throwable », vous ne faites que rappeller l’évidence verbeusement. Maaaal.

Il y a encore pire : avaler l’exception. Vous savez, ce que propose de faire Eclipse par défaut:

} catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Mais encore plus pire est possible (youpee) :

} catch (Throwable t) {
}

Certes, vous n’aurez plus d’exception dans l’application. Mais celles ci ne sont que les symptômes du mal… Sans elles, le mal sera toujours présent mais en plus indétectable. Plantages et comportements aléatoires en perspective, que du bonheur.

A noter que catch(Throwable t) détient la palme. En effet, pour mémoire, la hiérarchie des exceptions Java est la suivante:

Throwable (vérifiée) <- Error (non vérifiée)
^
|

Exception (vérifiée)
^
|
RuntimeException (non vérifiée)

Tous les problèmes du niveau de la JVM remontent via des sous classes d'Error. Quelques exemples fameux: StackOverflowError, OutOfMemoryError et autres KernelError.

Les problèmes dus au code sont signalés via des classes héritant d'Exception ou de RuntimeException. Genre les IOException ou les ClassCastException.

Du coup, le petit malin qui avale tout à partir de Throwable ne saura notifié ni des erreurs de son code ni des problèmes de la JVM. Sympa non ?

2. Bien allumer la patate lors de sa cuisson

Maintenant qu’on sait comment passer la patate, voyons comment la créer.

En premier lieu, toujours hériter de RuntimeException (sauf pour les développeurs derrière la JVM, bien sûr, qui eux étendent Error).

Pourquoi RuntimeException ? Facile : on veut faciliter la passe de la patate chaude, donc autant que l’appelant n’ait rien à faire par défaut, comme ça au moins il ne risque pas de faire mal. Genre avaler l’exception.

Ensuite, quel est le but de la patate ? Signaler un problème, un dysfonctionnement, une erreur. Du coup, autant communiquer un maximum d’informations : vos exceptions doivent toujours avoir un constructeur avec un message de type String. A chaque création d’une instance on pourra alors donner un maximum d’information de contexte. Genre les paramètres de la méthode appelée. Par contre, le nom de la méthode et la pile d’appel sont là par défaut, dans la pile d’appels (stack trace) pas besoin de dupliquer…

Si jamais votre exception encapsule une autre exception, merci de la lui donner. En effet, que se passe-t-il si je code ainsi:

catch (IOException e){
	throw new MyException("File access failed");
}

C’est tout simple : la personne traitant mon exception ne pourra pas en connaître la cause réelle. Et même dans le cas de cette bonne vieille IOException, si commune, ne vous laissez pas abuser : ces sous classes sont aussi diverses que ErrorInQuitException ou BadAudioHeaderException. Bref, si une exception a pour origine une autre exception, toujours la transmettre.

Bien sûr, si on peut donner du contexte, c’est encore mieux :

catch (IOException e){
	throw new MyException("File access failed for file '" + file + "' and user '" + user + "'", e);
}

In fine, le squelette d’une bonne exception à soi est, à mon humble avis, quelque chose du genre :

public class MyException extends RuntimeException{
	
	public MyException(String message){
		super(message);
	}

	public MyException(String message, Throwable throwable){
		super(message, throwable);
	}

	public MyException(Throwable throwable){
		super(throwable);
	}

} 

Pas de constructeur sans paramètre: on veut nécessairement du contexte. (Bon des fois y en a vraiment pas au delà de la pile d’appels, mais bon, comprenez le message ;)).

Si jamais vous décidez d’ajouter des paramètres supplémentaires et spécifiques à votre application, n’oubliez pas alors de surcharger getMessage(), afin que tout le contexte soit toujours affiché.

3. L’art de bien attraper la patate

A l’occasion, si on sait quoi faire sur l’exception, alors on s’en occupe.

Cela arrive généralement en deux circonstances : soit au plus près de l’exception, quand on peut retomber sur ses pieds autrement, soit plusieurs niveaux d’abstraction plus haut, aux frontières de l’application ou du module. Genre pour afficher un message d’erreur à l’utilisateur, ou au système tiers.

Gérer l’exception au plus près est normalement simple : on ne fait cela que si on sait quoi faire.

Par exemple:

public boolean isValidInteger(String text){
	try {
		Integer.parseInt(text);
		return true;
	} catch (NumberFormatException e){
		return false;
	}
}

Pour la gestion à plus haut niveau, il faut s’assurer d’attraper vraiment toutes les exceptions. Pour cela, il y a depuis Java 5 la méthode Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) qui définit qui sera appelé en dernier recours, si rien n’a attrapé l’exception au préalable. Ainsi toutes les exceptions seront attrapées de façon certaines, qu’elles aient été lancées le thread courant ou un autre. Faites en bon usage.

La gestion de l’erreur implique souvent la communication d’un message à un tiers, que ce soit l’utilisateur ou le système appelant. Il arrive parfois que des actions plus drastiques soient nécessaires, particulièrement dans le cas des Error, où parfois l’arrêt est la seule option (dans le cas d’une OutOfMemoryError, c’est le seul remède que je connaisse par exemple).

Toutefois, qu’on traite l’exception au plus près ou à plus haut niveau, toujours, j’ai bien dit TOUJOURS, faire en sorte de donner tout son contenu au développeur qui devra débugger le code. Ne serait ce qu’un log, fusse-t-il de niveau debug, ou, même, au pire, une sortie console. L’essentiel est que toute l’info soit accessible sans devoir changer le code. Se contenter d’afficher le message de l’exception (sans la pile d’appels) est, par exemple, notoirement insuffisant. De même, si vous utilisez un framework de logging, assurez vous qu’il affiche bien tout le contenu de l’exception, ainsi que des diverses différentes exceptions éventuellement contenues dans l’exception courante. La stack trace complète est de la plus haute importance.

Espérons que ces conseils améliorent votre gameplay à la patate chaude. Bien que souvent négligé et bien moins hype que d’autres jeux plus récents (comme réinventer la roue par exemple), gérer correctement les exceptions est crucial pour toute application, afin d’en assurer l’évolution et la maintenance sereinement.

Au plaisir de vous lire !

NB: pour les utilisateurs d’Eclipse (je sais, ça aussi c’est pas à la mode, désolé), notez qu’il y a une « Java Stack Trace Console » disponible au niveau de la console eclipse, via le bouton « Open Console ». Lorsque vous y collez une stack trace, eclipse vous permet d’aller aux différents points concernés en cliquant sur les lignes de la stack trace. Pratique. Pas révolutionnaire mais pratique.

NB2: Java 7 introduit le multi catch et autres try with resources. Bien que pratiques, ils ne changent pas fondamentalement la donne (sauf pour l’art obscur de la fermeture de ressources, non abordé ici).

Étiquettes : , , ,

Pourquoi les exceptions vérifiées sont une mauvaise idée

mai 30, 2013 5 commentaires

Dans la série « je blogue pour éviter de me répéter », je demande les exceptions vérifiées.

Attendez, je vous devine: c’est quoi une exception vérifiée ?

C’est une invention de Java (à ma connaissance) consistant en une exception que le contexte est obligé de considérer

Autrement dit, si j’écris:

throw new MonExceptionVerifiee();

avec

public class MonExceptionVerifiee extends Exception

alors le code entourant cette instanciation est obligé de prendre en compte l’exception.

Deux façons pour cela, la première consistant à relancer l’exception pour ne pas avoir à s’en préocupper :

public void maMethode() throws MonExceptionVerifiee {	
	throw new MonExceptionVerifiee("Pour la cause");
}

Le throws au niveau du nom de la méthode est ce qui permet de relancer l’exception.

La seconde façon consiste à attraper l’exception pour la traiter, comme suit:

public void monAutreMethode() {	
	try {
		throw new MonExceptionVerifiee("Pour la cause");
	} catch(MonExceptionVerifiee e){
		// ?
	}
}

Bon, là ça présente peu d’intérêt, en général on attrape plutôt les exceptions vérifiées lancées par les autres, par exemple :

public void monAutreMethode() {	
	try {
		maMethode();
	} catch(MonExceptionVerifiee e){
		// ?
	}
}

Pour finir avec l’introduction aux exceptions vérifiées, sachez qu’une exception, pour être vérifiée, doit hériter de Throwable ou Exception, mais qu’elle ne l’est pas si elle hérite d’Error ou de RuntimeException, ce qui la hiérarchie des exceptions Java suivante :

Throwable (vérifiée) <- Error (non vérifiée)
^
|

Exception (vérifiée)
^
|
RuntimeException (non vérifiée)

Autrement dit, Throwable est tout en haut et est une exception vérifiée. Error étend Throwable, et n'est pas vérifiée. Exception étend Throwable, et est vérifiée. RuntimeException étend Exception et… n'est pas vérifiée.

Alambiqué hein ? Je suis d'accord, et en général si la conception est compliquée, alors l'idée est foireuse. Mais j'anticipe.

En effet, pourquoi diable les exceptions vérifiées?

L'intention initiale est de forcer le code à considérer les exceptions. En effet, comme cela, en lisant un fichier, je serai bien conscient que la lecture de ce dernier peut planter. Certes, c'est appréciable, mais que puis je faire pour autant ? Et là est tout le mal des exceptions vérifiées. Leur traitement n'est pas simple et, surtout, rien ne garanti qu'il sera bien fait.

Revenons à l'exemple précédent :

public void monAutreMethode() {	
	try {
		maMethode();
	} catch(MonExceptionVerifiee e){
		// ?
	}
}

A noter que si une méthode lance plusieurs exceptions vérifiées, on est obligé de les traiter chacune. Par exemple, l’autre de maMethode pourrait choisir de lancer également des IOException, comme suit :

public void maMethode() throws MonExceptionVerifiee, IOException {	
	throw new MonExceptionVerifiee("Pour la cause");
}

alors la méthode appelante sera du genre :

public void monAutreMethode() {	
	try {
		maMethode();
	} catch(MonExceptionVerifiee e){
		// ?
	} catch(IOException e){
		// ??
	}
}

Verbeux. Et embêtant: la prochaine fois que l’auteur de maMethode choisira d’ajouter un throw, il faudra que je change à nouveau mon code. Que faire quand on est malin ? Facile, l’obligation de traiter les exceptions vérifiées prend en compte la hiérarchie, du coup je peux écrire ça :

public void monAutreMethode() {	
	try {
		maMethode();
	} catch(Throwable t){
		// ?
	}
}

Tadamm ! C’est nettement moins verbeux, et même plus robuste au changement : le petit gars derrière maMethode peut se lâcher. Désormais, j’suis blindé.

Vous noterez le commentaire « // ? » dans le catch, vu que sur le coup je ne savais pas quoi faire. Faire un tel catch qui ne renvoie aucune exception s’appelle avaler une exception, ou dans le cas présent avaler toutes les exceptions. Fort hein ? Ca semble la parade ultime…

Sauf que… sauf que désormais, plus aucune exception ne remonte. Vérifiée ou pas. Lancée par le programme ou la JVM (toutes les exceptions découlant d’Error). Nada. Rien. Et là, bonjour l’enfer : désormais en cas de plantage, plus aucune info n’est dispo. Avec un peu de chance l’appelant se rend compte qu’un effet de bord n’est pas présent (genre je clique et rien ne se passe), mais ce n’est pas garanti. A débugger, cela relève des travaux d’Hercule : aucune info, sauf que ça marche pas. Pas de trace.

Les seules options que je voie est de modifier tous les catch (ah ah ! – surtout sur du code tiers) ou de s’taper toute l’application au débuggeur… Dans les deux cas, vous serez forcé de faire ça après coup sans aucun élément sur l’origine du problème. Dans les deux cas, vous chercherez une aiguille dans une botte de foin. Et si votre code contient beaucoup de catch avalant des exceptions, vous avez un sacré paquet d’aiguilles différentes à chercher une à une, tout au long de la vie de votre application…

Bien sûr, me direz vous, aucun développeur digne de ce nom n’aurait la bonne idée d’avaler toutes les exceptions. Mais le catch vide est juste très facile, tentant même. Dans l’exemple ci dessus, dans monAutreMethode, je ne savais pas quoi mettre lors de la rédaction de l’exemple, j’ai mis un commentaire vide, le // ?, pour remplir. Et devinez quoi, ça compile et ça peut partir en prod sans problème! Combien de développeurs se retrouvent exactement dans la même situation ? Combien laissent un commentaire type « TODO » et autres « Euh, à traiter? » puis continuent comme si de rien n’était ? Beaucoup. Trop. De plus, cela semble résoudre le problème du traitement d’erreur, de ces satanés IOEXception dont on ne sait que faire…

Sans compter que cela ne semble pas être une si mauvaise pratique : eclipse propose par défaut de quasiment avaler les exceptions vérifiées. En effet, le quick fix par défaut d’eclipse pour gérer cette fameuse maMethode() throws MonExceptionVerifiee, IOException est le suivant :

try {
    maMethode();
} catch (MonExceptionVerifiee e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Génial non ? Exception avalée, pile d’appels imprimée mais… sans le message de l’exception (accessible via e.getMessage()). Noter cet appel direct à e.printStackTrace() : votre API de logging préférée n’a aucune chance de s’en mêler.

Bref, le professionnalisme est mis à rude épreuve et avaler les exceptions semble la bonne solution. Du coup, chaque code lançant une exception vérifiée est à la merci du premier développeur commettant une erreur dans son traitement. Quelques lignes et zou plus rien, des erreurs cachées et une application à débugger dès qu’on se rendra compte de l’erreur. Peut être après mille appels à la méthode plantant. Peut être après milles confirmations envoyées à tort. Splendide et… imparable.

Pour la petite histoire, avaler les exceptions n’est pas toujours le fait de développeurs. Eh oui, j’ai vu des architectes, et pas nécessairement Java, faire ainsi dans leur code. Sur toute l’application. A chaque fois qu’ils pouvaient se faire mordre par une saleté d’exception. Pour la défense de ces érudits, notons que nos glorieuses écoles d’ingénieur en informatique n’enseignent rien en la matière. J’ai discuté avec de nombreux étudiants de nombreuses (hautes) écoles différentes, ou d’université, et jamais le thème n’avait été abordé. Après tout, les exceptions, c’est pour ceux qui font du mauvais code en premier lieu non ?

In fine, sommes nous désormais d’accord que les exceptions vérifiées sont une mauvaise chose ? Rassurez vous, y a moyen de les traiter correctement : c’est l’objet de l’article suivant, Patates et exceptions. On se voit là bas 😉

Étiquettes : , , ,

Apache Maven, 2eme édition

décembre 12, 2011 2 commentaires

Cet été (si loin déjà!), Pearson m’a envoyé un exemplaire gratuit du livre Apache Maven 2 et 3, 2eme édition, grâce à la sympathique entremise d’Arnaud Héritier et Nicolas de loof.

Bien que j’ai dévoré le livre dès réception, la présente critique a été retardée par un déménagement/changement de taff. Ceci dit, mieux vaut tard que jamais, et maintenant que le contexte a été posé voyons pour une critique sans faux semblant…

Alors, que dire d’Apache Maven 2 et 3? Pour les pressés, en quelques mots: si vous sentez débutant/intermédiaire en Maven, foncez. Si vous êtes expert et cherchez à tuner votre Maven, passez votre chemin.

Pourquoi foncez? Tout simplement parce que le livre réussi à bien mettre en avant tout l’intérêt et la force de Maven, abordant les multiples domaines d’usage, sans sombrer dans le guide de référence infâme et soporifique (et supplanté par internet depuis que l’ADSL existe), le tout avec un mode narratif franchement agréable passé la surprise initiale (il s’agit en effet de Nicolas et Arnaud narrant comme telle ou telle personne ont eu tels soucis et comment cela a été résolu). Et comble du raffinement, nos deux comparses fournissent en chemin des trucs et astuces pour des problèmes « courants » qui, perso, m’ont bien servi depuis.

Certes, tout un chacun trouvera des aspects qu’il aurait souhaité voir plus approfondi, mais c’est également une des forces du livre: il pousse à aller de l’avant, tout en donnant les bases pour qu’on se sente capable de le faire. A l’inverse, il ne cache pas certains aspects encore perfectibles de Maven, tout en fournissant assez d’info pour que le lecteur ne soit pas démuni.

Je ne ferai qu’une critique négative de taille: les auteurs tentent de rassurer sur le futur de Maven, entre Sonatype et la fondation Apache. Et perso ils ont produit tout l’effet contraire. En effet, si on lit bien que les deux organisations sont faites de personnes pleines de bonne volonté, on devine également aisément que des tensions sont présentes, sans en avoir le détail, tout en voyant de façon évidente les contradictions des deux approches, entre le rythme mesuré de la fondation Apache et de ses règles et le dynamisme zélé (et intéressé) du papa de Maven et son équipe.
J’ai également ressenti un certain flou sur les produits Sonatype. Comment s’intègrent ils avec le reste? Où commence le domaine payant? Quelle stratégie est suivie par Sonatype dans tout cela?
Bref, ça manque de vision d’ensemble, à mon sens, ainsi que d’une présentation claire et sans ambages des tensions présentes (ou passées, j’en sais rien moi) histoire de poser le cadre.

Avec le recul, toutefois, cette critique s’atténue pour laisser place à la gratitude de se servir au quotidien des conseils et de l’inspiration générées par ce bouquin. Aussi, vue la période, je concluerai simplement: un parfait cadeau de Noël pour geek ou geekette!

Allez, bonne lecture à tous et encore merci à nos deux auteurs!
++
joseph

Étiquettes : , , ,

Wicket: fournir des données JSON via Ajax

septembre 3, 2010 1 commentaire

[Article also available in English]

Il y a quelques semaines, nous devions retourner des données sous forme JSON suite à des appels JavaScript. N’étant pas familier avec la chose, nous étions partis sur une page ne retournant qu’un contenu JSON. Quelque chose comme ça:

 @Override
    protected void onRender(final MarkupStream markupStream)
    {
        try
        {
            OutputStream outputStream = getResponse().getOutputStream();
            outputStream.write(jsonData.getBytes());
            outputStream.flush();
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }

    }

L’url de cette page était fournie au code JavaScript via cet appel:

 
RequestCycle.get().urlFor(jsonPage);

Bien évidemment, l’appel et la gestion de cette page étaient encapsulés, histoire de ne pas polluer chaque utilisateur avec ces subtilités.
Toutefois, bien que fonctionnelle, cette solution n’est pas parfaite. En effet, cette page supplémentaire implique un contexte différente où les infos doivent être amenées. Rester au sein même du composant/contexte pourrait être plus plus sympa (c’est certes toujours possible, mais bien moins propre et requérant plus de travail). Cette solution est également plutôt verbeuse.

Le bon côté de la chose est que cette page, avec peu de contenu, prend également peu de place une fois sérialisée, ce qui arrive souvent avec Wicket. Je vous l’disais, rien n’est parfait 😉

Cependant, plus récemment, je cherchais une façon de coordonner un Behavior Ajax Wicket avec une fonction jQuery, les deux se déclenchant sur le même événement JavaScript. En chemin, j’ai trouvé cette « astuce » de Richard Wilkinson dans une conversation nommée Wicket, Ajax and JSON. Et devinez quoi: c’est tout simple de faire interagir du JavaScript et un Behavior via des données JSON (ou quelque contenu de votre choix).
Voici le code de Richard:

 
    AbstractAjaxBehavior behaviour = new AbstractAjaxBehavior()
        {
            private static final long serialVersionUID = 1L;

            @SuppressWarnings("unchecked")
            public void onRequest()
            {
                //get parameters
                final RequestCycle requestCycle = RequestCycle.get();

                final PageParameters pageParameters = new PageParameters(requestCycle.getRequest().getParameterMap());
               
                //do something using nice json library to produce a string of json
                String json = .......
               
               
                requestCycle.setRequestTarget(new StringRequestTarget("application/json", "utf-8", json));
            }

        };
        add(behaviour);

Pour accéder à l’url de ce Behavior, il suffit de procéder ainsi:

 behaviour.getCallbackUrl(true)

Ma première implémentation tourne nickel, même si je ne suis pas sûr de toutes les implications du booléen fourni pour obtenir l’url, dont la JavaDoc est:
* @param onlyTargetActivePage
* if true the callback to this behavior will be ignore if the page is not the last
* one the user accessed

Quoiqu’il en soit, au final, l’essentiel est dans la facilité avec laquelle tout cela est faisable. Finies la page et les lignes de code supplémentaires, ainsi que de passer des infos à travers tout ce petit monde. Ce Behavior résout tout cela joliment.

Bien sûr, l’intégration de JavaScript avec le côté serveur est toujours un travail conséquent, mais au moins Wicket fournit vraiment des outils efficaces pour cela !

🙂

++
joseph

PS: dans sa réponse, Richard parle également de l’intégration de jQuery dans Wicket, via le projet anciennement nommé wiQuery et récemment intégré dans wicketstuff-core en tant que « jquery » project. Quelqu’un l’a t il déjà utilisé ? Des retours d’expérience ?
PS2: Plus d’info sur Richard sur son blog Out for a duck, all about Wicket, sans nouvelle entrée depuis quelque temps malheureusement.

Étiquettes : , , ,

Camel case: comment gérer les acronymes et abréviations en majuscules ?

juillet 23, 2010 2 commentaires

[Article also available in English.]
Rapide article à propos d’un sujet qui s’est présenté plusieurs fois dans l’équipe: les acronymes doivent ils rester en majuscules lorsqu’ils font partie d’un nom en camel case ? Autrement dit, faut il écrire XMLFileName ou XmlFileName ?

Pareillement, que faire des abréviations? Si un composant concerne le Front Office, et que ce même Front Office est souvent référé en tant que FO (ou Fo), ce composant doit il être nommé FoFileName ou FOFileName ? Et un autre SomeDataFODisplay ou SomeDataFoDisplay ?

Bon, je l’avoue, ça parait un peu inutile comme discussion. On développe des logiciels, le choix des noms n’est pas forcément le plus critique. Ceci dit, avec Eclipse et son auto complétion prenant en compte le camel case, comme le dialogue d’ouverture de type, il est requis de savoir quelle est la convention retenue. Aussi, il suffit de se mettre d’accord au niveau de l’équipe et, à priori, basta.

Ceci dit, nous ne nous sommes pas penchés pleinement sur le sujet, vu qu’il est limite accessoire, et la solution retenue, frisant l’arbitraire, n’a convaincu personne. Aussi, je me suis dit que je devrai creuser un poil le sujet 🙂

Aussi, armé d’un redoutable éditeur de code, voici ce que je constate:

  • tout garder en majuscules:
    + colle au plus près des acronymes. C’est XML et pas xml après tout.
    – devient illisible quand des acronymes sont combinés. FOXMLRMIConfig est plutôt confus par exemple.
    – inapproprié pour les noms de variables. Comment gérer le commun « private Foo foo » ? Aller pour « private FOXMLData FOXMLData » ? Arg. « private FOXMLData fOXMLData » ? Encore pire ! « private FOXMLData foXMLData » ? Un peu mieux, mais toujours pas génial AMHA.
  • ne garder que la première lettre en majuscule:
    + les noms de variables deviennent naturels. « private FoXmlData foXmlData » a tout simplement l’air comme il devrait être.
    + Peut être combiné à volonté. FoXmlRmiConfig est lisible.
    – étrange au premier regard. Comme dit plus haut, c’est HTML et PDF, pas Html et Pdf !

Aussi, il semblerait que ne garder que la première lettre en majuscule soit la bonne solution.

Vu que je ne voulais pas ignorer l’état de l’art, j’ai essayé de trouver des recommandations officielles sur le sujet. Ma pêche a été maigre, seul Microsoft en fourni sur le sujet, à la page Capitalization Conventions, dans le paragraphe « Capitalization Rules for Acronyms ».

En quelque mots, le contenu peut être traduit et résumé à:

  • Abréviations:
    ne pas en utiliser sauf pour ID et OK, qui « dans des identifiant Pascal-cased devraient apparaitre en tant que Id et Ok. Utilisés en tant que premier mot d’un identifiant camel case, ils devraient apparaitre en tant que id et ok. »
  • Acronymes:
    – si longs de 2 caractères: les laisser en majuscules, « excepté pour le premier mot d’un identifiant camel case ». Ce qui veut dire d’écrire « private IOFile ioFile ».
    – si plus de 2 caractères, ne garder que la première lettre en majuscule, excepté pour le premier mot d’un identifiant camel case. Ce qui revient à « private XmlFile xmlFile ».

Cette règle des 2 caractères m’a pas mal surpris en fait. Cela peut sans doute aider à satisfaire tout le monde, ceux pour le tout majuscule et ceux pour l’autre option. Ceci dit, je trouve cela un peu exagéré. Et, franchement, « private DBXml dbXml » ne me semble pas des plus naturels.

Si vous avez la version Java/Sun/Oracle sur le sujet, je suis preneur 🙂

Au final, cette règle des 2 caractères me semble bien superflu. Perso, je reste sur la règle du « seule la première lettre en majuscule ».

Je suis preneur de toute opinion différente.

Allez, suffisamment dit (voir trop) sur le sujet: direction dodo !

++
joseph

Étiquettes : , , ,
%d blogueurs aiment cette page :