11 octobre 2012

Lambda, under the hood

Retour avec Brian Goetz, cette fois pour comprendre comment les lambda sont implémentées. Comme je n'ai pas pris de photos de cette session, j'agrémente ce biller de quelques images prises au hasard :)

L’introduction des lambdas dans Java aurait pu se faire en introduisant un type « Function » dans la structure du bytecode. Cependant, ce genre d’évolution et les impacts en termes de compatibilité nécessitent de longs travaux, aussi une modification dans le compilateur est largement préférée !



On pratique déjà plus ou moins les lambda dans le code java avant la version 8 via les « interfaces fonctionnelles » n’ayant qu’une seule méthode (Runnable, Comparable, …). Première idée donc, simplement demander au compilo de convertir chaque lambda en inner class anonyme. On se retrouverait alors avec une classe par lambda dans le code, autant dire que le nombre de classe par fichier source java exploserait rapidement, et surtout un appel de constructeur par appel de lambda, et là vos perfs s'écroulent.

Seconde idée, utiliser les mécanisme d’invocation du bytecode pour convertir la lambda en méthode statique et l’invoquer. Idée intéressante mais dont les impacts sont peu évidents sans plus de recul, et n’oublions pas que ce genre d’évolution devra rester dans toutes les versions à venir de Java, pas le droit à l’erreur ! (voir l’article précédent sur les génériques pour vous en convaincre…)

Java 7 a cependant ajouté un truc bien sympa, le invokeDynamic qui profite déjà à Grovvy 2.0. Ce mécanisme permet d’attendre l’appel de méhode pour identifier la cible à invoquer, passerelle vers l’exécution rapide des langages dynamiques sans payer le prix de l’API de réflexion. Un MethodHandle peut ainsi être utilisé pour pointer vers la méthode à exécuter. Détail important, ce "pointeur" peut changer à chaque invocation, mais en pratique est souvent fixe, et peut donc être caché pour obtenir des performances proches d’une invocation directe.

L’ajout de invokedynamic, au départ pour ouvrir la porte aux langages dynamiques, profite ainsi aux lambdas. La JRE Java 8 propose ainsi une factory pour identifier le MethodHandle, et le conserve en cache tant que les types des arguments ne changent pas, ce qui est le cas pour la majorité des cas d'usage de lambdas. Cette factory peut au choix générer du bytecode, utiliser des wrappers, des proxies, ou des API internes, les lambdas sont « neutres » au niveau bytecode et laissent la porte ouverte pour de futures nouvelles stratégies ou améliorations, ou bien s’adapter en fonction du contexte : JRE embarqué par exemple.



Tout serait merveilleux, sans l’un des mécanisme les plus poluants que Java ai pu inventer : la sérialization.

Si ma JVM a généré du code, que je le sérialise, et qu’une autre JVM, basée sur une autre stratégie tente de le désérialiser, que va t-il se passer :-/ ? D’où … une factory pour la serialisation, dont le but est de capturer la « recette » de la lambda pour être capable de la reconstruire sur la JVM cible. Ce qui veut dire qu’il faut prévoir qu’un vilain programmeur pourrait construire à la volée un flux sérialisé comportant du code malicieux, et l’injecter par ce biais dans votre JVM, ce qui ne serait vraiment pas gentil …. Hum, ça donne envie, n’est-ce pas ?

Au final, une lambda est, en termes de performances, au pire équivalente à une inner classe, et dans de nombreux cas (pas de capture de variables du contexte) 5 à 20 fois plus rapide. Bref, pour une fois on pourrait bien avoir une évolution bien foutue dans Java !


09 octobre 2012

Good Bad and Ugly generics

Ce talk était un véritable show, entièrement réalisé en live coding. Speaker boosté aux stéroïdes, humour et contenu, une super session.
Dans le texte qui suit, je note les génériques avec des accolades carrées "[ ]" car blogger est une grosse bouse qui ne gère pas l'échappement des balises html. Je n'ai pas non plus réussi à éviter les &amps ... 



Les generics ont été introduites dans Java pour résoudre un problème qui n’existe QUE parce que le langage est statiquement typé. Cette version « simplifiée » des templates C++ a fait couler beaucoup d’encre, entre autre pour débattre de sa syntaxe particulièrement … pourrie.

Je vous passe la partie « good » de la présentation, les génériques permettant en substance d’écrire moins de code et d’éviter de se tromper en mettant des oranges dans un panier de bananes.

