Hier soir … c’était le printemps ?

Parce qu’hier soir, c’était chtijug, chtijug spécial Spring, et Spring boot en particulier

Pour laquelle Brian Clozel a fait un gros boulot de livecoding.

Alors Spring Boot, qu’est-ce que c’est ?

Eh bien c’est tout ça

D’après ce que j’ai compris, c’est une façon pour les gens de Spring de simplifier la vie des développeurs en fournissant

  1. Une façon très chouette de bootstrapper une application à partir de leur site web.
  2. Un framework d’utilisation de l’ensemble des couches Spring, qui inclut évidement le code, mais aussi les bonne spratiques d’utilisation
  3. Une interface « simplifiant » l’utilisation des autres bibliothèques de Spring.

En revanche, Spring Boot n’est pas une version simplifiée de Spring (tout Spring peut être utilisé dans Boot), ni un outil à réserver aux POC.

Donc, brian nous a fait du live-coding. Et sans utiliser cette cochonnerie de thème sombre illisible. Et ça c’est bien.

On a donc pu voir en action

  • Spring-data-mongo
  • Spring-rest (je reviendrai plus bas là-dessus)
  • Spring-security

Et quelques autres.

Au passage, j’ai beaucoup apprécié la façon d’utiliser les TODO de Brian, qui lui permettait de dérouler dans un ordre sympatoche les différents éléments de sa démo.

Il a ensuite fait une rapide présentation des différentes nouveautés de Spring 4.1 (en oubliant de préciser que certaines ne fonctionnent qu’avec java 8, comme par exemple les injections de types paramétrés).

Sauf que …

Comme le dit fort bien Thibaud

Pour clarifier un peu … J’ai fait du Spring il y a maintenant 8 ans. A l’époque, on était en plein XML hell, et Spring en était le champion. Des fichiers XML partout, avec des beans à câbler dans tous les coins, c’était l’enfer. Et je me souviens en particulier à l’époque d’un aspect pénible de Spring, qui était le fait de devoir toujours passer par la doc pour obtenir des infos : rien n’était découvrable automagiquement dans l’IDE.

Aujourd’hui, le XML Hell a été remplacé par l’annotation hell. Et honnêtement, ça ne change rien au problème : on ne sait toujours pas quel bean vient de quel endroit, et qui est injecté où.

Vous serez tenté de me dire que c’est exactement pareil dans le JavaEE d’en face, et vous aurez raison. Cependant, dans le monde JavaEE, j’ai l’impression qu’il existe une distinction plus claire entre les différents types de composants : les EJBs, les beans sont plus facilement définis, et mieux isolés. Enfin, je trouve.

Spring-data a tout copié sur gaedo ?

Quoi ? Vous ne connaissez pas gaedo , La meilleure librairie de mapping objet/stockage en Java ?

Je n’ai pas pu m’empêcher d’y penser quand j’ai vu cet écran

IMG_20150203_192539

Que vous pouvez comparer avec la doc de gaedo sur les finders dynamiques… Ouaip, c’est pareil. Et ouaip, on a tous copiés sur Ruby on Rails.

Oui mais Spring boot, c’est léger ?

Comparez par exemple avec DropWizard (comme l’a fait JavaLobby), à Wisdom ou à ninja … Dans tous les cas, Spring boot apporte effectivement la légereté de ces outils en s’appuyant sur la force de Spring. Mais du coup, c’est loin d’être aussi léger que ce que vous croyez : mettre en place un stockage va impliquer l’utilisation de Spring-data-*, qui va vous tirer des tonnes de dépendances, et il en sera de même pour implémente rune API REST : vous passerez par la librairie idoine du portfolio Spring à travers une couche d’adaptation, et du coup ce ce sera encore une fois un gros paquet de dépendances, et une complexité pas forcément masquée.

Conclusion

Donc une session intérressante, sur un des frameworks majeurs du monde Java, mais qui n’en était pas pour autant exaltante. Et c’est bien normal : Spring est une solution mature, déployée à des échelles industrielles, et dans des environnements qui n’ont rien de glamour. Ils ne cherchent donc pas à épater les utilisateurs, mais plutôt à trouver une solution qui marche, et qui réponde sérieusement aux problèmes des applications d’aujourd’hui.

Français, vous me dégoûtez

J’espère que le titre est assez clair.

Après les attentats du début du mois, j’ai cherché désespérément comment écrire que, comme d’autres, je n’étais pas Charlie.

Hélas, je n’ai pas trouvé.

Mais aujourd’hui, ma colère contre cette récupération idéologique est … incandescente.

Parce qu’il n’a pas suffit de commémorer la liberté d’insulter … pardon, d’expression, en invitant un ramassis d’amis de cette liberté (du moment que les opinions leur plaisent, évidement).

Il n’a pas suffit non plus de commémorer cette même liberté de haïr … pardon, d’exprimer la franchouillardise, en remettant des militaires dans la rue. Au passage, je ne résiste pas à deux appartés à ce sujet.

Vous savez que les militaires disposent d’armes incomparablement plus dangereuses que les flics ou les gendarmes ? Mais est-ce que vous connaissez les différentes règles d’engagement ? Pour ce que j’en sais, ça me terrifie. Parce qu’un militaire peut ouvrir le feu bien plus facilement qu’un policier. Et qu’un FAMAS a une portée incroyablement plus grande qu’un pistolet, fût-il automatique.

En bonus, je sais pas vous, mais moi, personnellement, voir un plan de défense relevé après l’attaque, ça me paraît aussi utile qu’une capote enfilée après l’éjaculation …

Bref, revenons à notre sujet pas joyeux.

La liberté d’expression a donc été défendue en invitant ses pires détracteurs, en mettant en place une politique visible d’intimidation des citoyens. Et c’est tout ?

Non. C’est encore pire.

La liberté d’expression a été défendue en punissant pénalement des enfants qui s’expriment.

Lisez donc ces deux articles

Et maintenant, essayez de vous regarder dans un miroir. Personnellement, j’ai beaucoup de mal à croire vivre dans un pays qui respecte la liberté quand je lis ça.

Et plus encore quand je vois les hommes politiques de mon pays se satisfaire de marquer des enfants à vie.

Quand je vois ça, je pleure.

Et c’est encore pire quand je compare la réaction française (raciste, hypocrite, mesquine) aux réactions d’autres pays, où la fraternité avait du sens.

Honnêtement, j’ai rarement eu autant envie de quitter ce pays qui sent le rance qu’en ce moment. Et ce qui provoque ce dégoût, ce ne sont pas quelques terroriste imbéciles, mais tous les carriéristes amateurs de dictature beige. Et oui, c’est peut-être, de ma part, une réaction allergique à la réaction allergique de notre pays que mentionne Maître Eolas.

Une étincelle au chtijug

Et c’est reparti pour un tour, cette fois-ci sur du Big Data, je crois …

