Vous aimez ce que vous lisez sur ce blog ?
Envie d'aller plus loin avec véritable formation d'expertise en Java ?
Venez suivre ma formation Masterclasse Expertise Java !

"Même un développeur experimenté a besoin de continuer à apprendre. Et dans cette formation... j'ai appris beaucoup !" - A.G., Java Champion

Sessions intra-entreprises sur demande : contact[at]mokatech.net.
Inscrivez-vous vite !

FooBarQix with a twist

A l'occasion de Devoxx FR 2012, David Gageot (@dgageot) et Jean-Laurent de Morlhon (@morlhon) ont proposé un atelier consistant à coder "en live" une application complète sur deux jours - oui, comme Notch au Ludum Dare :)

Pour sélectionner les participants et constituer des binômes cohérents, ils ont organisé un petit concours basé sur le kata "FooBarQix". Toutes les explications sont données sur le site code-story.net.

Evidemment, l'exercice est assez simple. Ce qui le rend intéressant, c'est la créativité des solutions soumises : tout est permis !

Pour ma part, je l'ai codé en Java (incroyable, hein ?). Mais avec une astuce ignoble : j'ai tout simplement hacké la méthode Integer.toString() grâce à du bytecode engineering. Oui je sais, c'est sale et ça pique les yeux, mais c'est ça qui est drôle !
Vous pouvez voir le code sur GitHub.

Making-of / Bêtisier

Au début, je pensais utiliser un agent Java pour instrumenter dynamiquement la classe Integer lors de son chargement. Mais celle-ci appartient à l'archive système rt.jar, qui est chargée avant l'agent. Raté.

Je me suis donc rabattu sur le bootclasspath. C'est le classpath système, contenant notamment rt.jar. En utilisant l'option -Xbootclasspath/p (notez le "p" comme "prepend"), il est possible de passer avant rt.jar, et donc de fournir ses propres classes systèmes.
C'est le principe utilisé par Terracotta, et certaines solutions de monitoring, qui ont besoin d'instrumenter les classes du JRE.

J'ai utilisé Javassist pour manipuler le bytecode et générer ma propre version de la classe Integer. Mais je me suis heurté à deux problèmes :

  • Javassist n'aimait pas ma boucle "foreach" ("for" amélioré), et refusait de compiler le code. J'ai mis du temps à trouver d'où venait le problème ! Une fois transformée en boucle normale, c'était bon.
  • Il est possible de se greffer au début ou à la fin d'une méthode pour ajouter du code, à la manière un aspect @Before ou @After, mais dans ce cas il est impossible d'accéder aux variables locales. Or, j'avais besoin d'accéder au tableau buf qui contient les caractères composant la String finale. J'ai donc dû remplacer intégralement le code de la méthode, en copiant/collant une partie du code original.

Conclusion

C'était bien amusant de bricoler la classe Integer pour implémenter le kata FooBarQix.
J'espère avoir trouvé une solution inédite (on verra au dépouillement des réponses), même si elle n'est pas spécialement élégante ni recommandée pour la mise en prod...

En tout cas, c'est toujours bénéfique de se pencher quelques heures sur un exercice inhabituel, ça entretient le "muscle de la programmation" : le cerveau !


Commentaires

1. Le mardi 17 avril 2012, 15:57 par moulou

Chapeau!

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.