Si on décompile un bout de code qui manipule une List[foo] on constate qu’il ne subsiste rien du paramètre de type dans le bytecode. Cet effacement, nécessaire pour assurer la compatibilité, fait des génériques un simple « sucre syntaxique » pour éviter au développeur de caster ses variables, opération qui sera bel et bien présente au final dans le bytecode (checkcast). Les choses se compliquent lorsque vous créez une méthode foo(List[fruit]) qui veut naivement ajouter une Orange dans le panier. Le compilo vous insulte. C’est là que l’on mesure l’intelligibilité de ces génériques, sur lequel Dr Odersky (qui créa Scala par la suite) a bossé, faut-il y voir une relation de cause à effet (#troll et mauvaise foi inside). 

Il faut donc écrire foo(List[? extends Fruit]), pour lequel le mot clé extends n’a RIEN à voir avec le sens classique du terme, comme si un mot clé plus spécifique n’avait pas pu être introduit ici, genre le compilo est très con il ne sait pas identifier un mot comme réservé lorsqu’il est dans une expression générique et le laisser libre dans les autres cas … j’ai toujours été ébahi que le mot clé « class » ne puissent être utilisé comme nom de variable, alors qu’il n’est utilisable dans le langage QUE pour des éléments très spécifiques et facilement identifiables. Ca montre que le compilo est basé sur une analyse lexicale puis sémantique à la grand papa, dommage.


On passe ensuite à la paramétrisation (ça se dit ça ?) des classes, et un petit rappel du principe de substitution de Liskow, qui nous amène à la conclusion qu’on ne devrait quasiment pas utiliser l’héritage et lui préférer la délégation, ce qu’on ne fait évidement jamais en java tellement il est simple d’écrire Foo extends Bar - à moins d'utiliser lombok et @Delegate, rendez-vous au prochain JUG pour en savoir plus. Après cette parenthèse, la leçon à retenir est que List[orange] n’étend pas List[fruit], certes à juste titre, mais qui crée en général des nœuds au cerveau pour les développeurs novices.

Pour copier les oranges d’un panier d’orange dans un panier de fruit il faudra donc écrire : copy(List[T] source, List[? super T] target)
une nouvelle fois en utilisant un mot clé existant dans un contexte ou son sens est complètement détourné et peu intelligible. Nos génériques, avec une syntaxe de m…, sont nées pour mourir à la compilation, ce qui porte le doux nom de Type Erasure. Confronté au même problème, C# a choisi de casser la compatibilité ascendante pour promouvoir la réification de type (essayez de placer ça dans la conversation, ça fait mec intelligent).

L’effacement de type n’est pas systématique tout de même, ainsi un [T extends Comparable] sera traduit dans le bytecode par un type Comparable. Par contre, un [T extends Comparable & Serializable] - et oui, on peut aussi faire ça, le saviez vous ? pas moi - ne verra plus aucune trace du Serializable dans le bytecode. Le « & » dans une expression générique n’est donc pas commutatif ! fun non (ou très con, selon les goûts) ?

On passe rapidement sur l’absence de support pour les types primitifs, qui nous collent ainsi du boxing/unboxing caché, source de NullPointerException, sans doute mon bug préféré. Un petit mot sur l’impossibilité de construire une instance du type paramétré (sauf à bricoler avec de la réflexion), et on enfonce le clou avec cet exemple : partant d’une interface :
EventListener[t] { void onEvent(T evt) }
vous ne pouvez pas créer une classe Foo implements EventListener[String], EventListener[number], car le code Type-Erasé subira une collision de méthode !

Pour conclure, on prend un exemple ou une classe paramétrée Foo[T] tente de maintenir un compteur statique de son nombre d’instance. Le compteur est alors global, et non par type considéré, et comble du bonheur on ne peut même pas écrire Foo[String].getCount() sans se faire insulter par le compilateur.



Bref, si certains arguments touchent à des utilisations peu communes des génériques, le talk aura proposé un tour assez complet de leurs impacts sur Java, aussi bien au runtime que dans le code source, et démontré la nécessité de toujours définir l’usage attendu des arguments de méthode lorsqu’il sont paramétrés, selon qu’on veut en extraire des données (extends) ou en ajouter (super).

The road to Lambda

Brian Goetz, que vous connaissez peut-être pour le livre « concurrency in java », présente l’historique et le rôle des lambda qui apparaitrons en java 8.

Java est le dernier langage majeur à ne pas disposer de « closures » - même C++ en a dans sa dernière mise à jour ! Si le concept pouvait paraître trop avancé à l’époque de java 1.0, qui visait à proposer une plateforme simple et accessible (comparée à C/C++), les temps ont changé et Java se doit de s’équiper de ce bagage devenu indispensable, comme nous allons le voir.


Une lambda est grosso-modo une méthode anonyme qui peut accéder au contexte lexical depuis lequel on l’invoque. La syntaxe a longtemps été débattue, et je ne suis pas super fan de celle que a été retenue - j’aimais bien #(params){ … } - mais comme pour le reste ce n’est qu’une question d’habitude.

Pour mettre en évidence le rôle des lambda, Brian part de l’exemple du traitement d’une collection par itération. Le foreach traditionnel, dit « itération externe », oblige le code client à interagir lourdement avec la « librairie » (java.util.collections). L’iterateur et ses méthodes hasNext() / next() montre d’ailleurs un soucis d’implémentation avec une inévitable duplication de code. Les lambda, bien au dela d’un simple changement de syntaxe, permettent de passer à une « itération interne », où on laisser à la librairie le soin de traiter l’itération et d’invoquer le code client au bon moment (un peu comme avec le pattern visitor).

Le traitement en parallèle d’un collection devient alors très simple à mettre en œuvre, en exposant simplement un mécanisme de Stream, et une approche fonctionnelle du code, avec des appels chainés de méthodes de filtrage, mapping ou aggregation, plutôt qu’impérative - il va falloir ressortir vos cours de Lisp :P. Ce petit pas vers la programmation fonctionnelle pourra aussi vous aider à mieux appréhender des langages fonctionnels comme scala et clojure, et donc à élargir votre panel de compétences.

Cette possibilité de prendre en charge le parallélisme du hardware avec un moindre impact sur le code est le principal argument qui a poussé la mise en œuvre des lambdas, afin de permettre à java de bénéficier de la multiplication des cœurs. Le « fork-join » de java 7 est en effet encore bien trop complexe, verbeux et différent d’une itération classique pour être significativement adopté en dehors de code très critique. Les lambdas ne suffisent cependant pas pour permettre à java de devenir un bon language multi-cœur, car il faut faire avec l’héritage en place, à savoir l’API collections.

L’évolution de JDBC a montré que l’ajout de nouvelles méthodes dans une interface est une erreur catastrophique (regardez le build de commons-dbcp pour vous en convaincre). Aussi les default methods ouvrent la voie à de nouveaux usages sans briser la compatibilité. Lambda et default methods ont donc été introduites dans Java 8 avec un objectif bien précis, et leur impact général est encore délicat à estimer.

Les default methods ont fait penser à l’arrivée de l’héritage multiple en java. Techniquement parlant cet héritage existe déjà, par contre il est restreint et ne permet pas l’héritage d’état. Cela s’apparente aux extensions method de C# pour ceux qui connaissent. En case de conflit sur une default method, si j’implémente Foo et Bar qui définissent toutes deux la default method blah(), le compilateur réclamera une redéfinition explicite. Ce mécanisme est donc prévisible et mentalement acceptable, ce qui n’est pas forcément le cas de l’héritage multiple dans d’autres langages qui nécessitent un esprit bien entrainé.

Cette session repositionne donc l'introduction des Lambda et des default methods dans java 8, avec un objectif précis au départ, et un potentiel évident sur de nombreux autres domaines. Il est intéressant de voir que ces évolutions sont parties d'un besoin spécifique, et pas juste d'une volonté d'apporter un nouvel élément de syntaxe à Java.

08 octobre 2012

Large-Scale Automation with Jenkins

Pour la première journée de conférences de JavaOne (qui suit les keynotes du dimanche) j'attaque avec CON6256 - il y a tellement de conférences qu'organiser un planing est un challenge en soit !

Cette session, c'est tout simplement celle de mon collègue Kohsuke, sur l'utilisation avancée de Jenkins.  Il faut croire que je n'ai pas eu ma dose avec la JenkinsConf de la veille :P La salle est bien pleine, malgré l'heure matinale.

Kohsuke présentait donc en une heure l’utilisation de Jenkins pour l’automatisation du processus de développement, introduisant de manière progressive les plugins adaptés pour porter un « pipeline » complet.


En premier lieu, il présente les paramètres de job puis le parameterized build trigger plugin. Derrière ce nom à rallonge peu expressif se cache un plugin majeur qui permet de définir des jobs très génériques et de les chainer de manière efficace en jouant sur leurs paramètres. Après une rapide démo, Kohsuke présente le plugin join en insistant sur ses limites, utilisable uniquement pour les cas simples, et laissant le suspens pour la suite.

En jouant sur ces plugins, KK montre comment découper un job long en plus petits traitements plus faciles à paralléliser et à distribuer sur une infrastructure de machines « courantes ». Kohsuke présente ensuite la notion de promotion, utilisant cette fois le résultat du job comme déclencheur d’une promotion, qui active alors un processus de QA. Ce mécanisme permet de lier les jobs de deux équipes (Dévelopeurs et Qualiticiens) tout en laissant à chacun toute la liberté nécessaire sur la configuration du job.

Pour aller plus loin dans la mise en place d’un pipeline, KK aborde la problématique de la transmission d’un binaire entre jobs. Le plugin copy-artifact est présenté, il permet en effet de récupérer le binaire archivé par un job, sous sa forme de « dernier build stable » ou même de « résultat du build qui vient de déclencher ce job » (upstream). Il montre également l’utilisation des fingerprints pour identifier un binaire facilement dans l’instance jenkins et créer ainsi des références entre jobs sans configuration lourde. Kohsuke présente enfin le plugin maven-repository-server, qui transforme votre Jenkins en repository maven, permettant ainsi de faire facilement référence au binaire upstream de manière maven-compliant, ce qui est délicat avec le plugin copy-artifact. Je vous recommande également cet excellent plugin si vous ne le connaissez pas, afin de découper un job maven massivement multi-module comme certains les aiment en enchainement de jobs plus légers.
Petite anecdote : KK venait juste d’installer le plugin en question sur son instance de test avant le début de la session, ce qui amha était quelque peut risqué :). 

Afin de simplifier la configuration de la chaine de jobs qui commence à apparaître, KK présente le build-flow plugin, puis en fait une démo sans oublier de me faire un clin d’œil en passant mon nom comme paramètre du build.