J’avais entendu parler de Spark dans l’interview de Sam Bessalah chez les castcodeurs, et Duy Hai Doan est venu préciser les idées.

Et Duy Hai a été sympa pour rendre les slides disponibles sur le web

Ainsi que sa présentation pour Spark avec Cassandra

En nous expliquant d’abord que Spark est bien plus concis que Hadoop (en partie parce qu’en Scala), et bien plus rapide (parce que stockant ses données en mémoire, plutôt que sur disque, comme Hadoop). En bonus, Spark traite les données en graphe (d’ailleurs, de façon amusante, Blueprints n’est pas listée dans les API de graphe Big Data), en SQL, ou via des flux.

Cool, non ?
Petit détour par les RDD, qui reprennent, conceptuellement, ce que toute personne ayant implémenté un processeur de requête comprendra : il n’interprète les requêtes qu’au dernier moment. Par exemple, un filter suivi par un groupBy ne sera évalué que si, à la fin, l’utilisateur du RDD tente de récupérer, d’une façon ou d’une autre, les données sur son poste. D’une façon intéressante, certaines opérations vont redistribuer les données sur le réseau (typiquement, un groupBy) à cause de notions compliquées de « hashcode » de données. D’ailleurs, curieusement, on ne distingue pas les opérateurs impliquant un brassage (groupBy) des autres, ni d’ailleurs des actions démarrant le processus. Et personnellement, je trouve ça moche pour une raison bien simple : le développeur peut (et va) écrire du code inefficace, simplement parce qu’il ne saura pas comment distinguer le code efficace du code inefficace.
On passe ensuite aux API.

Spark supporte le SQL, le streaming, et le mapping d’objets. Pas mal … Sauf bien sûr qu’il y a toujours ces histoires de redistributions de données temporaires, que je vois come le vrai défaut de Spark. Je m’explique …

Comme les opérations brassant les données peuvent les envoyer n’importe où, si on en écrit « par accident », on risque de passer d’un code très rapide (parce qu’en mémoire) par un code très lent (parce que sur le réseau). Et Spark ne fournit aucun moyen de distinguer les deux, malheureusement.

Et ça empire si on utilise Cassandra comme couche de stockage, à cause de la nature multi-datacenter de l’outil, qui va certes permettre de survivre à des accidents nucléaires, au prix de coûts de transferts de données.

Pour troller, Spark, c’est bien, pour faire du SQL distribué.

Ré-réinstaller fonz_fun_plug

Parce que j’ai rebooté mon NAS, et depuis, j’ai perdu

  • l’accès SSH
  • Lighttpd
  • minidlna

Heureusement, je peux toujours y accéder en « vrai » FTP et consulter le ffp.log qui me dit des choses aussi absconses que

* /ffp/start/uwcron.sh ...
wc: can't resolve symbol 'posix_fadvise64'

ou

* /ffp/start/sshd.sh ...

/ffp/bin/ssh-keygen: symbol '_res': can't resolve symbol

/ffp/bin/ssh-keygen: symbol '__stack_chk_guard': can't resolve symbol
tr: can't resolve symbol 'posix_fadvise64'
Starting /ffp/sbin/sshd 

/ffp/sbin/sshd: symbol '__stack_chk_guard': can't resolve symbol
* /ffp/start/rsyncd.sh inactive

Préferrant la brutalité à la subtilité, je vais donc réinstaller fonz_fun_plug 0.7. Heureusement que j’ai déja détaillé les étapes.

Donc allons-y …

(je démarre à 11H00)

Au passage, je lis dans mon article de référence

You may select to upgrade system package by packages from other repositories, but it may bring some system instability. Do it at your own risk …

Ouais, ben j’aurais dû le mettre dans une espèce de welocme message …

(et à 11H22, ffp est réinstallé, et je redémarre pour vérifier que les modifs fonctionnent – et oui, ça marche).

Par contre, dans la partie

Installer ensuite toutes les libs de minidlna, puis minidlna

Bêtement, je n’ai pas noté la liste des « libs de minidlna » … heureusement, une rapide recherche sur « kylek minidlna » me donne cette liste :

  • libjpeg-8c (system)
  • flac (kylek)
  • ogg (kylek)
  • vorbis (kylek)
  • libid3tag-0.15.1b (kylek)
  • sqlite-3.7.9 (system)
  • libexif-0.6.2 (system)

Et ça ira !

Avec ça, minidlna redémarre correctement.

J’ai en revanche un petit souçi avec lighttpd … mais je vais arranger ça rapidement …

Donc, si après le démarrage de lighttpd, je ne vois rien dans mon navigateur internet, je dois aller jeter un oeil dans /mnt/HD_b2/www/logs/error.log pour y trouver des erreurs comme par exemple

2015-01-10 18:36:22: (mod_fastcgi.c.1103) the fastcgi-backend /ffp/bin/php-cgi failed to start:
2015-01-10 18:36:22: (mod_fastcgi.c.1107) child exited with status 16 /ffp/bin/php-cgi
2015-01-10 18:36:22: (mod_fastcgi.c.1110) If you're trying to run your app as a FastCGI backend, make sure you're using the FastCGI-enabled version.
If this is PHP on Gentoo, add 'fastcgi' to the USE flags.
2015-01-10 18:36:22: (mod_fastcgi.c.1397) [ERROR]: spawning fcgi failed.

Et donc, je n’ai pas dû installer la bonne version de PHP …

Bon, en fait, c’est pas ça : quand je tape php -v, j’obtiens ça

php: can't load library 'libcurl.so.4'

Normal, puisque curl n’est pas installé.

Donc il faut installer curl avant de tenter d’utiliser du php !

J’ai donc maintenant un lighttpd+php qui marche à peu près (suffisament en tout cas pour jtartQage). En revanche, pour krissfeed ou Shaarli, j’ai toujours des erreurs

Fatal error: Call to undefined function gzinflate() in /mnt/HD_b2/www/pages/Shaarli/index.php on line 773

Qui sont liées, d’après internet à … des problèmes curieux de zlib (que j’ai pourtant installée).

Bon, en fait non, c’est juste parce qu’il ne faut pas oublier de copier le php.ini qui est sauvegardé sur GitHub !

Cinq ans d’ALM, putain !

Encore une suite à cinq ans, putain !

Oui, je mets le terme ALM à toutes les sauces, parce que c’est mon bon plaisir.

Donc, sur ce gros projet, j’ai fait ce qu’on pourrait de l’ALM. Qu’est-ce que je mets sous ce terme ?

L’ensemble des tâches qui permettent de passer du code au produit.

Ca inclut, de façon non exhaustive

  • Les outils de build
  • Les outils d’intégration continue
  • L’intégration entre ces outils et les outils de suivi de bugs.

Et évidement, je vais vous (re)parler de Tuleap.

Mais avant, je vais reprendre les étages un par un

Compiling !

Aimablement fourni par http://xkcd.com/303/ mais vous vous en doutiez, non ?

Quand on a commencé notre projet, j’avais déja touché du build maven multi-module. Maias je n’imaginais pas que j’en ferais autant, puisque notre build intègre maintenant

  • De la compilation flex avec flexmojos (raisonnablement facile)
  • De la compilation C++ … et selon la plateforme, cette compilation utilise soit Visual Studio, soit XCode … alors ne me parlez pas de maven-nar-plugin, parce qu’il est notoirement insuffisant pour nos besoins.
  • Du packaging sous d’innombrables formes (war, ear, zxp, …)

Qu’est-ce que ça m’a appris ?

It’s alive

Que la vraie force de maven n’est pas la création d’un format de dépendance universellement utilisé.

Je veux dire, c’est vrai que c’est pratique, ces dépendances, mais quand on arrive à du build « d’entreprise », c’est-à-dire moche et farci de profils, la vraie force de maven, ça n’est pas ça. Non.

La vraie force de maven, c’est de définir un cycle de vie universel. Parce que ce cycle de vie permet, quelquesoit le type de projet, le langage utilisé, ou quelque concept que ce soit, de positionner les différentes opérations dans un tout cohérent. Ca n’a l’air de rien, comme ça, mais c’est réellement indispensable pour les gens qui s’occupent de faire un packaging réaliste. Parce que je sais, quand j’en arrive à la phase « packaging », que tout mon code est compilé, testé, que les ressources ont été traité.

Franchement, quand je regarde les alternatives à maven, je me dis qu’ils n’ont rien compris : ne pas reprendre ce cycle de vie, c’est juste irresponsable maintenant.

Groovy, baby

Alors évidement, vous me direz qu’écrire un plugin maven pour les cas non standard, c’est l’enfer. Et c’est vrai.

Heureusement, j’ai également découvert une gradation dans la personnalisation que j’applique de façon systématique (vous savez, pour tous ces trucs foireux – comme par exemple construire un fiochier de config requirejs à partir de dépendances Javascript) :

  1. Je trouve un plugin maven qui convient ? C’est la fête
  2. Je trouve un ensemble de tâche ANT qui colle ? Cool
  3. Je peux écrire un script groovy avec gmaven ? Bien (dans ce cas-là, n’écrivez pas le script dans le build, mais mettez-le dans un dossier clairement séparé, par exemple src/build/gmaven)
  4. Aucun des trois n’est suffisant ? Alors il est temps d’écrire un plugin maven.

Avec ça, rien n’est impossible dans un build.

Et notez que je ne suis passé du point 3 au point 4 que dans deux cas. Et dans les deux cas, c’est parce que je devais en fait écrire un plugin avec cycle de vie complet. Dans tous les autres cas, groovy a été suffisant, et je dirais même fun.

Non mais tout ce XML, quand même …

Tout ce XML de maven ? A priori, on le regardait sous tes les angles dans m2e quand on ajoutait un nouveau type de build, et après, il n’y avait plus vraiment besoin d’intervenir dessus. Alors dire que c’est pénible, faut pas déconner. Le pire, en fait,a vec maven, c’est qu’Eclipse ne différencie pas les scopes des dépendances. Heureusement pour nous, Jenkins compilait en-dehors de tout IDE.

Make me a sandwich

Et encore, on n’a pas besoin de sudoer Jenkins

Ben oui, Jenkins, le gagnant de la grande guerre du fork.

Lui aussi, on l’a bien tanné.

Justement à cause de notre build natif multi-plateforme. Parce que si on compile une partie de notre application selon la plateforme, on fait comment pour avoir les artefacts dans un build commun ?

Eh bien on se fait un profil spécial Jenkins, dans lequel le build maven est découpé en parties multi-plateformes et dépendant de la palteforme, et on joue du build matrix plugin pour que tout compile et se package sans problème.

Et ça marche, mpême si c’est pas très facile.

Ca chauffe !

A vrai dire, le plus grand échec a été l’implication de l’équipe : même avec un bon radiateur, personne (sauf la testeuse en chef – que toujours elle marche sur un chemin de roses fraîchement coupées) ne s’y est jamais vraiment intéressé. Et ça, c’est triste.

Parce que ça veut dire que cette histoire d’intégration continue n’a été qu’une lubie de ma part, et que je n’ai pas réussi à en communiquer la valeur pour l’équipe, le projet, le produit.

Là-dessus, je peux dire que je retiens la leçon, et que je ferais en sorte que les builds en échec ne puissent plus être ignorés.

Tester c’est douter

Cela dit, tout n’est pas si sombre, puisque le projet a quand même une bonne partie de son code testé, et que TDD a été utilisé dans la plupart des acceptations du terme. La meilleure, et la plus efficace étant qu’aucun bug ne devait être marqué corrigé sans qu’un test ait été ajouté spécifiquement. Parce que

ce qui a foiré foirera

Ca a l’air con dit comme ça, mais ça c’est vérifié à chaque fois : les parties de code ayant connu un bug en ont toujours connu plus, et plus encore.

Heureusement qu’il n’y avait pas d’exploitation statistique des liens entre code et bugs pour vérifier ça, sinon c’aurait été l’enfer.

Et mylyn ? Et Tuleap ?

Là, par contre, l’échec est patent.

Plus encore quand je regarde ce que j’ai pu faire avec gaedo où, là, chaque bug est corrigé à travers un commentaire de commit.

Imaginez que le seul lien dont on ait pu dispoiser était, éventuellement, un lien HTTP dans un commentaire de commit référençant un bug. Comme ça, par exemple :

http://mantis/bugs/view.php?id=7137
the error was stupid : I did not add children to parents when they were needed

ca, c’est moi qui l’ait écrit aujourd’hui.

Ce qui est bizarre, c’est que j’avais parlé de mylyn, de Tuleap, et qu’un autre collègue avait parlé de svn commit hooks … mais aucune de ces tentatives n’a pris. Et pour des raisons diverses … La pire étant celle qui nous a empêché d’utiliser Tuleap : « j’ai pas vraiment eu le temps de regarder ». je dois dire que ça, ça m’a tué.

Alors, content ?

En fait, la plupart des choses installées vont continuer à fonctionner … jusqu’à ce qu’on les arrête.

En revanche, je reste convaincu de l’intérêt de ces outils, et je n’hésiterai pas à pousser leur adoption la prochaine fois.

Cinq ans de projet, putain !

TL-DR

Dans une série d’article commençant par cinq ans, putain ! j’essaye de faire un post-mortem d’un projet d’environ 5 ans de dév. Là, je vais vous parler gestion de projet. Ca n’est peut-être pas mon rôle, mais j’y ai trempé un peu.

Ouaip, bosser sur le même projet pendant cinq ans, c’est long.

Quand on a commencé ce fichu projet, on s’est dit que ce serait bien de faire de l’agile plutôt que du n’importe quoi, comme c’était auparavant l’usage dans la boîte.