J’apprécie la publicité gratuite, à moins que ce soit un encouragement pour que je prenne le temps pour faire avancer ce plugin dans le bon sens. Nous avons eu par la suite d’intéressantes discussions sur les possibles évolutions du plugin, tant en termes d’expérience utilisateur (validation du DSL) que d’extensibilité par d’autres plugins.
Kohsuke présente aussi le plugin Jenkow, déjà exposé à la JenkinsConf, qui utilise une approche différente, assynchrone à l’extrême, en déléguant tout le chainage des jobs à un moteur BPM. Avantage de ce plugin, la configuration du flux de jobs se fait en mode purement graphique dans Eclipse, puis le résultat est pushé dans jenkins via un repo git virutel. Idée intéressante à développer également pour le build-flow via l’introduction d’un fichier décrivant le DSL que l’IDE sait interpréter pour assister la saisie.

Enfin, Kohsuke aborde le problème de visualisation du résultat de tous ces jobs. Il présente d’une part la vue « project relationship » qui utilise les fingerprints pour tracer les relations entre job, ce qui peut devenir délicat avec un même binaire qui passe de job en job pendant les étapes du pipeline. Il présente également le plugin job dependency graph permettant de visualiser les liens entre jobs, et qui gère même les relations créées par le copy-artifact, puis le build-pipeline dont il fait une démonstration sur la base de son exemple précédent.



Le plugin build-flow comporte une tentative (pour l’instant pas très concluante) de visualiser les relations entre build, dans l’idée que deux exécutions successives peuvent faire intervenir des jobs très différentes - contrairement à ce que le build-pipeline présuppose. Je vais probablement extraire ce code dans un plugin dédié et le rendre générique. J'utilise pour l'instant jsPlumb qui permet de tracer simplement les liens entre jobs, et je regarde du côté de JGraphx pour l'algorithme de layout permettant de positionner les jobs -- s’il y en a parmi vous que cela intéresse et/ou qui connaissent bien le tracé de graphes acycliques orientés :) …

07 octobre 2012

JenkinsConf SF

JavaOne commence dès le dimanche avec une grande keynote en guise de tour de chauffe, mais pour ma part j'étais évidemment aux côté de l'équipe CloudBees pour l'organisation de la seconde Jenkins User Conférence dans la silicon valley.


Pour l'occasion, André avait mis le paquet pour se fondre dans l'ambience de l'événement :)

Avec deux tracks en parallèle, la journée a été riche en informations. Elle a été aussi riche en échanges et en longues discussions avec les trois members du board jenkins-ci.org, et la large communauté à avoir fait le déplacement (250 participants).

J'ai particulièrement apprécié deux sessions consacrées au développement de plugins Jenkins et à expliquer les concepts et pratiques associées. J'avais ébauché une documentation du développeur newbie, il semble que la motivation revienne pour m'y remettre, avec de nouvelles idées et peut être même un peu d'aide :)

Pour cette édition, nous avons tenté en fin de journée d'organiser le "governance meeting" à la fois sur #IRC et en direct, pour permettre aux participants de découvrir son fonctionnement et d'interagir plus naturellement. Je ne suis pas sur que ceux qui ont suivi cela depuis la console IRC on tout compris, mais le format, à la "castcodeurs live" était très sympa. De nombreuses personnes semble grace à cela intéressées pour participer plus activement à la communauté en se joignant à ce rendez-vous bimensuel.

Retrouvez quelques images de cette conférence sur mon album Google+

Les rues de San Francisco

Arrivé vendredi dans l’après midi, j’ai pour une fois une journée complète pour visiter la ville, ce qui m’évitera d’avoir fait 14h d’avion pour ne voir que l’aéroport et la salle de conférence, comme cela m’arrive souvent. Me voici prêt à explorer la ville dès 6h, jet lag aidant.

Je commence par remonter Van Ness, large avenue au bord d’une zone d’habitation bourgeoise. L’architecture typique se retrouve dans chaque bâtiment du quartier : entrée avec porche à colonnes, fenêtres en bow-window, façade largement décorée de moulures mises en couleur.


Je rejoind fisherman's wharft, autrement dit les anciens quais qui sont pour beaucoup convertis en lieux chics ou touristiques. Un vieux tramway en bois, soigneusement entretenu pour conservé le cachet de ce secteur très prisé, me permet de rejoindre le centre en longeant la côte jusqu’à l’embarcadero, qui débouche sur Market Street, grande avenue qui ouvre l’accès au centre ville.


Gratte-ciels et palaces de luxe, nous voici au cœur de la city à l’américaine, où les taxis jaunes se frayent un chemin dans une circulation dense. Je passe au Hilton Union Square, récupérer mon badge « presse » pour JavaOne. Pays de tout les contrastes, au pied même de cet immense hotel de luxe on croise tous les dix mètres un homeless, souvent handicapé, que le système social libéral n’a pas épargné, et qui subit les prix ahurissants de cette ville symbole de la silicon valley.


Je remonte à travers le centre pour rejoindre Union Square, privatisé par Oracle pour installer les tentes de ses animations VIP. Je monte dans un de ces fameux cable car, sorte de funiculaire héritage de l’histoire de la ville, et qui on survécu grâce au tourisme. Le charme et la mécanique basique de ces engins ravis les touristes qui sont nombreux à faire la queue.


Accroché au cable qui court sous la chaussée, l’engin de fer et de bois attaque la pente de russian hill qui délimite le nord de la ville. On est content de ne pas être à pied ! San Francisco à quelque chose d’une ville de montagne par endroit, avec des rues à 45° très impressionnantes. Dont la célèbre « lombard street », dont la pente est si extrème que la ligne droite aurait été suicidaire.



A nouveau au nord, je longe fort Mason en face de la célèbre prison d’alcatraz pour attraper un bus qui m’emmène tenter ma chance pour prendre le golden gate en photo. Le climat très particulier de SF se confirme : le pont est noyé dans une brume épaisse. San Francisco est la ville qui bénéficie d’un micro-climat différent dans chaque block. Quand il fait grand soleil et 35° sur San José, le centre pointe à 28° sous un petit vent frais et la plage pacifique de SF est noyée dans la brume et peine à dépasser les 20°.
Mark Twain aurait dit « Mon plus dur hiver a été un été à SanFrancisco ».



Histoire de m’oxygéner, je reviens à pied en remontant la Presidio Promenade, dans ce quartier étonnant préservé de l’urbanisme galopant qui règne partout ailleurs sur la péninsule.


Les épaisses pelouses verdoyantes contrastent avec le sol plutôt asséché que j’avais aperçu en arrivant de l’aéroport depuis le BART. Dans les quartiers moins chics du sud de SF, l’immensité et le mimétisme géométrique de l’urbanisme retire toute âme au lieu, sans même parler de ces rues, nues de toute trace végétale, qui sont « juste » numérotées de 1 à 42, et donnent à l’ensemble un aspect sans saveur.
  

Presido est l’extrême opposé, dans une verdure luxuriante et des rues tortueuses - sans doute pas avec les même prix au mètre carrré. 


J’arrive à la Lombard Gate qui marque brutalement la frontière de cette zone à part et le retour au béton et à l'urbanisation géométrique. 




Retour au centre en bus et passage par ChinaTown, véritable ville dans la ville, bouillonnante de vie. Un resto chinois me permet de préparer l’après midi, avec un plat dont la générosité aurait probablement pu nourrir une ou deux autres personnes (ce qui contrastera avec les sandwich de javaOne).