Du n’importe quoi ?

Oui : sur la première année, j’ai aidé mes collègues à finir de livrer une version du logiciel historique dont la date de livraison initiale était … avant mon arrivée dans l’entreprise. Et en fait, il a fallu toute la première année pour livrer.

Et encore, on a gagné du temps en

  • mentant pendant les comités de pilotage
  • virant la moitié des fonctionnalités
  • introduisant des gros hacks pour que ça marche

Est-ce que c’était intellectuellement satisfaisant ? Bien sûr que non. Surtout que de l’agile qui marche, j’ai déja vu ça il y a bien des années. J’étais donc plutôt déterminé à assister mon mentor local dans cette transition.

Allez on commence les assouplissements

La première chose qu’on a mis en place, curieusement, c’est un pipeline d’intégration continue. Et ça a bien marché. Parce que ça nous permettait de ne plus stresser (trop) autour des livraisons. Bien sûr, des gros paquets de code foireux ont été livrés, et des retards conséquents ont été pris. Mais le fait de disposer chaque jour d’un build complet était (et est toujours) une satisfaction profonde, parce que ça donne une existence « concrète » au produit qu’on développe.

Et puis il a fallu s’intéresser à l’amont. Les user stories, les tâches, les sprints et toute cette terminologie que je trouve rétrospectivement inutile et qui n’a en fait pas marché. Je vais essayer d’éclaircir.

Donc, on a essayé de faire du scrum (qui comme chacun le sait, est une forme d’agilité) et, à cause de notre équipe moitié intégrée, moitié distribuée, on a dû gérer nos tableaux avec un outil (qui n’est pas en cause ici).

Raconte-moi une histoire – le backlog et les stories

Evidement, dans ces tableaux, la première entrée, c’est le backlog, et dans ce backlog, on trouve les stories de notre client (en l’occurence, le marketting). Et c’est là qu’est le premier problème : faire du marketting, et réussir à exprimer un besoin, c’est loin d’être simple. Et les personnes qui s’en sont occupées n’ont sans doute pas été formées à cette tâche (mais ça, ça reviendra souvent). Du coup, on a pu rencontrer, malgré le formalisme assez classique « En tant que …, Pour …, Je voudrais .. » des problèmes assez pénibles :

  • Toutes nos stories avaient comme rôle « l’utilisateur ». Du coup, impossible de dégager différents sous-sytèmes ou autorisations qui auraient pu clarifier les choses. En fait, il a fallu attendre que le projet ait déja 4 ans pour voir émerger différents rôles.
  • Il n’y avait que rarement des demandes, et bien plus souvent des solutions … dont le réalisme prétait évidement le flan à la critique.
  • Il était également  courant de voir le contenu du backlog totallement transformé d’un sprint au suivant, essentiellement parce que le marketting avait rencontré un client avec d’autres besoins

Des défauts pénibles, donc, que je regrette vraiment de ne pas avoir tenté de corriger, d’une façon ou d’une autre.

Qu’est-ce qu’il aurait fallu améliorer ?

Notre marketting n’a jamais compris ces histoires d’agilité : pour eux, il fallait « juste livrer ». Du coup, leur expliquer que donner des rôle bien définies était difficile. Pour ça, je pense que l’approche des personaes aurait été bien pratique : mettre un nom, un visage, pour que,v raiment, les différents rôles apparaissent clairement.

De la même manière, la fourniture de solutions complètes (mais toujours incorrectes) aurait sans doute nécessité de notre part plus d’accompagnement initial, pour vraiment comprendre le besoin sous-jacent plutôt que l’implémentation proposée.

Il est chouette, ton jouet … il fait quoi ?

Cela dit, on disposait de nos stories, qu’on traduisait en paquets d’items, ce qui nous paraissait correct, jusqu’à la première fin d’itération.

Oh, oui, pardon, je parle d’itération … sans doute parce que nos sprints avaient dépassé les 6 mois, ce qui les rend assez … peu courts, dirais-je.

Et donc, à la fin d’une itération, on fait deux choses :

  1. une démonstration
  2. une rétrospective

Deux occasions d’être fier de son travail … ou pas.

Ca tourne !

La démonstration … l’occasion pour l’équipe de briller devant le marketting. Qu’est-ce qui pourrait foirer ?

Oh, plein de choses (que j’ai vu, hein)

  1. Des développeurs qui ne préparent pas de démonstration, et ne s’attendent même pas à en faire, alors que leur développement est releasé
  2. Des démos qui foirent
  3. Un marketting qui profite de la réunion pour parler d’autres parties de l’application (qui n’ont reçues aucun développement, donc)
  4. Un autre marketting qui profite lui aussi de cette réunion pour râler sur cette équipe de dév qui est toujours en retard

Et quand je dis que je les ai vues, je veux dire que je les ai toutes vues dans la même démo. Alors forcément, à la fin de la démo, l’équipe est … peu satisfaite, pour dire le moins.

Qu’est-ce qu’il aurait fallu améliorer ?

La préparation de la démo, évidement. Il aurait fallu demander à toute l’équipe si les démos étaient prêtes, et testées. Et j’insiste d’autant plus sur le second point que j’ai moi-même foiré une démo parce que je l’avais insuffisament testée. Pour le premier point, je dois bien avouer que la seule façon de s’assurer que les gens préparent une démo est de les laisser se vautrer sur scène au moins une fois.

Pour le marketting, là, c’est simple, parce que je l’ai fait la fois suivante : il ya  un ordre du jour clair à cette réunion, et si certains veulent s’en écarter, c’est à l’animateur d ela réunion (moi, sur ce coup-là) de les recadrer, ce que j’ai fait.

Et dans les coulisses

Parce qu’il y a un pendant interne à cette démo : la rétrospective.

Personnellement, j’adore ce moment où on peut tenter de proposer de nouveaux modes d’organisations.

Par exemple, c’est lors d’une de ces réunions que j’avais proposé qu’on utilise Tuleap … mais j’en reparlerais.

Bref, là aussi, c’est une réunion qu’il vaut mieux préparer …

Et comme vous devez vous y attendre, j’ai eu quelques réponses comiques aux trois questions rituelles.

Vous savez :

  1. Qu’est-ce qui a bien marché ?
  2. Qu’est-ce qui n’a pas bien marché ?
  3. Qu’est-ce qu’on peut améliorer ?

Et l’ordre est important : commencer par ce qui a bien marché permet normalement aux gens d’avoir un étatt d’esprit positif … enfin, normalement.

Mais avant d’en venir aux insultes internes, une petite astuce offerte

Tout ça, c’est la faute à Raoul.

Lors de la rétropsective, regardez bien la deuxième question : c’est la porte ouverte aux réglements de compte. Pour les éviter, l’astuce est simple, on avait une persona de mauvais développeur : Raoul Abdaloff (le nom ne doit rien au hasard, et tout à l’UMP). Et tout ce qui s’est mal passé est de sa faute. Une fois muni de ce mauvais développeur, qu’est-ce qui peut foirer ?