Un rapide passage par le financial district, puis, lassé de ce centre ville, je prends un bus pour rejoindre l’ouest de la ville et Golden Gate Park (perdant au passage 5°). La géométrie de la ville a au moins l’avantage qu’on a pas vraiment besoin de plan pour s’y retrouver, il suffit de compter les rue, encore que SF innove avec la Market Street qui passe à 30° des autres :P


Golden Gate Park est une appréciable bouffée d’oxygène, où les habitants sont nombreux à venir profiter des grands espaces verts et des rues fermées à la circulation pendant le week-end.


Au centre de Stow Lake, Strawberry Hill est une étonnante colline aux pentes raides et à la végétation exubérante, au milieu d’un quartier qui semble par ailleurs assez plat (si si, il y a de quartiers plats à SF). La vue aurait sans doute été intéressante sans la brume maritime qui envahi maintenant l’horizon.

 


Je m’offre la visite du Japanease Tea Garden, magnifique jardin au style asiatique (n’y connaissant rien je ne préciserait pas si c’est Zen, Thao ou juste Californien) qui permet de prendre un bon bol de vert et de se ressourcer un peu au calme.


Un peu plus loin l’académie des sciences et le Young Museum, deux imposants bâtiments à l’architecture antinomique, attirent un public nombreux. Le premier expose ses colonnes et ses moulures, le second se cache derrière sa cuirasse métallique.

Je remonte ensuite le parc, qui semble être le lieu obligé pour fêter les événements familiaux autour de grands piques-niques - il faut dire que les jardins privés on l’air particulièrement exigus). Je me retrouve alors au milieu d’une impressionnante rencontre de customs et voitures de collection - et oui, on est au US tout de même :P

Je passe le dutch windwheel qui marque le bout du parc cet j’arrive enfin à l’océan, sur une place au sable fin (mais gris) noyée dans la brume, ce qui ne semble pas décourager les surfers. Il ne me reste plus qu’à reprendre un bus qui remonte une des ces interminables streets qui traversent SF de part en part, pour rejoindre le 21th amendment, lieu de rendez-vous pour quelques participants à la JenkinsConf du lendemain.



Bien que courte, cette visite de SF a été une belle journée pour moi, pleine d’étonnement. Cette ville est vraiment un lieu à part, qui peut, en moins d’une heure – ou en se déplaçant de quelques blocks, passer d’un beau soleil à un hiver sibérien.

17 septembre 2012

JugSummerCamp 2012

Sauf à avoir déconnecté Twitter pendant 3 jours vous n'avez pas pu passer à côté : vendredi avait lieu la troisième édition du JugSummerCamp.

Le camp commence dès le jeudi soir, au gite que les organisateur ont loués pour les speakers. L'occasion de se retrouver autour d'une bonne table, de mieux faire connaissance, et de passer un bon moment avant d'attaquer la journée de conférence. L'occasion aussi, après quelques verres, de se faire coller un gage pour le keynote du lendemain :  caser "catadioptre" et "funiculaire" dans le discours d'ouverture :-/

Le vendredi matin, on rejoint l'équipe Serli au commande de cette conférence qui peaufine les derniers détails. On retrouve de nombreuses têtes connues, habituées de ce rendez-vous devenu incontournable. Après un café (lyophilisé) on attaque une grosse journée par la keynote de bienvenue.

J'ai eu l'honneur d'ouvrir ce JugSummerCamp 2012. L'exercice "keynote" est particulièrement délicat si on veut faire un sujet sérieux, et je suis resté sec pendant un bon moment, jusqu'à tomber sur ce tweet. C'était donc décidé, les cast-codeurs seront bien présents au JugSummerCamp, pour une session de "muppet-show" 


Pas trop de fond dans ma présentation donc, mais au moins on a bien rigolé et le public a apprécié ce moment de détente avant d'attaquer des sujets plus sérieux.

J'ai suivi la session d'Alexis Moussine-Pouchkine et Martin Görner sur le développement d'une application Google AppEngine en HTML5. En deux fois 30 minutes, et en choisissant quelques sujets précis utilisés dans cette application, ils ont réussi à donner une idée précise du développement et de l'animation en HTML5. Accessoirement, on pouvait gagner une place à Devoxx en se servant de leur application ;)

Nicolas Martignole présentait ensuite une présentation sans play (enfin, presque). Il s'agissait pour lui de présenter la société ZapTravel qu'il a rejoint, les enjeux techniques à relever pour affronter un marché très concurrentiel, et les options qu'ils avaient retenus. On sent qu'il s'éclate sur ce boulot, tant mieux !

Mathieu Ancelin enchainait avec un Quickie Play! permettant à la salle de jouer à une space battle. Développé en Play/Akka/Canvas ce petit exercice de style était l'occasion de mettre en pratique ces technos et de nous en faire un retour.

Un passage par l'excellent buffet, délaissant les quickies à venir pour tenter de chopper le wifi - capricieux cette année - nécessaire pour ma session Cloud de début d'après-midi. Pour une fois (sic) je suis content d'être chez Orange, ce qui m'a permis de chopper le wifi de l'opérateur.

Ma session consistait à montrer en quoi le Cloud est une libération pour les développeur pleins d'idées. J'ai donc suggéré à la salle de "niquer Google" en développant un moteur de recherche concurrent. Partant from scratch, en live-coding (avec une anti-sèche) j'ai donc crée une application hébergée sur CloudBees, un index WebSolr, marié les deux dans une IHM générée sur un générateur de template de site. Le but était de montrer que ces offres Cloud permettent de tester une idée en grandeur nature en quelques heures, sans contraintes ni coûts significatifs, et de la laisser murir ou de l'abandonner rapidement. Autrement dit, l'agilité dont rêvent les grosse boites, crispées sur leurs demandes de budgets. 

David Gageot proposait dans la session suivante un pur live-refactoring 100% code dont il a le secret. Mes quelques lignes de code paraissaient bien ridicules à côté, et il ne s'est pas privé de lancer quelques gentilles piques. Le but de David était de nous montrer la démarche et l'esprit général pour attaquer du code legacy : construire une suite de test systématique plutôt que de chercher à valider la spec (dont on ne sait pas si elle est à jour), chercher les symétries, faire confiance à l'IDE pour tous les refactoring simples afin d'éviter les surprises. En 30 minutes, le code immonde du début est recomposé de manière compréhensible et bien structurée, avec un peu de délégation via Lombok parce que c'est super pratique :)

Laurent Huet proposant ensuite une session "hardware" avec la programmation sur BeagleBone. Petit soucis, la carte a cramé juste avant de partir à la Rochelle, l'occasion de montrer que le warning du slide #3 "attention aux tensions" n'est pas inutile. Qu'à cela ne tienne, Laurent à réussi à équiper une raspberry Pi pour faire tournée sa démo, et allumer une LED depuis sa console bash devant un public émerveillé, ou effrayé (selon) devant la possibilité de faire interagir du soft avec du hard. Beaucoup étaient venus avec des idées de pilotage de leurs volets-roulants / aquarium / etc et sont repartis avec des idées un peu plus réalistes :) Quoi qu'il en soit, un sujet très sympa, que je n'avais pas pu suivre au BreizhCamp, et qui change des présentations de frameworks ultra-abstraits.

Dernier sujet, une présentation de Programmatoo Audrey Neveu et Ludovic Borie. Pourquoi attendre la Fac pour découvrir la programmation ? Ici on prend des enfants qui savent tout juste lire (ou pas, selon les outils) et on leur met entre les mains des outils adaptés. Les résultats sont étonnants, comme toujours avec les gosses. Les outils sont nombreux, et on ne parlait ici que de ceux qui était francisés. N'hésitez pas à les contacter pour organiser un Coding gouter :)

La journée se termine autour d'une bière, puis d'un bar (le poisson), puis d'une autre bière... pour finir dans une ambiance night-club avant de retourner au gite et de se rendre compte ... qu'on a pas le code de la porte. David a donc mis en place un refactoring complet de la porte et trouvé le code en testant toutes les combinaisons impliquant les touches les plus usées ! Comme quoi, faut toujours avoir un David sur soi.

A bientôt pour tout ceux que je n'ai pas pu saluer, un énorme MERCI aux organisateurs, et rendez-vous l'an prochain (avec les vrais castcodeurs cette fois) !


11 septembre 2012

maven settings et sécurité apparente

Maven 3 permet de crypter les mots de passe serveurs stockés dans votre fichier settings.xml. C'est un net progrès pour ce fichier qui peut vite contenir tous les sésames de votre infrastructure. Cependant beaucoup (trop ?) de personnes semblent se contenter de la sécurité apparente de voir leur mot de passe remplacé par un obscur "{ABCDEF1234567890ABCDEF1234567890=}".

Un indice : Maven 3 est en mesure de retrouver vos mots de passe, sans vous demander quoi que ce soit : le cryptage est donc réversible sans votre intervention. Si vous utilisez un client ssh vous vous souvenez peut-être avoir mis en place un agent qui "cache" votre passphrase pour ne pas avoir à la retaper à chaque commande. Bien pratique, l'effet pervers de ces outils est qu'on finit par oublier où se situe la réelle sécurité dans le système.

Petit rappel donc : Maven utilise un mot de passe maître,  stocké dans votre settings-security.xml, et lui même cryptée pour ne pas révéler de manière trop évidente cette info capitale. Cette clé sert pour crypter vos autres mots de passes. Si cette clé est inaccessible à un malveillant, vous êtes en sécurité (dans la limite du raisonnable, comme tout système cryptographique l'attaquant très bien armé et très patient pourra passer au travers - il peut aussi vous couper les orteils un a un pour vous faire révéler votre mot de passe c'est souvent plus simple)

On se retrouve donc avec deux fichiers bien obscurs qui donne un sentiment de sécurité. Seulement que ce passe t-il si un vilain pas bô peut accéder à ces deux fichiers ? Disons qu'il passe 2 minutes à regarder le code de maven et qu'il essaye un truc du genre :

PlexusCipher _cipher = new DefaultPlexusCipher();
String bare = _cipher.unDecorate( "{...=}" );
String master = _cipher.decryptDecorated("{...=}", SYSTEM_PROPERTY_SEC_LOCATION);
System.out.println( _cipher.decrypt(bare, master) );


Ne m'accusez pas de révéler une faille de sécurité, c'est vraiment à la portée du premier stagiaire venu de retrouver ce fragment de code à partir du code source Maven :P

La documentation de Maven vous le dit très clairement, le fichier settings-security.xml est la clé du système et doit donc être traité avec tous les égards. La solution recommandée consiste à renvoyer, dans le settings-security.xml par défaut, vers un autre fichier que vous placez sur une clé USB, disque réseau, ou tout autre ressource que vous pouvez "débrancher" en votre absence. On en revient donc au final à la bonne vielle sécurité physique. 