Tout va mal, et rien ne s’améliorera

Dans l’ensemble, ces réunions se passaient bien. Jusqu’à ce jour funeste, où trois collègues ont répondu dans un bel ensemble

Qu’est-ce qui a bien marché ?

Je sais pas

Qu’est-ce qui n’a pas bien marché ?

Tout

Qu’est-ce qu’on peut améliorer ?

Rien

Là, faut être lucide, parce que les mecs, j’ai bien eu envie de les passer par la fenêtre.

Qu’est-ce qu’il aurait fallu améliorer ?

Pour la rétropsective, pas grand chose, puisque le but du jeu était d’améliorer le processus. Et ça marchait bien !

Du coup au bout de cinq ans c’est le top ?

J’ai déja parlé du dépôt de bilan, non ?

Eh bien on peut dire que ça a tout détruit.

Aujourd’hui, il n’y a plus

  • de démos
  • de rétrospectives
  • de sprints
  • d’agilité
  • d’envie

Ca calme, non ?

Mais pourquoi ?

Au fond, l’agilité, le scrum, le lean, le kanban, tout ça, c’est mignon, mais c’est juste un mensonge.

Parce qu’en fait, ces idées se contentent de dire qu’il faut que les personnes aient envie d’améliorer leur mode de travail pour que leur mode de travail s’améliore … Autrement dit, ça permet plus de canaliser l’enthousiasme de jeunes chiens fous que de remotiver des vieux développeurs dont la culture sectaire a réduit l’enthousiasme a néant.

Et, je regrette de le dire, même mon enthousiasme a disparu dans la bataille (d’un autre côté, c’est aussi pour ça que je m’en vais).

Du coup, si je peux me permettre un conseil aux apprentis agilistes, ou à ceux qui se demandent pourquoi leur processus agile est arrêté au bord de la route : regardez vos développeurs, et vos « clients ». Est-ce qu’ils sont motivés ? Est-ce que ça leur plaît ? Est-ce qu’ils ont envie de faire mieux ? Si ça n’est pas le cas, laissez tomber tout ça, et contentez vous de faire des itérations courtes, et de durée fixe. Parce que ça, le rythme, ça aide aussi beaucoup. Et le perdre, souvent, c’est un signe que quelque chose d’autre ne va vraiment pas.

 

Ch’mongoDB

Eh ouais, hier soir, c’était chtijug sur MongoDB avec Tugdual Grall.

Mais avant, minute copinage …

Le chtijug a la chance d’avoir un nouveau sponsor, et ça, c’est cool (d’autant plus que ce sont mes voisins de bureau jusqu’à ce soir) :

IMG_20141217_185256[1]

Le représentant d’Onyme a peut-être un moins chouette polo que certains précédents sponsors, mais un sacrément chouette discours

Et je me suis laissé dire qu’ils recrutaient

Bref, merci les gens !

Revenons-en donc à Tugdual

IMG_20141217_185548[1]

Oracle, eXo, Couchbase, MongoDB … clairement, le développeur un peu âgé a souvent touché à plein de trucs

Même fatigué, c’est un speaker sacrément rodé qui nous a fait une présentation intéressante, bourrée de live-coding, sur MongoDB.

Alors MongoDB, qu’est-ce que c’est ?

IMG_20141217_190640[1]

Mongo, une base agile, flexible, intituive et stockant les données dans un format facile à exploiter

En gros, c’est une espèce de gros système de stockage de BSON (un format binaire adaptant le JSON) disposant d’interfaces dans les différents langages … mais ça n’est pas ce que racontait vraiment ce slide moche.

Non. Ce que voulait expliquer Tugdual, c’est que les bases de données relationelles datent de 40 ans, à une époque où l’esapce disque coûtait vraiment cher. Et donc à cette époque, l’optimisation la plus importante concernait l’utilisation du disque. D’où les bases relationenlles où la donnée est forcément unique, et en troisième forme normale.

C’est pratique pour les DBA, parce que la donnée est bien structurée.

C’est en revanche infernal pour le développeur, puisque la donnée n’est pas accessible facilement. Ce qui explique, par exemple, l’intérêt pour les outils de mapping objet-relationnel.

Un autre inconvénient du fait qu’une écriture se fasse à de multiples endroits, c’est que l’écriture nécessite d’être encapsulée dans une transaction, qui est lourde en termes de ressources pour le serveur (et donc impactant l’ensemble des clients).

A l’opposé, MongoDB cherche à être une base de stockage agréable pour les développeurs.

Ca veut dire quoi ?

  • MongoDB stocke des documents en JSON, qui peuvent contenir des champs simples ou des tableaux de tableaux de tableaux (avec toutefois des limites … qui me semblent assez difficiles à atteindre à première vue).
  • Si deux documents doivent contenir chacun la même donnée, il peut être plus simple de dupliquer cette donnée … ou de la référencer (mais dans ce cas, c’est le développeur qui gèrera l’unicité du lien)
  • Du coup, comme le document est complet, il n’y a pas vraiment besoin de transactions : soit il est écrit, soit il ne l’est pas, mais le développeur le sait tout de suite. Donc MongoDB est non transactionnel, et ça n’est pas grave.

Et paf, Tugdual enchaîne sur une démonstration de la « convivialité » du shell mongo.

insertion d'un document dans la collection "customers", et récupération de la liste des "customers"

insertion d’un document dans la collection « customers », et récupération de la liste des « customers »

Et là, c’est le drame : comme le shell Mongo n’offre ni complétion, ni mise en valeur de la syntaxe, et que Tugdual était un peu fatigué (mais ça, je comprends, parce que coder à l’heure de l’apéro, c’est loin d’être facile), les accolades oubliées s’enchaînent en rafale

Ami lecteur, trouve l'accolade manquante ... Ouaip, c'est lioin d'être facile

Ami lecteur, trouve l’accolade manquante … Ouaip, c’est lioin d’être facile

Notez que je ne critique pas Tugdual, mais le shell mongo. Peut-être qu’un outil comme Robomongo, mongodb-shell ou même l’un des innombrables plugins Eclipse aurait pu lui faciliter la vie. Mais je comprend qu’en tant qu’évangéliste Mongo, ça lui soit un peu difficile d’utiliser des outils tiers.

Bref. Après l’insertion, une autre chose intéressante : la seule chose que doivent avoir les documents Mongo, c’est un attribut « _id » qui peut être soit généré (à partir de l’adresse Mac, du numéro de process, et du timestamp unix), soit écrit manuellement. Et il se passe quoi quand un utilisateur essayé de créer un nouveau document avec un _id déja utilisé ?

Si j'essaye d'avoir deux documents avec le même _id, j'ai droit à une jolie erreur