La réelle sécurisation proposée par Maven consiste donc à déplacer le problème de sécurité des mots de passe. En fait, si on considère le scénario où vous placez votre fichier sensibles sur une clé USB à reconnaissance d'empreinte digitale,  une simple redirection du fichier settings.xml donnerait une sécurité globalement équivalente. La sécurisation proposée par maven 3 est donc :

  1. d'éviter que vos mots de passe apparaissent en clair, par exemple lorsque vous ouvrez votre fichier settings.xml en plein pendant une démo lors d'une conférence (non, ça ne m'est pas arrivé :P)
  2. de vous permettre de séparer l'accès à vos mots de passe en deux fichiers. Un attaquant opportuniste qui vous piquerait l'un des deux éléments ne serait pas plus avancé.


C'est donc un réel progrès, mais le risque que je constate - risque général d'ailleurs - c'est qu'on est tenté d'utiliser son ID et le même mot de passe un peu partout. Résultat, dans le settings.xml utilisé par le serveur d'intégration continue je vais retrouver les clés du responsable technique du projet. Si celui-ci est conscient de ce risque (et c'est désormais le cas, vu qu'il lit forcément assidument ce blog) il aura créé un utilisateur dédié sur son Nexus / Artifactory / Archiva pour les déploiements maven. 

Moralité, sortez couverts !

update : 
si vous récupérez le mot de passe de session Windows de votre chef-de-projet-apprenti-responsable-technique par ce biais, merci d'envoyer de sa part un mail à toute l'équipe déclarant que la journée du 14 septembre sera chômée afin de tous vous envoyez au JugSummercamp à ses frais.

09 septembre 2012

Jenkins User Event CPH

Une fois n'est pas coutume, pour être lisible de mes hôtes je rédige ce billet en pseudo-anglais (c'est comme le pseudo-code, ça ne compile pas mais ça donne l'idée générale)


Last week, praqma was organizing in Copenhague a "Jenkins User Event". A User Event, compared to JenkinsConf, is a lighter meeting with (suposed to be) reduced costs organized by volunteers. Praqma got sponsorship from both CloudBees and Programing Research so that they can book a high quality conference room and prepare a nice meeting with all commodities.

That was my first travel to Danemark. I enjoyed the winds-farm on northern sea as well as the duty-free lego shop at airport, but didn't have much time to discover the city - so will have to come back next year ;)


Thursday was about a Jenkins Code Camp (aka "hackathon"), that I joined late at 2pm due to flight being delayed. 20 geeks were talking about some technical issues, new features, implementation strategies for a large set of topics. I contribute a group to solve an integration issue by creating a new extension point in jenkins-core. Those already confident with jenkins development helped to write this code, some discovered the extension point design as well as way to contribute to jenkins (github pull request, etc), some were looking at jenkins source code for first time so learned a lot.



Day ended with beer then a chinese restaurant (typical Danish food :P), with lots of fun and nice discussions.


Ajouter une légende
Friday was the Jenkins User Event. To reduce costs for such an event, compared to other Jenkins Conferences organized by CloudBees this year, lunch was not provided and conference program was "packed" into afternoon. This let praqma get a "reasonable" cost for this nice event, but still have a high quality conference, with printed programs, goodies, and coffee break. All praqma team was involved to make this event as pleasant as possible for all attendees, thanks a lot to them for contributing !

Conference was sold-out on friday morning, with 80 attendees.

After Lars Kruse welcome speak, and CloudBees to announce partnership with Praqma for DK, the conference started with two options : either an introduction to Jenkins, or an open-space discussion (~barcamp-like) for those that already know it well. I joined a small group first discussing about pre-tested commit, and then we divert speaking about best-practices, job and test performances issues, etc. Was a great exchange with interesting feedback.

The rest of the conference was single-track.


1rst session was about "facilitate strategic reuse of software" using jenkins CI. This session exposed how a industrial company changed it's internal software development practices and team organization to share components and be more efficient. This for sure introduced some coordinations and integration costs but resulted in a significant productivity improvement. This talk was interesting as it demonstrate that highly industrial companies (here, a low energy consuming water pumps producer) today follow development practice to share component and use continuous integration practice to help. I just wondered speaker said "Clearcase facilitated" sharing components  -I wouldn't expected those two words in same sentence :P

"Tales from the trenches" was a funny session explaining how Nokia came from stone age (manual integration with code freezes) to modern development practices. After reinventing the wheel with ~15 home made, perl-script based CI tools, they switched to Jenkins and Git as common tooling. Explanation on Git selection, evaluating multiple DVCS popularity, then migration from ClearCase, helping a lot early adopters, and later evaluating benefits (1 day / week / developer) was very interesting. Conclusion was that, "some tools a radically better" and "deep process renewal depends heavily on tools renewal".

"Continuous Code Inspection" talk explained use of industrial C++ coding standard and normative coding convention, with dedicated analysis tools. After explanation on those rules and tooling, a dedicated jenkins plugin was demonstrated. Such jenkins integration makes QA mostly a single checkbox to enable, and provide history graphs, reports, and external tools integration. Introduction was a little slow imho but content was demonstrating the power of jenkins plugin model to adapt software factory to specific industrial needs.


Coffee break with delicious Danish chocolates ...

Sony was presenting its "Huge Jenkins Cluster", with 4 master, some of them handling up to 6000 jobs, 300 slaves, 7000 builds a day an executing 175,000 tests a day for android platforms. Development teams use a dedicated slave machine with android devices connected through USB.

Such a build farm requires a dedicated support team and monitoring/maintenance tooling. IT only provides the computer and maintain the OS, but all Jenkins stuff is under the hands of a dedicated team. They evaluate plugins and core upgrades, educate teams, and analyse errors.

With 45Gb for a single full android build, they have to monitor available disk space, and developed maintenance scripts to delete old build artifacts and cleanup /tmp. They also use a local git mirror to speed-up cloning, and integrated with CFEngine-managed infrastructure to ensure no update occurs as a slave is running a build. They also significantly optimized build speed by switching from NFS to SAN, and are now evaluating XFS.

Remaining issue is about jenkins build queue (subject discussed on Jenkins Code Camp) because a 9 in the morning, thousand users connect to jenkins master and the UI widget to expose the queue status hits the queue synchronisation bottleneck.


Next talk was mine, exposing Jenkins Enterprise and demonstrating one ouf our Enterprise plugins. I'm not pleased by my talk, both because my english is crappy (maybe you already noticed?) and also because I was not confident with the standard JE slides. Assuming I jad more time to prepare this talk, and as a tribute to this Danish event, I'd have used a bunch of lego bricks pictures to present Cloudbee plugins. So I quickly left the slides to run a demo, setting-up Jenkins Enterprise to run pre-tested commits. Hope you enjoyed the talk.

Last talk was Lars one, exposing praqma "Corporate approach to opensource". This light, generalist talk was welcome as last one after a heavy-technical afternoon. Lars exposed reason to switch to open-source :

  • costs - for sure, 
  • but also open standards and interoperability, 
  • and contribution to public good. 
This last point distinguish "innovators" that create new content and contribute to the oss project, and "free riders" that only want to save money and consume other efforts. Lars didn't went deeper into what "contributing" can be about, but spending some time joining the mailing lists, exposing detailled bug report, or writing blogs or documentation about the issues you encounter is already a huge contribution to opensource. Organizing such a great user event also is ;)



Meeting ended with a "socialize" time, sponsored by Pragmatic Research, with beer and sandwiches. A nice time to discuss with speakers, know a face to match an #irc nickname, discuss about everything geeks like to discuss about, and round off this pleasant day.

So, back in France, and hope we can find volunteers, sponsors, and a low-cost location to get a comparable Jenkins User Event in Paris the day before Devoxx France 2013, stay tunned !





05 septembre 2012

un billet pour JavaOne

JavaOne, la grosse grosse conférence organisée chaque année à San Francisco pour évangéliser l'écosystème Java se déroulera la première semaine d'octobre, précédé le dimanche par la Jenkins User Conférence. 

J'ai tenté ma chance au call-for-paper sans succès, aussi j'ai voulu re-tenter en passant par le programme "press & bloggers". Demande envoyée début juin, restée sans réponse...

... jusqu'à réception de ce mail :



mail daté du 21 août, juste avant mon départ en vacances, autant dire qu'il est grand temps de s'organiser pour un départ aux "States" fin septembre.

Etape 1 : négocier avec mon employeur préféré pour une semaine quasiment chômée au support CloudBees (rassurez-vous, mes collègues assurent dans ces cas là). CloudBees étant sponsor de JavaOne, l'équipe marketing est ravie de pouvoir compter sur moi pour donner un coup de main.

Etape 2 : trouver un vol pas cher et un hotel ... et là  c'est pas le plus facile vu que JavaOne crée un véritable vide dans l'offre d'hébergement à San Francisco. Je serais finalement au Kabuki, raisonnablement pas trop cher et bien placé (1 mile). L'hotel, un peu moins cher, que j'avais trouvé sur booking n'a pas accepté mon paiement par carte bancaire !

Etape 3 : gérer les formalités administratives ... et là évidement mon passeport n'étant plus valide, ça se complique. A savoir que la préfecture met 1 mois et demi en moyenne pour produire ce document, aussi on passe par la case "lettre justificative de l'employeur" pour demander un passeport en urgence pour raison professionnelle. Dispo 10 jours plus tard. Reste à remplir le formulaire de visa "êtes vous un terroriste ? oui - non"...

Etape 4 : changer la date de la session de rentrée du BreizhJug, justement prévue le 1er octobre. Heureusement, Julien Dubois qui viendra pour cette occasion à Rennes est assez souple sur son agenda. Je dois aussi annuler ma proposition pour Agile Tour.

Etape 5 : annoncer à madame qu'elle va devoir gérer les 3 délinquants juvéniles pendant une semaine. Sachant que je pars déjà à Copenhague (Jenkins User Event) puis à la Rochelle (JugSummerCamp), juste pendant la rentrée scolaire, je sens qu'il va falloir être très très gentil, et que je lève le pied en Octobre pour la préparer psychologiquement à rempiler pendant Devoxx ...

La suite ... bientôt ! J'essayerais de vous faire vivre JavaOne en live sur ce blog (vu que c'est tout de même ce qui me donne mon billet, il va bien falloir faire le boulot).

13 août 2012

Pourquoi il ne faut pas aller voir le talk de Julien Dubois au JugSummerCamp

Le JugSummerCamp 2012 vient d'annoncer son programme. Je ne m'attarderais pas à essayer de vous convaincre de la nécessité de vous joindre à cette merveilleuse conférence, qui a su doser à la perfection décontraction et excellence technique pour une rencontre inoubliable (bref, un peu comme le BreizhCamp quoi :P)



Par contre, vous aurez peut être remarqué dans le programme la session de Julien Dubois. Voici donc 10 raisons pour ne pas perdre votre temps avec cette session :


  1. C'est le sujet qu'il a présenté à Devoxx, et que vous avez peut être déjà vu ou que vous pouvez consulter sur Parleys.
  2. Ca parle de Spring, HTML5, Rest, Cassandra, bref rien que des technologies sans grand intérêt.
  3. C'est programmé juste après le repas, autant dire qu'à cette heure là avec la digestion ça va être dur d'encaisser un cours magistral sur NoSQL
  4. Le sujet est l'application Tatami, le Twitter-like de Ippon. Tout le monde sait bien que ça ne sert à rien twitter, surtout en entreprise - d'où la configuration du proxy qui le bloque d'ailleurs.
  5. Julien sera au BreizhJug le 1er Octobre pour nous présenter ce même sujet avec plus de temps pour répondre à toutes vos questions, alors autant attendre un peu.
  6. A la même heure il y a une excellente session que je vous recommande vivement.
  7. Julien a un gros nez.