Si j’essaye d’avoir deux documents avec le même _id, j’ai droit à une jolie erreur

Bon, maintenant que j’ai bourré la base, il est temps d’y chercher des trucs.

Et là, franchement, pour moi, c’est le moment du malaise.

Parce qu’autant je veux bien comprendre l’intérêt des documents en JSOn, des réponses du serveur en JSON mais quand Tugdual a fait ses query/update avec du JSON pour

  • rechercher les documents à mettre à jour
  • définir les opérations d’altération à effectuer (modification, suppression, insertion)

Je dois avouer que j’ai eu comme un malaise

Regardez donc :

Une opération simple de recherche et mise à jour, avec un paquet de JSON dedans

Une opération simple de recherche et mise à jour, avec un paquet de JSON dedans

Et si ça ne vous paraît pas assez clair il y a évidement de la doc sur internet.

Je vais quand même essayer de clarifier mon malaise : il me semble que tous les paramètres de toutes les opérations sur une base MongoDB sont passés sous forme de JSON. Et c’est quelque part assez bien.

Toutefois, tenter d’exprimer une recherche et une mise à jour sous cette forme paraît assez bizarre, surtout vu quelques choix faits (et présentés ici)

  • Les opérations de MongoDB sont définis dans les paramètres sous forme d’attributs JSON préfixés par « $ » alors n’allez pas utiliser ce caractère magique dans vos données !
  • Si vous cherchez au fond d’un sous-document, il faudra passer votre chemin de recherche dans une chaîne (parce que « . » n’est pas accepté comme clé dans un hash JSON). Du coup vous aurez certaines clés avec des guillemets autour et d’autres sans. Et vous vous demanderez d’où vient l’inconsistence.
  • Si vous cherchez dans un tableau une valeur ayant plusieurs propriétés, ce sera … un peu plus compliqué.

Bref, je peux le reconnaître, je n’ai pas aimé cette syntaxe, bien qu’elle soit extrêmement déclarative.

Bon, une fois arrivés là, il est temps de sortir du shell et de passer au driver Java, qui se présente sous plusieurs formes (au passage, il y a des tonnes de drivers, listés dans une très belle page – dixit Tugdual) :

  • Un driver basique qui vous fait manipuler des DBObject qui sont en fait une vision javaisée et fluente des documents JSON. Au apssage, ce driver fournit un chouette outil de création de requête : QueryBuilder.
  • Morphia, qui est un ODM qu’on pourrait considérer comme un concurrent d’Hibernate OGM ou de Spring Data, mais spécifiquement conçu pour MongoDB.
  • MongoJack qui utilise les annotations de Jackson pour mapper les objets Java sur les documents JSON.

Petite parenthèse : le style Dracula d’Intellij ne m’a paru super lisible …

Et pourtant j'étais au deuxième rang ...

Et pourtant j’étais au deuxième rang …

Une fois ces différents outils présentés, Tugdual nous explique, à travers un exemple d’application web, comment utiliser tout ça au mieux.

D’après lui, et plus j’y pense, plus j’approuve, la meilleure solution et d’utiliser le driver basique pour les lectures, et les mappers pour les écritures. Et la raison est assez simple :

En lecture, on passe le JSON de Mongo jusqu’au client … typiquement écrit en Javascript, et donc parfaitement capable de lire ce Javascript.

En revanche, en écriture, pour contrôler ce qui est écrit dans la base, on a intérêt à passer par un mapper. MongoJack a ma préférence … surtout que, contrairement à Tugdual, je sais lui faire ignorer les propriétés inconnues (en utilisant par exemple la DeserializationConfig).

Une fois ce tour du dev fait, Tug est passé au clustering … Bon, là, c’est assez classique : il y a du sharding, de la haute disponibilité via l’élection automatique d’un master … La routine, en quelque sorte.

Et il était déja l’heure du …

Ouaip, Onyme sait toujours aussi bien recevoir !

Et alors, est-ce que je vais passer à MongoDB ?

Bon, j’ai failli il y a peu travailler sur une application utilisant massivement du MDM. Et MongoDB faisait partie des systèmes de stockage candidats.

Je dois bien reconnaître que cette présentation m’a appris pas mal de choses vraiment chouettes sur cette base. Et je comprend bien les cas d’utilisation présentés par Tugdual :

  • Vision 360° d’un client pour, par exemple, du support
  • Aggrégation de données provenant de façon assynchrone de plusieurs systèmes de gestion de données

Bref, la construction de rapports et leur utilisation dans des applications architecturés autour de concepts proches de CQRS paraît facile avec MongoDB.

En revanche, ce qui me paraît beaucoup plus compliqué, c’est la construction de données historisées « sans fin » (à cause par exemple de la limite dans la taille des documents).

Et puis, après avoir bossé sur des bases graphes, je dois bien reconnaître que je reste très attaché au graphe, c’est-à-dire à la création, et à la gestion de cohérence de ces liens par le système. Or c’est précisément le sujet que MongoDB ne veut pas adresser (et je les comprend, parce que ça simplifie bien des choses).

Cela étant, c’était une sacrément chouette session. Merci au chtijug !

Cinq ans, putain !

Comme il me reste plus que cinq jours de présence dans celle qui sera bientôt mon ancienne entreprise, je pense que le moment est parfaitement adéquat pour me lancer dans une petite série d’articles revenant sur ces cinq années de présence dans une boîte qui s’est appelée Perigee.

Je vais, pour ce premier article, ne pas vous parler de ce qui m’a occupé pendant quatre de ces cinq années : une espèce d’usine à gaz permettant de générer des catalogues grâce à Indesign.

Parce que la technique est chiante. Surtout quand c’est l’une de ces horreurs dont Adobe a le secret (oui, je parle d’Indesign).

Parce que, quand ce projet a commencé, l’idée (en 2010, donc) de créer un nouveau logiciel dont le seul objectif était de produire du papier me paraissait anachronique (pour être gentil).

Bref …

En fait, c’est la première fois dans ma carrière que j’ai eu la chance de pouvoir prendre des décisions impactantes pour un développement logiciel, mais aussi la première fois que j’ai pu vivre un projet de la première idée farfelue à sa réalisation concrète. Et même si le projet est un échec commercial, c’est également, de mon point de vue, une certaine forme de réussite technique … une réussite aussi évidente que pourrait l’être, dans un autre domaine, un aéroglisseur de transport de troupes : en dehors de son domaine d’utilisation, c’est lourd, lent, pénible, insupportable, même. Mais dans son domaine, c’est la meilleure solution possible … ou presque. Toujours est-il que voir un logiciel se construire de la première à la dernière brique est une sacrée aventure collective.

Et je crois que c’est la principale transformation que m’a fait subir mon mentor local : comprendre que si le codage ets une étape nécessitant de la tranquilité, le développement d’un logiciel, pris comme un tout, est avant tout un travail d’équipe nécessitant de la communication. Et pas n’importe laquelle. J’ai l’impression que le développement st de l’ordre de la maïeutique. En effet, l’équipe dans son ensemble cherche à donner corps à une idée, pour le simple développement, ou à comprendre ce qui dysfonctionne, dans le cas plus courant de la correction de bug.

Quoi ?

Vous me dites que vous ne comprenenez pas pourquoi je parle plus de correction de bugs que de développement ?

Eh bien c’est aussi l’une des grandes leçons de ce développement : même pour un nouveau développement, même pour un bout de code qui n’a pas encore passé l’épreuve du client, on passe plus de temps à reprendre du code qu’à en écrire du nouveau.

Et je pourrais développer ça sur quinze pages, mais ça me forcerait à entrer dans des considérations techniques qui ne sont pas le sujet de ce texte … mais peut-être du prochain.

Cap sur 2015

J’ai cet article dans mes brouillons depuis près d’un mois … et 2015 se rapproche inexorablement, et avec ce changement d’années d’autres changements se profilent.

Bref, vous vous souvenez qu’il y a un an, mon employeur avait déposé le bilan, puis avait été partiellement repris, et moi avec.

Qui dit reprise dit nouvelle direction, et donc nouvelle stratégie. je n’entrerais pas dans les détails de cette nouvelle stratégie, parce que ce blog n’est pas le bon endroit pour en discuter. Je me bornerais à dire que, comme quand c’est arrivé il y a 14 ans chez Miriad Technologies (à une époque où je n’avais pas encore de blog – et où le mot n’existait d’ailleurs même pas), la nouvelle stratégie n’avait pas vraiment de place pour moi, ce que j’ai compris avant qu’il faille en parler clairement.

J’ai donc pris la décission d’aller voir ailleurs si j’y serais.

Oh, pas très loin.

Mais alors vraiment pas loin, puisque je vais retourner dans le temple de Lille is French Tech : Euratechnologies. Et plus précisément, je vais aller chez Cap Gemini.

Quoi ?

Ca vous fait bizarre parce que j’ai toujours affirmé une relation plus qu’ambivalente vis-à-vis des marchands de viande ?

C’est vrai.

Mais mes discussions m’ont conduit à un poste qui ne m’emmènera pas forcément en représentation technico-commerciale permanente chez les clients.Et d’autres raisons, beaucoup moins palpables, me font penser qu’il pourrait s’agir d’un emploi bien plus intéressant que ce que je peux en penser. Bref, j’yv ais, parce que je suis intrigué, et un peu effrayé, de voir ce qui peut se passer dans l’une des incarnations les plus limpides de Cleer …Et puis ce changement va me permettre de faire un bilan de ces cinq dernières années.

Après deux mois de Javascript, on se sent comment ?

La question peut paraître … curieuse. Elle n’en demeure pas moins valide : quand on est comme moi un développeur Java un peu expérimenté, et qu’on passe d’un coup à ce langage aussi ubiquitaire que malaimé, qu’est-ce qui surprend ? Qu’est-ce qui étonne ? Qu’est-ce qui déçoit ?

J’ai vu des choses …

Avant d’aller plus loin, une petite mise au point. Je ne vais pas vous parler du dernier projet à la mode de lad ernière startup qui démarre. Non. J’ai fait du Javascript ces deux derniers mois pour la même raison qui m’avait forcé à faire du Flex pendant trois ans en pointillés sur le même projet : si vous voulez faire une extension pour indesign CC 2014, vous n’avez pas vraiment le choix, vous devez faire du HTML+Javascript. Alors du coup, je ne vais pas vous parler de Javascript qui communique avec son serveur via HTTP, mais de Javascript qui communique avec une extension Java/C++ via le système de communication créé par Adobe. Et, il faut le dire, Adobe fait des choix techniques … surprenants (j’y reviendrais).

En dehors de ces contraintes techniques spécifiques, l’application sur laquelle j’ai bossé n’a pas vraiment de spécificités. Enfin, pas trop :-)

Alors, grunt, bower, npm ?

hrm hrm …

Je vais essayer d’expliquer ça de façon claire, même si ça va choquer.

Le projet pour lequel on fait cette interface est un projet multi-module de taille « moyenne » : 32 modules différents, compilant et générant tout un tas d’artefacts. Est-ce que j’allais introduire dans ce gros paquet de modules, et dans mon Jenkins, un autre outil, ou plutôt ensemble d’outils ? Non. Je voulais (peut-être de façon dogmatique) que cette interface soit packagée par maven.

Tester du JS dans maven, c’est possible ?

A la lumière de mes expériences avec Wisdom, je me suis dit que j’allais jeter un oeil à frontend-maven-plugin histoire de profiter de ses fonctionnalités (en particulier les tests). Mais, curieusement, je n’ai pas réussi à lui faire faire quoi que ce soit. Alors j’ai arrêté de faire le mariole, et j’ai dit à l’un de mes collègues de faire un système de test Javascript à base de Fluentlenium (qui est devenu pour une raison que j’ignore du Selenium pur et dur) et de JunitParams.

Autrement dit, pour chaque test Javascript, on crée un fichier HTML le chargeant via requirejs (j’y reviendrai) et on récupère grâce à Selenium le résultat du test via un peu de Javascript. Ca pique un peu les yeux la première fois, mais ça marche en fait très bien (même si tester du code asynchrone avec Jasmine est un peu compliqué).

Et les dépendances ?

Bon, évidement, comme notre projet n’utilise pas HTTP, nos dépendances Javascript (pour lesquelles Webjars rempalce très avantageusement NPM) nécessitent un peu de travail, essentiellement pour faire une translation de chemin qui les rende facilement utilisables.

Je m’explique.

Notre projet a (par exemple) ces dépendances :

		
	<dependency>
            <groupId>org.webjars</groupId>
            <artifactId>requirejs</artifactId>
            <version>2.1.14-3</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>requirejs-text</artifactId>
            <version>2.0.10</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>log4javascript</artifactId>
            <version>1.4.9</version>
        </dependency>
		

Comment je fais pour utiliser log4javascript sans m’emmerder à mettre son numéro de version partout ?

Parce que, par exemple, avec Wisdom (désolé de prendre cet exemple de façon systématique, mais son utilisation m’a appris quelques trucs vraiment chouettes), je n’ai pas besoin de mettre le numéro de version grâce au WebJarController.

Eh bien c’est … assez compliqué, et ça se fait en plusieurs étapes

  1. On a un script groovy (encore merci à gmaven) qui nous permet de créer pour les dépendances Javascript des propriétés maven. Les artefacts mentionnés me donnent donc les propriétés org.webjars:requirejs:javascript:require, org.webjars:requirejs-text:javascript:text et org.webjars:log4javascript:javascript:log4javascript qui deviennent faciles à inclure dans un <script src="${org.webjars:log4javascript:javascript:log4javascript}"></script>
  2. Le même script maven crée également une grosse variable ${requirejs.dependencies.compile.paths} qui sera bien utile pour générer le shim de requirejs.
  3. Et tous nos artefacts javascript sont dézippés grâce à amven-assembly-plugin pour générer l’application.