Je sais, ça ne fait que 7 raisons, mais je n'en trouve pas plus. Du coup je vais devoir mettre les bouchées doubles pour blinder la session concurrente. 

Consolation, ceux qui choisirons son sujet (très bon soit dit en passant, pour l'avoir suivi à Devoxx) m'auront tout de même accompagné le temps de la keynote, car le JugSummerCamp me fait l'immense honneur d'ouvrir cette troisième édition.

rendez-vous le 14 septembre !

09 août 2012

Debug en production

Avec toute la bonne volonté du monde, on arrive parfois pas à reproduire un bug et il faut donc tapper sur la production pour analyser ce qui s'y passe.

Je suis tombé sur ce cas et j'ai donc du mettre en place un remote-debugger sur nos machines de production. Comme je risque de ne plus me rappeler la procédure la prochaine fois, voici un pense bête.

Etape 1 : mettre le workspace local dans l'état du code distant. Ca peut paraître bête, mais ce n'est pas une fois le debugger connecté qu'il faudra se rendre compte que les sources ne collent pas au runtime !

git checkout dev-at-cloud-1.447.2

Etape 2 : établir un tunnel SSH. J'avoue être totalement novice en la matière et avoir fait appel à
Google pour trouver la commande miracle, très bien expliquée par Korben.


ssh -i ~/.ssh/operations-ci.pem -L 5008:localhost:5005 root@10.192.xxx.xxx

######################################################################
Unauthorized access to this CloudBees system is forbidden and will
be prosecuted by law. By accessing this system, you agree that your
actions may be monitored if unauthorized usage is suspected.
######################################################################


Etape 3 : relancer l'instance en mode debug. Il ne semble pas possible de faire "passer" un JVM en mode debug après son lancement, même avec des API propriétaires de la JVM Sun/Oracle. C'est dommage, ce serait sacrément pratique.


-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005


Et enfin étape 4, lancement du remote debug depuis Idea.



Bon évidemment, à traverser l'atlantique pour debugger la production c'est pas ultra véloce, mais c'est nettement mieux que de rester planté devant les logs vierges ;)


Une autre option, que j'ai testé quelques fois et qui à l'avantage de ne pas souffrir de la distance qui sépare mon portable des datacenters Amazon : YouDebug

YouDebug utilise lui aussi le port de remote debugging, mais n'est pas interactif comme l'est un IDE. Il utilise des scripts Groovy pour définir les actions à réaliser sur un point d'arrêt. Il est ainsi possible de tracer le passage dans des méthodes, chopper le valeurs des paramètres et dumper la stack d'exécution courante. C'est évidemment moins confortable, mais c'est tout de même très pratique.


04 août 2012

passez votre clavier à la machine

faites le bouillir ...

Pour un poste de travail confortable, j'ai branché à mon MacBook un clavier USB Apple avec pavé numérique. Comme il était plutôt encrassé, à l'occasion d'un grand ménage du bureau j'ai voulu le nettoyer avec un coup de pchitt + chiffon. Et là, grand moment de solitude au moment de reprendre le taf : la moitié des touches ne répondent plus. Quelques heures plus tard, le clavier ne donne plus aucun signe de vie. Et m..., 50€ de fichu en l'air (et oui, tarifs Apple)



Au hasard des forums, j'ai appris que certains avaient ainsi "cramé" leur clavier à coup de café renversé ou autres maladresses, et qu'on leur conseillait un passage au lave vaisselle, suivi de quelques jours de séchage, pour retrouver un clavier 100% fonctionnel.

J'avoue ne pas être très convaincu par la neutralité du lave-vaisselle, entre les 70° du bain de lavage, l'agressivité du produit et la chaleur du séchage en fin de cycle, donc je me suis contenté d'un bon lavage à l'eau chaude. Le clavier a ensuite passé 15 jours posé sur les touches (pendant mes vacances).

Retour à la maison, et bonne surprise, le clavier fonctionne parfaitement - et en plus, il est propre !



Bon, je ne dis pas que c'est la solution de nettoyage idéale, ni que ça marche à tous les coups [disclaimer] toute opération équivalente que vous tenteriez sera à vos risques et périls et ne sauraient engager ma responsabilité [/disclaimer] mais si comme moi vous pensez avoir fait la connerie de trop avec votre clavier Mac, vous savez ce qui vous reste à faire.



NB: je n'ai pas testé avec le MacBook passé à la machine à laver, si quelqu'un a essayé merci de se faire connaître d'urgence des services psychiatriques.

02 août 2012

L'été sera chaud

Depuis l'an dernier, je savais qu'il y avait une source quelque part dans mon jardin (ou plutôt, ma prairie). Rénovation d'une vielle grande, ancienne ferme encore habitée il y a 60 ans, je me doutais que les précédents habitants n'allait pas à la rivière pour chercher de l'eau, mais la fontaine (comme disent les gens du coin) présente était tarie depuis longtemps, et l'agriculteur avait fait poser un compteur d'eau - ce qui nous a bien arrangé au moment des travaux.

Sauf que ... avec les travaux de terrassement il semble que la source se soit dé-tarie. Déjà l'an dernier le bas du pré était bien humide et en creusant un peu on avait mis en évidence une petite source. Cette année, après un printemps pourri et un été pourri, avec une moyenne de 28 jours de pluie par mois, la source semble s'être renforcée.

C'est donc, de retour de vacances, directement dans mon jardin au pied de la maison que j'ai pu faire "flotch flotch" en marchant dans de l'herbe très verte. Après quelques tours de jardin j'ai finalement fait un "sgrrrr-plouch" enfonçant ma botte de 20 cm dans la glaise détrempée. J'appellerais ce point "point S.P."

Plan A : poser un drain et canaliser toute cette eau vers le fossé le plus proche, autrement dit ce que j'ai fait l'an dernier - la vie est un éternel recommencement.

En creusant au niveau du point SP je me suis rapidement trouvé submergé par l'équivalent d'un robinet ouvert, le tout à 10 cm de la surface. Du coup, c'est comme pour le lancement de java 7, on change de plan.

Plan B : creuser un puit ! Pour ceux qui se posent la question, voici comment on creuse un puit à la main :



  • Acheter des buses en béton de 80cm de diamètre minimum. Problème, ça pèse très lourd. J'ai donc pris des 80cm x 20cm qui sont manipulable à une seule personne. Les buses spécifiques pour puit de 1m x1m pèsent 350 kg !
  • S'équiper d'une pelle à manche court (pelle américaine), marteau+burin, seau à gravats, etc.
  • Poser une buse à plat sur le sol, se placer à l'intérieur, et creuser ...
  • Sous son poids, la buse va descendre dans le trou en cours de formation. Dès qu'elle atteint le niveau du sol on en place une autre par dessus, et re-belote. 

Le trou est ainsi étayé pendant le creusement et la mise en place des buses est facile. Par contre, on est un peu à l'étroit dans 80cm de diamètre, d'où un choix important de l'outillage et de la longueur des manches !

Pour info, après les deux premières buses, je suis passé des bottes au maillot de bain, car le trou se remplissant rapidement d'eau c'était ingérable. J'aurais du me faire prendre en photo tiens... La glaise détrempée se creuse quasiment à main nue, tant qu'on ne tombe pas sur une #&$£@! de caillasse.

A la troisième buse, j'ai du écoper pour "vider" le puit régulièrement afin de voir ce que je faisait. Si je veux aller plus profond il faudra investir dans une pompe vide-cave (qui accepte l'eau "chargée"). J'avoue hésiter, parce que l'exercice est assez fatiguant et un peu spécial. J'ai trouvé sur des forums des témoignages de fadas qui ont appliqué cette technique jusqu'à 6m de profondeur, faut pas être claustrophobe ! Et puis, j'ai déjà 50cm d'eau (soit 0,25 m3), sous réserve que la source reste aussi active quand (si ?) le soleil reviendra.