Alors évidement, toutes ces technologies sont infiniment moins hypes que les build tools Javascript, mais elles nous permettent d’intégrer proprement des dépendances Javascripts dans notre build et ça, ça fait plaisir.

Et requirejs, c’est vraiment bien ?

Vous allez rire (ou pas), mais pour l’instant, deux choses ont été embêtantes (mais résolues)

  1. Si vous chargez tous vos scripts avec le protocole file://, vous serez limités par la longueur maximale des chemins de Windows. Et si vous avez des gros chemins, par exemple pour des classes Java dans des packages profonds pour lesquelles vous générez des stubs Javascript à l’aide de flexmojos (essentiellement parce que GraniteDS intègre un super générateur pour les entités et les services – et ne me demandez pas comment je transforme mes fichiers .as en .js), eh bien vous allez pouvoir vous amuser à écrire un algorithme de translation de chemin et un plugin amven (ou un script gmaven) pour copier les bons fichiers aux bons endroits au bon moment (parce que amven-assembly-plugin est clairement dépassé, là).
  2. Et si vous avez des dépendances en scope compile et d’autres en scope test, ça ne posera pas vraiment de problème à requirejs, mis à part bien sûr qu’il faudra distinguer le data-main de l’un et de l’autre.

Mais dans l’ensemble, require me réconcilie vraiment avec le côté « packageless » de Javascript. Je n’ai pas besoin de faire ces fameuses fonctions anonymes auto-appelées. Je déclare chacun de mes fichiers presque comme je le ferais en Java, et tout (ou presque) est explicite. Le fait de travailler dans un environnement contrôllé donne un sentiment de sécurité asssez plaisant, et des fichiers déclarés selon une syntaxe vraiment agréable.

Et Ractive, c’est pas du flan ?

Ce qui est assez marrant, c’est que plus je m’en sers, moins je comprends les mecs qui font de l’angular (oui, ça sonne comme du bashing, mais c’est plutôt de l’incompréhension).

Il nous a été assez facile d’écrire des composants pas forcément triviaux, et à chaque fois qu’on se dit que Ractive pose un problème, il s’agit en fait d’un problème entre la chaise et le clavier (une erreur ID10T comme dirait mon collègue).

Et le fait de ne pas s’embarasser d’une gestion du modèle nous a permis d’utiliser ce fameux protocole de communication Adobe sans « trop » de problèmes.

Ah bon, alors vous faites pas de JSON ?

J’ai dit protocole, je n’ai pas dit format d’échange.

En fait, on utilise du JSON, mais sans passer par la librairie JSON fournie par Adobe (et je vous conseille de faire de même parce que cette librairie est buggée).

En revanche, échanger du JSON entre du Java et du javascript pose une question sérieuse : on part d’un monde typé, dans lequel chaque objet peut avoir des méthodes associées, méthodes pour lesquelles on aimerait bien disposer d’équivalents en Javascript. Par exemple, l’un de nos objets doit s’afficher en utiliser le resourceBundle fourni, on a donc envie de mettre la méthode dans le fichier Javascript généré par Flexmojos (pas de panique, Flexmojos en génère en fait deux : un qui sera réécrit à chaque build pour contenir les champs définis par le Java, et un autre généré une seule fois, dans lequel on peut ajouter notre code).

Mais comment fait-on pour que le JSON reçu du Java s’interprète non pas sous forme de hash anonyme, mais grâce à notre classe ?

Eh bien là, c’est vraiment compliqué :

  1. On demande à Jackson d’envoyer les informations de type dans le flu JSON grâce à son système de déserialisation polymorphe (on a utilisé jsonMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_OBJECT))
  2. Du coup, côté Javascript, on récupère des hashes qui associent à une classe le hash correspondant à l’objet, et là, c’est l’enfer : on a dû écrire un système qui « unmarshalle » ces hashes anonymes pour retourner des instances des classes Javascript correspondant aux aux classes Java. Et comme ça passe par require, il faut faire ce truc qui fait toujours peur : du code récursif asynchrone. Heureusement que Deferred est là, parce qu’il me semble que de tout le code Javascript, c’est la partie la plus compliquée que j’ai eu à écrire. Un enfer, je vous dit
  3. Ah, et en bonus, il ne faut pas oublier le code inverse : celui qui va prendre des objets Javascript ou des hashes anonymes pour créer de beaux obejts Java à l’autre bout du fil … Pas gagné.

Tiens, d’ailleurs, c’est le moment idéal pour vous rappeler que, comme les maps javascript n’ont pas de clés non string, ça ne peut pas être le cas non plus pour le JSON. Alors comme vous ne voulez pas réécrire tout votre code serveur pour votre nouveau client moderne, eh bien vous aller devoir vous taper la (dé)sérialisation des maps sous forme de tableaux de tableaux … Bon courage ;-)

Autrement dit, comme d’habitude, la couche de communication va vous plonger dans un enfer sans nom, et surtout sans aucune raison valable.

Oui mais alors, le fait que ce soit pas compilé, qu’il n’y ait pas vraiment d’objets, c’est galère ?

Pour être honnête, oui.

Et pour être encore plus honnête, c’est pas trop grave.

Parce qu’en fait, il s’agit vraiment d’une interface HTML/Javascript : la partie complexe de l’application est bien au chaud, dans du code Java qui est correctement testé, qui a été écrit de façon à être raisonnablement robuste et qui est surtout déja utilisé en prod, donc qui a passé l’épreuve du feu.

Du coup, même si on galère parfois sur des histoires de types, ou de paramètres manquants/mal typés que Javascript ne voit pas parce que ça n’est pas son problème, ça n’est pas vraiment dramatique.

Et donc tu referais sans hésiter la même chose en plus gros ?

A dire vrai, mon Wiko a une version portable de Firefox qui fait fonctionner Ractive sans problème (comme Chrome, d’ailleurs). Alors du coup, demain, si je dois développer une application web, je peux vous assurer que le serveur se cantonnera à envoyer du JSON à mon client require/Ractive qui me fera, lui, une chouette interface.

Au passage, le bonus caché de Ractive, c’est que la philosophie est vraiment très proche de celle des web components, ce qui est loin d’être avantage mineur.

Eventuellement, j’ajouterais un coup de Facebook Flow pour valider mon code, et peut-être aussi que j’utiliserais plus frontend-maven-plugin pour minifier et toutes ces sortes de choses, mais dans l’ensemble, je comprend mieux ces histoires de microservices : si le client peut s’occuper d’aggréger et de présenter les données, pourquoi s’embêter à utiliser toute la pile JavaEE là où Wisdom suffit largement ?