Reste à mettre un couvercle (avec les gosses, c'est SUPER dangereux ces conneries), à faire un joli habillage, et à évacuer les gravats.

Voila pour ce billet de mi-été. Peut être le début d'une reconversion comme puisatier ?

04 juillet 2012

Maven n'aime pas WebDav

Maven 2 disposait d'un client webdav pour le déploiement d'artifacts dans les dépôts de ce type
Maven 3, pourtant conçu pour être 100% compatible, n'a plus cet extension. 

La conséquence immédiate, c'est qu'il n'est plus possible de faire une "mvn deploy:deploy-file" vers ce type de repository. On est obligé d'avoir recours à une astuce pourrie, consistant à avoir un pom.xml bidon qui configure maven avec l'extension nécessaire, juste pour invoquer le deploy-file :

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelversion>4.0.0</modelversion>
    <groupid>com.example</groupid>
    <artifactid>webdav-deploy-pom</artifactid>
    <packaging>pom</packaging>
    <version>1</version>
    <name>Webdav Deployment POM</name>

    <build>
        <extensions>
            <extension>
                <groupid>org.apache.maven.wagon</groupid>
                <artifactid>wagon-webdav</artifactid>
                <version>1.0-beta-2</version>
            </extension>
        </extensions>
    </build>

</project>


Ca c'était pour l'astuce du jour.
On peut aussi chercher le pourquoi de cette incompatibilité. 

  • Il faut admettre que le composant wagon-webdav, péniblement amené à une version 1.0-beta-2 est un morceau de code assez obscur et peu maintenu. Dans la refonte générale à l'origine de Maven 3, il n'était pas aberrant de le mettre au placard.
  • Il faut aussi admettre que c'est un protocole assez merdique, qui va nécessiter 40 requêtes HTTP pour tester puis créer chaque niveau de répertoire pour finalement n'uploader qu'un unique fichier  - avis personnel, il a sans doute aussi des avantages.
  • Il faut aussi savoir que Nexus gère le déploiement en HTTP POST "brut" et crée la hiérarchie de répertoires à la volée. Je ne suis pas sur pour Artifactory ou Archiva mais c'est bien possible qu'ils fassent de même vu que dans ces systèmes le "groupId" n'est plus un répertoire mais un identifiant logique. Tous ceux qui utilisent ces outils n'ont donc que faire de ce wagon-webdav.

Cependant, aujourd'hui le projet Apache Maven dispose d'un nouveau composant WebDav basé sur jackrabbit, 100% fonctionnel, bien conçu et supporté. Le premier argument saute. Le second est discutable, mais si on n'utilisait que des outils et des protocoles bien foutus on ne ferait pas grand chose de nos ordis. Quand au troisième... il me semble que le retour de WebDav dans maven 3.0.x serait la preuve que le projet est indépendant de tout éditeur.

Enfin, je ne voudrais influencer personne ;)

22 juin 2012

One Year at CloudBees

Et oui,  un an déjà passé chez CloudBees !



Cela fait en fait un an et une semaine, mais BreizhCamp oblige j'ai un peu laissé filer la date.

Mon bilan ?

J'ai rejoins une équipe exceptionnelle. CloudBees s'est entouré de pointures, et je me sens souvent bien petit, mais j'en prends plein les yeux. Vous connaissez buildhive ? Il y a quelque temps Kohsuke nous en parlait comme un petit projet rigolo développé pendant ses vacances. Et n'allez pas croire que c'est un cas isolé ;) Avec une équipe composée d'ex-SUN et d'ex-JBoss, on est servi.

J'apprends tous les jours, je découvre via l'activité support les méandres de Jenkins et ses multiples utilisations, ainsi que les mile et une subtilités de la gestion d'une plateforme Cloud. Je prend aussi un grand bol de DevOps chaque jour, avec comme guides Ben Walding (Mr infra chez codehaus) et Ryan Campbell (Architecte DEV@Cloud) . Je prépare un sujet dessus, j'espère avoir l'occasion de vous en reparler

Je travaille de chez moiAucun frais de transport ni temps perdu dans les bouchons, ça libère du temps efficace pour bosser. Sans perturbations, j'ai rapidement été impressionné par la productivité qu'on peut atteindre. Les premières semaines on été dures, car la concentration est telle qu'il faut apprendre à "quitter le boulot" le soir  et à se ménager des pauses (pause aspirateur, pause sortir les poubelles, ... :P). Depuis j'ai pris mon rythme, et - rassurez-vous - le contact de mes collègues ne me manque pas. J'ai troqué les discutions à la machine à café sur le dernier match contre une place dans l'association de parents d'élèves.  

Je travaille avec des méthodes légères. Je ne dirais pas "agile" parce que, télétravail oblige on est pas dans un cadre qui s'y prête et je m'attirerais les foudres de certains puristes, cependant l'équipe applique les principes d'auto-organisation, d'amélioration continue, de simplicité et de pilotage par la valeur utilisateur. Nous travaillons beaucoup avec Trello pour la gestion de tâches, IRC ou skype pour la communication. Il y a évidemment plein de choses qu'on devra expérimenter et améliorer, ou qui ne fonctionneront plus quand la société aura grossis, mais c'est un contexte qui change de MS Project.

Je suis libre de mon tempsJ'amène mes gosses à l'école chaque jour, je suis libre de mes horaires, et ça, c'est une régal. En gros, start-up oblige, il y a du boulot autant qu'on en veut, et le tout est de faire le maximum sur les tâches les plus prioritaires pour faire avancer le schmilblick. Ca veut aussi dire donner parfois de son temps en soirée (l'équipe étant fortement localisée aux US), ou le week-end, mais aussi pouvoir prendre une heure dans la journée sans prise de tête, ou aller prêcher la bonne parole dans les JUGs sans poser un RTT. 

Je peux (enfin) boire du bon caféJ'ai aussi un accès Internet qui dépote (et encore, j'habite en bout de ligne), sans proxy à la con. J'ai une vraie machine de développement, sans antivirus merdique et avec plus de 3.25Gb de mémoire - machine que j'avais déjà chez Orange, mais installée en douce. Par contre je n'ai plus de photocopieuse relieuse trieuse recto-verso couleur 200 pages/minutes. En même temps j'avoue ne plus en avoir tellement l'usage.

Je n'entre plus dans les cases de la sécu. J'ai été en arrêt une semaine pour une pneumonie et, clairement, bosser en France de chez sois avec une entreprise dont le siège est en suisse et la maison mère immatriculée dans le Delaware, ben s'est pas prévu dans le formulaire. J'ai pourtant un contrat de droit français, aussi je n'ose pas imaginer ce que ça doit être dans des cas plus exotiques.

J'ai fait de vagues progrès en anglais. Mon accent est toujours aussi pourri (je cite ma femme qui enseigne cette langue aux primaires et qui a un très bon niveau) mais l'oreille s'est affinée, et j'ai même apris quelques mots, comme "awesome" et "onward" :)

Bref, je rempile ;D