21 juin 2011

multi-tenancy

"Java EE 7 sera Cloud"
Voilà une annonce pleine de bonnes intentions, mais qu'en est-il concrètement ?

Les démos, comme celle de Spring/VMWare lors de What's Next pour CloudFoundry ne nous montrent que l'abstraction faite sur la gestion des infrastructures, OS et middlewares : truc app dans une console, et hop j'ai une appli en ligne, truc db et hop, j'ai une base MySQL... Les utilisateurs de Heroku doivent bien rigoler de nous voir admiratifs devant ce spectacle !

Il y a un second aspect qui est nettement plus délicat à percevoir, qui du coup fait moins l'objet des démos, et qui sera - j'espère - au centre des discutions de l'expert group Java EE 7, que Spike Washburn (celui qui a conçu RUN@Cloud) va rejoindre : la gestion multi-tenant. Je fais mon savant là mais je n'ai compris ce concept que récemment lorsque mes collègues de CloudBees m'ont fait une explication de texte ;)

Pour expliquer ce concept, nous allons ensemble - virtuellement - construire un SaaS. Je vais donc dérouler les différentes variantes de ce que j'ai pu mettre en oeuvre.

1. Serveur mutualisé

Dans le but de réduire les coûts de mise en oeuvre et d'administration, c'est la première chose qu'on met en place. Dans mon cas, un proxy Internet pour les dépendances Maven. On réserve donc une bonne bécane et on installe un repository manager, Archiva dans mon cas (je participais à son développement à cette époque).

Avantage : une seule instance, c'est simple à comprendre et à administrer
Inconvénients : pollution mutuelle entre utilisateurs, qui ont tous une librairie machin à installer. En gros, on impose à tous une logique commune, ce qui fait préférer à certains d'avoir leur propre dépôt et de le gérer eux-même pour retrouver une certaine liberté même s'il faut payer le coup de mise en place.

Je ferais un parallèle avec SVN vs Git : le fonctionnement du système centralisé s'impose à tous et devient pénalisant.


2. Clonage de VM

Ici on met à disposition un environnement type qu'on est en mesure de mettre en place en quelques minutes. L'utilisateur peut alors adapter à ses besoins un canevas de base, qu'on aura éventuellement bridé si nécessaire, ou au moins préparé avec les pratiques généralement acceptées. Exemple type, une image VM Linux avec Git/svn + Nexus + Jenkins + Sonar + Java/Ant/Maven préinstallés.


Avantage : on démarre en quelques minutes, et chacun peut faire ce qu'il veut
Inconvénients : la mise à jour des instances existantes reste une tâche d'administration pénible.  Le clonage des VM ne permet pas de mutualiser / centraliser ces opérations. Lorsqu'une nouvelle version de Jenkins arrive, qui fera la mise à jour ? Qui pourra valider son fonctionnement. On s'attendrais à ce qu'une phase de qualification permette ensuite de déployer la nouvelle version sur toutes les VM clonées, avec peut être possibilité de débrayer cet update automatique. 

Le parallèle qui me vient à l'esprit ici c'est la gestion du parc de PC, souvent basée sur le clonage d'image système puis création du compte utilisateur à la main. Sauf que nos administrateurs disposent de Windows Update pour assurer la maintenance, sans quoi il faudrait toutes les semaines venir faire la queue à la logistique pour obtenir les correctifs adéquats.




3. Création automatisée des VM

On monte d'un cran et on exploite les outil de déploiement continu pour construire nos images de VM à partir de "recettes" (pour reprendre le vocabulaire de Chef). La mise à jour d'une recette se traduit par une mise à jour de toutes les instances, et l'élimination de la redondance dans les tâches d'administration. Autre avantage par rapport au clone, il est possible d'utiliser un OS différent vu qu'on a scripté l'installation.


Avantage : gestion centralisée et automatisée
Inconvénients : sur-consommation de ressources. Je ne l'ai pas évoqué ci-dessus, mais nos VM par projet consomment de nombreuses ressources sur la machine physique de notre data-center. Même si l'hyperviseur fait de son mieux pour répartir la charge, chaque instance "up" consomme mémoire, cpu et I/O. 

La tarification d'Amazon EC2 en est d'ailleurs le reflet : on paye certes à la minute, mais une instance de serveur web qui reste démarrée est facturée pour un temps plein, car un serveur web qui ne fait rien ... consomme tout de même cpu, mémoire et I/O ! Ceux qui ont démarré une instance EC2 pour faire un test et ont "oublié" de l'éteindre en ont eu pour leurs frais :P La virtualisation a cet effet pervers qu'on a tendance à laisser tourner des VM sans réaliser ce qu'elle coûtent réellement, et par voie de conséquence d'obliger à surdimensionner les machines physiques (ou la facture).

Le parallèle cette fois ce serait un serveur sur lequel on fait tourner 100 instances de Tomcat avec le war Jenkins déployé, consommant 100 fois la mémoire nécessaire malgré les effort de l'OS pour swapper les processus inactifs, et obligeant l'admin à commander quelques Go de mémoire supplémentaire.

Imaginons à présent la même machine avec un seul Tomcat musclé et 100 webapps déployées dans des contextes dédiés. On économiserait au moins l'empreinte mémoire du serveur et de la JVM. Le problème serait alors d'assurer l'indépendance, la performance et l'étanchéité de chaque webapp pour qu'elle ne voit pas "par erreur" les données de sa voisine. Sans parler de l'empreinte mémoire de nos 100 instances de la même webapp qui pèse tout de même 80Mo à grand coup de Spring+Hiberante+CXF+<votre-framework-préféré>. D'où le concept de ...

4. Application mutli-tenant

Le cas le plus connu de multi-tenant c'est la notion de virtual-host dans Apache HTTPD : le même serveur web gère les requêtes de plusieurs sites web (du point de vue de l'utilisateur) et détermine ce qu'il doit faire en fonction du nom de serveur invoqué.

Imaginons que notre serveur JavaEE soit étendu pour proposer une fonctionnalité bien spécifique : une seule application jenkins.war est déployée, mais en fonction du virtualhost par lequel les requêtes HTTP arrivent "monAppli.serveur.com", il va basculer dynamiquement les ressources vers un répertoire dédié /var/lib/jenkins/monAppli. Il va faire de même pour notre DataSource qui pointera vers jdbc/monAppli, nos files JMS, nos fichiers de log, etc.

Ce serveur JavaEE++ magique, c'est un serveur prêt pour le Cloud ! En installant une instance de ce type en frontal nous serons en mesure de gérer la diversité de nos instances du même service, puis de distribuer la charge de travail sur un pool de machines (ce que propose déjà Jenkins via ses esclaves, et qui du coup le rend particulièrement éligible à cette évolution, comme le prouve DEV@Cloud).

C'est cela qu'on attend de la norme Java EE 7 lorsqu'on parle de "multi-tenancy". 

Pour le développeur, cela signifiera très probablement quelques aménagements. aussi il est important de comprendre ce concept si vous voulez suivre les débats du JCP sur le sujet (la liste de discussion est accessible en lecture seule à tous ceux qui veulent prendre le temps de la suivre).

Si ce sujet vous intéresse, poursuivez la lecture via cette série d'articles :

16 juin 2011

Jenkins au JugSummerCamp

Le BreizhCamp est déjà commencé avec l'atelier Git que Sébastien Douche anime en ce moment même, avec comme objectif simple de sauver le monde.

Surprise de la programmation des conférences de demain, et je vous jure que je n'y suis pour rien, j'animerais en fin de journée une session en concurrence avec celle de Julien Dubois, ce qui nous rappèle d'excellents souvenirs du JugSummerCamp 2010 !

Aura t-on droit à la revanche de Julien ? J'en doute, car sincèrement, qui irait voir une n-ième session barbante sur Hibernate, NoSQL et le Cloud, alors que vous pourriez conclure la conférence sur une présentation sur la gestion de projet atypique de Jenkins et quelques clés de son exceptionnel succès.

La réponse de Julien sur son blog ne devrait pas tarder ;)

02 juin 2011

CloudBees @ Jax

CloudBees sera présent à la conférence JAX, fin juin à San José.


San José, c'est beau, mais c'est loin (comme dirait un ex-président bien connu), aussi ce n'est pas de la conférence que je vais vous parler mais du vote que les organisateurs proposent aux internautes sur http://vote.jax-awards.com/, destiné à élire la technologie, la compagnie et la personne la plus innovante de l'année dans le microcosme Java. Je n'ai aucune idée de la façon dont a été faite la short-list qui nous est proposée, mais je suis fier d'y trouver CloudBees, au côté de pointures comme Atlassian et RedHat.

Le système de vote n'utilise pas d'authentification des utilisateurs et pourrait donc faire l'objet de truandages  divers, mais il permet de voter sans laisser votre eMail dans une liste de spam. Votez si possible pour une société sympa, innovante et bourrée de mecs cools, mais bon je ne voudrais pas vous influencer ;)

Si vous n'arrivez pas à vous décider, vous pouvez aussi rejoindre Sacha Labourey lors d'un webinar mercredi prochain pour une présentation de CloudBees et une démo de la chaine code -> build -> tests -> run "dans le cloud". C'est en anglais, mais avec ce petit accent Frenchie si particulier que le monde entier nous envie :P

Plus que 10 jours pour moi avant de rejoindre l'équipe CloudBees, je trépigne d'impatience ! Des chantiers passionnants à affronter, mais sans doute le plus beau challenge qu'il m'ait été offert de relever.

29 mai 2011

Merci Zenika!

Cette semaine, vous n'avez pas pu y échapper, c'était What's Next. Je n'ai pas pris le temps de blogger sur le sujet parce que j'étais bien trop occupé à profiter à plein de ce grand moment organisé de main de maitre par Zenika, et à discuter avec les nombreux Geeks de notre microcosme. Si vous voulez en savoir plus lisez le blog de l'autre Nicolas, moi la nuit j'ai besoin de dormir au moins un peu ;)

Autant les conférences que les échanges très fertiles qu'on a lors de ces rencontres sont une véritable mine.
Il y a bien sur les aspects techniques : J'y ai, entre autre, découvert la commande Git ReReRe (j'ai d'abord cru que Benoît Courtine se foutait joyeusement de moi avant d'aller vérifier) qui m'a obligée à modifier en urgence ma présentation (voir plus bas).
Il y a aussi les aspects sociaux, avec toutes ces personnalités connues et moins connues qui font la richesse de notre milieu. Une idée d'ailleurs pour les prochaines conférences : en plus des noms , mettez le compte twitter des participants sur les badges, nous sommes nombreux à nous connaitre par ce biais sans le savoir.

Moralité : si vous n'y étiez pas, dites vous bien que vous avez raté un grand moment de geekitude et de techno-remise à niveau. Si j'ai du poser deux jours de congé pour en profiter je suis très loin de les regretter !

J(enkins)UG
Non content de participer activement, comme toute l'équipe Zenika, à l'organisation (irréprochable) de What's Next, Grégory Boissinot nous a offert en cette fin de semaine un concentré de Jenkins. A peine remis de ces 2 jours de conférence plutôt denses, nous avons attaqué par un Jenkins User Meeting vendredi soir, en petit commité dans les locaux de Zenika. Sous forme de mini-conf nous avons ainsi pu présenter notre utilisation de Jenkins, nos bonnes pratiques, voir nos contributions pour certains. Un moment d'échange riche et plein d'enseignements.

Une idée sympa et ouverte à tous, à retenir pour des événements locaux.

Pour ma part j'ai présenté mon approche de l'intégration continue couplée aux multiples branches Git, en tentant une démo qui a été un vrai massacre à la bonaldi (sans quoi ce ne serait pas une démo me direz vous).  Mais l'événement de cette rencontre c'était la présence de Kohsuke Kawaguchi de passage à Paris, un gars étonnant, qui du haut de son mètre 90 vous parle d'une voix ultra grave, pas vraiment le Japonais des images d'épinal.

Après une courte nuit de repos, nous enchaînons par un hackathlon dans les locaux de Zenika. Le hackathlon, c'est quelques "hackers"ou apprentis-hackers (9 dans notre cas, on a perdu du monde en route semble t-il) qui se regroupent pour travailler sur des sujets communs et surtout s'entraider. En une petite journée j'ai appris de nombreux détails du développement Jenkins, avec les explications très précises de Kohsuke, tandis qu'Arnaud s'attaquait à une amélioration de l'intégration Maven, enchaînant les Pull Request, que Gregory et Frédéric discutaient sur la complémentarité de leurs plugins respectifs de gestion de configuration et que Dimitri prenait un cours particulier de développement Jenkins avant de se lancer dans une amélioration de l'usabilité (oh le joli mot) de l'outil.

Chacun à son niveau a beaucoup de chose à apprendre des autres et autant à leur apporter. J'ai ainsi aidé Dimitri à configurer son compte GitHub et à monter sa Pull Request tandis qu'il m'a déplombé la configuration i18n de mon editeur de Ressources sous Intellij Idea. Kohsuke était évidemment un acteur précieux de cette journée; accessible, toujours agréable et très ouvert à toute forme de discussions, il nous a ouvert les portes de son bébé tout en nous laissant une complète liberté de notre sujet.

Le modèle de gestion de la communauté Jenkins, unique à ma connaissance, à cette particularité : même le premier newbie venu (tiens, moi par exemple) peut demander les droits sur GitHub et voir où sa contribution pourrait être bénéfique. La plateforme Jenkins à un tel potentiel que chacun y trouve rapidement de quoi faire, quelque soit sont niveau technique. Etant donné le public déjà très limité prêt à se lancer dans l'exercice, nous donner ainsi carte blanche est finalement peu risqué car chacun de nous se sent alors responsabilisé et ne prend pas le risque de modifier quelque chose qu'il ne comprend pas sans demander un avis. C'est ainsi que Jenkins a monté sa très large communauté de plugins et de contributeurs, bien loin du modèle de nombreux autres projets opensource pour lequel le billet d'entrée est très sélectif et en décourage beaucoup. Et après tout, par définition le SCM permet au besoin de revenir en arrière et d'éliminer une maladresse, régression, indélicatesse ou grosse boulette.

En sortant de cette journée, on a la sensation d'appartenir pleinement à une communauté, avec des
liens étroits - twitter peut en témoigner - une grande complicité et des valeurs fortes; on a les réponses à de nombreuses questions, et surtout l'envie d'aller plus loin; on en arriverait presque à penser qu'un monde meilleur est possible :P

Conclusion
Chacun de nous a en tout cas apprécié ces moments étonnants et d'une richesse incroyable. Un grand merci à Zenika d'avoir organisé ce beau rassemblement, à Kohsuke pour sa disponibilité alors qu'il accumule le décalage horaire, et bien sur à tous les geeks qui font de notre communauté Java française un terreau fertile.

Rendez-vous au breizhCamp pour certains, au JugSummerCamp et/ou à Devoxx pour les autres, en tout cas ne laissez plus passer ce type d'événement "juste" parce que ca tombe avant un week-end et qu'il y a un barbecue de prévu chez tonton André. Remontez-vous le moral et le niveau technique après une journée de m... sur un projet en TMA en développant sur quelques minutes de temps libre votre propre plugin jenkins/maven/graddle/idea/Androïd ou que sais-je, au moins pour être fier d'un truc sympa, dans une techno innovante, et qui pourrait même vous mettre faire entrer dans ce qu'on commence à appeler la  "french Mafia" (terme que l'on doit à @olamy il me semble), avec son accent inimitable quand elle s'exprime en anglais - soyons en fiers et faisons la grossir.

09 mai 2011

Bzzzzzz

D'ici quelques semaines, je quitterais mon poste au sein d'Orange Business Services (date non encore fixée). J'y ai rencontré des gens passionnés et passionnants, mais je vais donner une tournure nouvelle à ma carrière professionnelle en m'installant dans les nuages.


"2011, l'année du Cloud" entend-on un peu partout. Pour ce qui me concerne, ce sont les sirènes de CloudBees qui m'ont séduit. Une équipe d'exception, une entreprise ultra dynamique, un projet enthousiasmant, et un challenge à relever, de quoi me motiver à bloc !


Pour ceux qui ne connaissent pas, CloudBees est l'un des acteur du PaaS Java, techno en core émergeant mais promise à un très bel avenir (on parle d'une normalisation dans JavaEE 7...).


  • Avec DEV@Cloud, CloudBees propose de virtualiser la forge logicielle. Son produit phare, articulation de la forge, c'est l'intégration continue Jenkins "as a Service". Des plugins spécifiques permettent de tirer parti de la virtualisation (exécuteurs à la demande par exemple) et des partenariats permettent de l'enrichir avec des offres d'inspection continue Sonar "as a Service" ou des tests Selenium (SauceLabs) "as a Service", et bien plus encore à l'avenir. 

  • Enfin, une offre commerciale plus classique pour un Jenkins custom enrichis de plugins maison (Nectar) maintenu par Kohsuke Kawaguchi en personne, en concurrence directe avec le Hudson Profesionnal de Sonatype.


Je vais donc muter mon Chocobo en Choco-Bee, pour rejoindre ce projet ambitieux et les milles-et-une idées qui sont encore en murissement.

 --> 
Mon poste sera majoritairement focalisé sur le support, en contact direct avec l'engineering, mais aussi avec de nombreuses autres casquettes dans le développement (le temps de rentrer dans le code), du consulting, de l'assurance qualité, de la formation ... bref, un poste "couteau suisse" qui colle très bien à mon passif.

Particularité de CloudBees, la société elle même est dans le nuage : je travaillerais donc à domicile la majorité du temps, en collaboration avec mes collègues répartis de la west coast jusqu'en nouvelle zélande - l'occasion aussi de renforcer mon Anglais qui manque cruellement de pratique.


J'espère avoir le plaisir de vous rencontrer comme client, partenaire, lors du BreizhCamp, de What'sNext ou Devoxx, ou simplement à l'occasion d'un JUG sur un sujet "forge logicielle", qui devient donc définitivement ma marque de fabrique ;)

05 mai 2011

Hudson/Jenkins, episode V : l'empire contre attaque

Dans l'épisode précédent, Sonatype s'était allié à Oracle pour supporter Hudson, tandis que la rébellion s'organisait pour développer Jenkins avec le succès qu'on a pu constater.

Aujourd'hui, Oracle annonce vouloir donner Hudson à la fondation Eclipse (avec le soutien de Sonatype et VMWare), acceptant ainsi au final les conditions qui étaient réclamées par la communauté lors de la "crise" :
  • disposer d'un modèle de gouvernance sans prédominance d'une société
  • libérer le nom "hudson" de toute emprise en le léguant à un organisme indépendant

Ces conditions, à l'époque, se sont heurtées à un "non" sans appel de la part d'Oracle. Aujourd'hui, sans doute calmé par le succès de Jenkins fàce à un Hudson qui a du mal à exister autre part que sur le blog de Sonatype qui met en avant sa version "pro", Oracle change son fusil d'épaule.

On pourrait presque imaginer les deux branches fusionner à nouveau dans un grand moment de réconciliation, mais c'est assez peu probable.

D'une part, cette décision arrive bien tard. Jenkins a évolué depuis la scission, la communauté a pris ses aises et choisi son modèle de gouvernance. Il n'est pas du tout évident que celui de la fondation Eclipse soit aussi souple :P

D'autre part, la querelle avec Oracle a laissé des cicatrices; s'il ne s'agit pas de régler ses comptes, les principaux acteurs se voient mal travailler main dans la main comme si de rien n'était.

Enfin, passer le code de Hudson dans la fondation Eclipse ne se fera pas en deux minutes. Le processus d'incubation de la fondation est très strict (pour ne pas dire lourdingue), en particulier sur les aspects propriété du code et compatibilité des licences. C'est pour cela d'ailleurs que l'IDE Eclipse n'a pas de support SVN natif, l'implémentation Java SvnKit étant sous licence LGPL. Sans parler d'ailleurs du code pour lequel Oracle n'a pas a priori la propriété intellectuelle (pensez aux contributions de Kohsuke après qu'il ai quitté Oracle).

L'idée de voir Jenkins hébergé par la fondation Apache a été évoqué à un moment pour donner plus de visibilité au projet et lui assurer un cadre juridique solide. De la même façon, Jenkins devrait passer par l'incubateur Apache et résoudre les mêmes soucis de propriété intellectuelle et de licences.

Au final, cette contre-attaque est délicate à pronostiquer. Avec les moyens de Oracle + Sonatype + VMWare et la force de communication liée à l'aura de la fondation, Hudson peut rester sur les rails et progresser de manière intéressante. Dans le même temps, Jenkins démontre sa capacité à avancer vite et bien, avec :

  • un nouveau processus de release à deux vitesses, avec une version "stabilisé" par tranche de 3 mois n'incluant que les corrections majeures
  • plus de soin dans la gestion de la compatibilité, avec un mécanisme de test des plugins sur la version N+1 (action menée par notre compatriote Frédéric Camblor)
Il nous reste à attendre le prochain épisode. Je ne pense pas que le Jedi veuille bien revenir pour détruire l'étoile noire, et les deux outils continueront probablement à vivre côte à côte pendant longtemps. En tout cas, nous aurons assisté à un formidable gâchis depuis l'intervention de l'empire et de son allié dark vador (je vous laisse mettre des noms en fàce par vous même).

01 mai 2011

Portes ouvertes

C'est aujourd'hui que s'ouvre l'inscription du BreizhCamp

La salle qui nous accueille étant strictement limitée à 200 places, nous sommes contraints de mettre en place un système d'inscription. Si les Rennais ne sont pas coutumiers de ce principe, nos amis Parisiens savent que les places pour ce type d'événement partent très très vite, aussi ne trainez pas trop ...

Et si votre employeur rechigne à vous libérer une journée, vous pouvez faire valoir votre D.I.F pour nous rejoindre.

infos et programme : http://www.breizhcamp.org/
inscription : http://jugevents.org/jugevents/event/36125

19 avril 2011

JPA, et après ...

Ceux qui suivent ce blog connaissent déjà Fonzie, mon petit hack pour éliminer l'écriture de toute la couche persistance d'une application JavaEE dans le cas des requêtes simples, qui constituent d'après le projet sur lequel il a été utilisé plus de 90% des cas d'utilisation.

Avec une API puissante, JPA nous permet de construire des requêtes et du code d'accès à la base pour quasiment tous les cas de figure (bien sûr il reste quelques exceptions, sinon le groupe de travail JPA 2.1 serait au chômage). Seulement, cette API est parfois surdimensionnée pour des requêtes simples, de la forme select * from Truc where bibi = 'foc'

Fonzie était inspiré par Grails (GORM), mais n'est pas, loin s'en faut, la seule tentative de simplifier le codage des accès à la base de données. Il y avait déjà Hades, présenté il y a deux ans à Devoxx, qui permet de déclarer un Repository sous forme d'interface et de laisser le framework analyser les noms de méthodes pour en déduire les requêtes. Il y a depuis peu Spring-Data et son module JPA qui reprend la même idée avec la force de frappe de SpringSource/VMWare.

C'est bien, mais certains (j'en suis) regretterons que tous ces facilitateurs ne valident pas les requêtes définies par les programmeurs. Il faut attendre l'exécution pour que le framework nous indique qu'une méthode ne peut être interprétée. Un refactoring de trop et hop, tout plante.

Pour répondre à cette attente il y a donc, depuis JPA 2.0, l'API Criteria. Contrairement à Hibernate Criteria, celle-ci est totalement type-safe et valide la construction des requêtes dès la compilation. C'est donc une très bonne chose a priori. Sauf que ... Criteria s'impose de couvrir 100% des capacités de JPQL, et aboutit à une syntaxe extrêmement lourde et très peu lisible; jugez plutôt, pour la même requête pourtant triviale :

CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<truc> query = cb.createQuery(Truc.class);

        Root<truc> truc = query.from(Truc.class);
        query.where(cb.eq( truc.<string>get( Truc_.bibi ), "foc" ));

        TypedQuery<truc> tq = em.createQuery(query);

L'informatique semble avoir horreur du vide, aussi un framework se propose de combler ce manque de lisibilité. L'idée est de générer (avec un annotation processor Java6) un métamodel qui soit spécifique aux requêtes QueryDSL (les classes Q*), et pas juste le métamodel "neutre" défini par JPA (mais qui par contre pourait servir à d'autres frameworks ... si l'API était sortie du package javax.persistence). QueryDSL, qui d'ailleurs peut accéder à bien plus que JPA, propose de construire des requêtes avec une excellente lisibilité, et 100% type-safe :

import static QTruc.truc;

   public List<Truc> getBibiFoc() {
        return from( truc )
              .where( truc.bibi.eq( "foc" ) )
              .list( truc );
   }

C'est pas beau ça ? Aux parenthèses près, on se croirait sous .Net en train de coder avec LINQ !
Alors, évidemment, il est probable qu'en creusant un peu queryDSL ne supporte pas 100% de JPQL, et ne permette pas de faire un LEFT OUTER JOIN sur une Map d' Embeddable, mais en même temps, le jour où j'aurais vraiment besoin de ça, ce n'est pas de coder le Repository qui exécute cette requête qui va me coûter mais plutôt de comprendre comment on a pu pondre un modèle pareil...

01 avril 2011

deloof++

Si vous me suivez sur twitter (@ndeloof) vous savez que je suis papa pour la troisième fois. Oui, annoncer une naissance sur twitter c'est bien un truc de geek, je suis d'accord avec vous, mais je me sens moins seul quand je vois vos messages de félicitation. Celui de Laurent m'a bien fait rire :

public class HuitiemeMerveilleDuMonde implements Bebe {
 
    @Override
    public String getNom() { return "DE LOOF"; }
 
    @Override
    public String getPrenom() { return "Mat :-)"; }
 
    @Override
    public Sexe getSexe() { return Sexe.GARCON; }
 
    @Override
    public double getTaille() { return 53.0d; }
 
    @Override
    public double getPoids() { return 3.400d; }

    @Override
    public String getFelicitations() { 
        return "BRAVO au papa et bon repos à la maman..."; 
    }
 }

Ceci dit, nous sommes ici sur un blog technique, et Laurent se désole de ne pouvoir faire de l'héritage multiple. Je lui propose donc d'utiliser l'AOP !

@Aspect
public class Nananere {

    @Before(" execution( +Parent.dormir() )" )
    public void ouin_ouin() {}
}

Merci à tous

PS: non, très bizarrement, nous ne l'avons pas appelé "Jason"...

UPDATE:
J'apprend à l'instant que ce billet n'est qu'un vague réchauffé de celui-ci. Désolé, je n'ai pas pris le temps de vérifier mes sources pour une fois

23 mars 2011

"à la Facebook"

Mon twitter (1) me pousse cet article très intéressant : http://framethink.wordpress.com/2011/01/17/how-facebook-ships-code/

On y découvre le mode de fonctionnement de Facebook, ou comme le géant du web utilise la culture geek pour piloter ses développements. Ce que je note, c'est l'importance et la liberté données aux ingénieurs, et la contrepartie : l'engagement qu'on leur réclame.

Je vais tenter de résumer l'article en quelques lignes (en tout cas, les points qui on retenu mon attention...)

 
Facebook ce sont des ingénieurs, triés sur le volet, qui bossent en totale autonomie sur le sujet qui leur plait, avec éventuellement un Product Manager qui essaie de leur souffler des idées. Un PM pour 7 à 10 développeurs, ça me laisse rêveur - on aurait presque l'inverse en France parfois. Chaque développeur a une semaine pour monter son truc, de l'UI au backend. Les premières semaines dans la boite, le "bootcamp", leur permet de découvrir tous les rouages du site et d'être autonome par la suite - pour ceux qui arrivent à suivre. Quand on vous dit "triés sur le volet"...

Cette liberté totale et le manque d'emprise des PM sur le projet est à contre courant de tout ce que j'ai pu rencontrer jusqu'ici :) D'un autre côté, avec un cycle de release très rapide, ça ne doit pas être aussi anarchique qu'on pourrait le croire a priori. Sur des projets de 6 mois évidemment ce serait ingérable, mais si on compte en jours ?

La contre-partie de cette très grande liberté est que les développeurs sont ici partie prenante du projet avec une très lourde responsabilité. Sans doute facilité par une connaissance de l'ensemble du SI et pas juste d'une brique isolée, les ingénieurs assurent le reporting, ils sont le contact direct pour toutes les questions relative au projet. Autrement dit, ils incarnent implicitement le rôle de PM. D'autre part, il y a le mardi.

Le mardi, c'est le jour de la mise en prod - oui, une par semaine, ça surprend toujours tant cette notion  est lourde dans nos contextes traditionnels. Tout les développeurs qui ont introduit du code doivent être présents sur site et disponibles. Ne pas répondre aux demandes des Ops et/ou ne pas supporter un bug détecté dans son code est un motif de licenciement. Et avec 60.000 serveurs à mettre à jour, il doit y en avoir quelques unes des demandes de la part des Ops !

On rentre dans une logique différente, un esprit de responsabilité que la culture MOA/MOE, forfait, prestataire nous a fait perdre : on ne développe pas juste du code, on développe du code qui doit tourner en production. La logique DevOps semble particulièrement mise en pratique chez Facebook.

Pourrait-on appliquer cela ailleurs ? 

Je vous vois venir, je ne parlerais pas de mon cas personnel. Par contre, globalement il y a des lessons à retenir :

  • On ne motive pas des développeurs en les infantilisant. Les ingénieurs ont besoin de créer quelque chose, d'en être fier, et de le porter au yeux de leurs pairs. Arrêtons de leur affecter des tâches, de leur imposer des roadmaps à plusieurs mois. Evidemment, cela passe par un raccourcissement des cycles de production. Compter en mois (voir en années) cela impose une planification. Compter en semaines cela permet de tenter des choses, de laisser une part d'inconnu, d'expérimenter sans faire de gros frais.
  • La culture DevOps a encore du chemin à faire. On ne crée pas de l'engagement en les mettant dans des silos. On pourra faire toute l'agilité qu'on veut, si le développeur n'est pas directement responsable des bugs constatés en production et du client qui gueule au bout du fil, il continura à délaisser sa stratégie de test pour passer à quelque chose de plus "intéressant".

Pour moi, le premier point à traiter est notre cycle de release. Il ne s'agit pas juste de créer tous les 30 jours un "logiciel potentiellement livrable" comme nous le suggère Scrum, il s'agit de mettre à l'épreuve toute notre chaine de production aussi souvent que possible. Le liens vers DevOps est alors évident et rapidement indispensable.

Comment vendre cette évolution à nos Managers ? 

Un seul argument à vous proposer (je vous laisse trouver les vôtres) : combien de temps faut-il pour fournir une évolution ou un correctif sans désorganiser l'équipe (je ne parle donc pas du gros bug critique "stop the line") ? Avec un cycle tel que celui de Facebook, cela peut être juste une semaine, sans créer le moindre stress supplémentaire. Avec une approche traditionnelle, en 13 ans, je n'ai connu aucun projet qui faisait des mises en production à moins de quelques mois d'intervalle. Le time-to-market est le nerfs de la concurrence, et de ce point de vue tous les CMMi du monde n'ont rien à nous proposer.

(1) pour ceux qui en doutent, twitter est aussi un outil de veille technologique et de support. Comme tout réseau social, il peut porter des choses totalement futiles ou des infos pertinentes, le tout est de mettre en place les bon filtres.

22 mars 2011

BreizhCamp, c'est parti


Il y avait le BreizhJUG, et ses soirées Java.
Il y avait AgileRennes, et ses soirées agiles.
Il y avait alt.Net, et ses rencontres .Net
Il y avait Rennes-on-Rails, et ses rencontres Ruby.
Il y avait le club .Net-ouest, et ses sujets .Net
Il y avait aussi les Flex-istes, Python-istes, PHP-istes, JavaScript-istes, pas spécialement structurés mais bien présents

Maintenant, il y a le BreizhCamp, une rencontre "par des techos, pour des techos", inter communautés. Une journée complète de conférence, 4 tracks sur des sujets d'actualité, 27 sessions par des speakers de tous horizons.

Les inscriptions ne sont pas encore ouvertes, et le programme pas encore finalisé, mais préparez vous pour rafler l'une des 200 places disponibles.

C'est le 17 juin, toutes les infos sur www.breizhcamp.org

07 février 2011

Objectif : Mars

Je serais cette semaine à Marseille pour une formation Maven. J'en profite pour faire un petit tour au MarsJUG mercredi 9, pour une présentation de GWT et les nouveautés de la version 2.x. 

Non, je ne parlerais pas de Maven  (ou alors, juste un petit peu) vu qu'Arnaud a déjà fait le nécessaire et a abreuvé l'assistance de sa bonne parole pendant plus de 2h. Par contre, on pourra aussi parler un peu de Jenkins, ou de tout un tas d'autre sujet. Bref, soirée à la carte ;)

  

01 février 2011

Hudson et Jenkins sont dans un bateau ...

C'est chose faite, la communauté des développeurs Hudson a choisi de quitter définitivement Oracle et de forker / renommer (tout dépend du point de vue) le projet en Jenkins (http://www.jenkins-ci.org).



Les choses sont déjà suffisamment compliquées, voici que Sonatype prend position et apporte son soutien ... à Oracle Hudson :
"

One problem that we've encountered frequently in the past with Hudson
is stability after upgrades.  

This will be one of the areas of primary focus for Sonatype and when the rename happens 
today we will begin the process of merging most of our stabilization work back to Hudson. 
`This will take a bit of time because we stepped off the train to decide how and who we 
wanted to continue working with. I think this whole situation is unfortunate, but ultimately 
Kohsuke has the right, like everyone else, to do what he feels is right. I honestly do not 
believe what has happened is in the best interest of users, but this is my opinion and only 
time will tell.

If anyone is interested in the work to be done on Hudson the java.net lists should be up, the 
@hudsonci twitter account will be very active, and I'll have a series of blog posts about the 
work Sonatype is planning to contribute, a critique of the current architecture, and proposed 
roadmap. While I'm sure we're not going to be very popular in the short term, continuing the 
Hudson with Oracle is what we feel is best. Our goals and motives have not changed since 
the first time I posted about Sonatype's potential involvement. We care about the IP, the 
provenance of the code, the stability of the core, helping to create a new architecture while 
maintaining backward compatibility, create great Maven integration and create a commercial 
product. We've done a lot of work for enterprise users and we hope to share this with the 
Hudson community as soon as we can.

I believe it is truly regrettable what has happened, but life goes on and I'm sure both projects 
will do well catering to their users.

"

Jason met le doigt sur un élément clé : la stabilité et l'architecture de Hudson. C'est un critère important pour son utilisation en entreprise sur des projets stratégiques. Il faut reconnaitre que le modèle de développement de Hudson est particulièrement ouvert et manque parfois d'un cadre strict. Cela n'a pas empêché le projet de progresser très vite et de s'enrichir de fonctionnalités avancées, et ça a toujours été une volonté affichée pour réduire au minimum la barrière de contribution. Par contre, ça peut ne pas rassurer un DSI (vous me direz, c'est le même qui a commandé des licences Websphere 7, mais bon ...).

L'offre Sonatype Profesionnal intègre un Hudson validé et supporté ("Matrix"), il ne fait donc aucun doute que Sonatype a des évolutions techniques à proposer pour stabiliser et améliorer le projet. Devant le vide laissé par le départ de la communauté des développeurs pour Jenkins, ils vont ainsi se retrouver premier contributeur au côté d'Oracle, une place de project-lead inespérée.

Evidemment, rien n'est gagné : la communication autour du changement de nom a été large et Jenkins va continuer d'avancer au rythme qu'on lui connait. D'un autre côté, les clients d'Oracle ou de Sonatype seront sensibles à l'argumentaire de qualité technique et de stabilité d'un élément clé de leur forge logicielle. Sonatype va donc devoir mettre les bouchées doubles pour démontrer une plus-value et sa capacité à améliorer Hudson. Jenkins étant contraint de conserver les APIs existantes, les nombreux plugins ne sont pas remis en cause (dans l'immédiat), aussi Sonatype va pouvoir se focaliser sur le coeur Hudson et sur une intégration Maven 2/3 particulièrement poussée. Le niveau technique des développeurs ne fait aucun doute, tout va donc se jouer dans le timing et l'art de communiquer auprès de la communauté d'utilisateurs.

Pas facile de prédire ce que cela va donner... en espérant que ça ne va pas tourner au troll "audit de code" ou que sais-je pour démontrer qu'un projet est techniquement supérieur à l'autre.

On vit une époque formidable.

27 janvier 2011

"Mavenizer" un projet

Lorsqu'on cherche à convertir un projet "old-school" sous Maven, l'une des premières tâches consiste à identifier la liste de dépendances du projet. On peut se baser sur le nom des JAR, éventuellement se rassurer en inspectant le fichier MANIFEST (lorsqu'il est renseigné), mais en général c'est :

  • long
  • barbant
  • peu fiable : j'ai déjà vu des JAR "patchés" ou "complétés" avec des classes annexes

Une solution plus propre consiste à se baser sur les empruntes MD5 et SHA1 que le repository Maven conservent pour chaque artefact. Une simple recherche Google sur cette clé retourne l'identification précise d'une bibliothèque (avec parfois des surprises !).

Il y a pourtant encore plus simple...

Le repository manager Nexus propose un moteur de recherche qui prend en entrée l'emprunte SHA1. Basé sur son index interne, il va nous retrouver la bibliothèque, et en plus nous indiquer les versions plus récentes (si on veut en profiter pour un petit lifting). L'avantage de Nexus, c'est qu'il propose une API REST qui permet d'automatiser tout ça. Allons-y donc gaillardement !

J'écrit donc mon tout premier script Ruby ! - et oui, tout fout le camp ma bonne dame - ce langage est génial pour écrire des scripts de ce type, avec des bibliothèques bien puissantes ;)

require 'find'
require 'digest/sha1'
require 'net/http'
require 'rexml/document'
include REXML

for file in Dir.glob("*.jar") do 
    sha = Digest::SHA1.file( file ).hexdigest
    url = "http://myNexus/service/local/lucene/search?sha1=" + sha 
    resp = Net::HTTP.get_response( URI.parse( url ) )
    puts File.basename( file ) + " (" + sha + ") = \n";
    doc = REXML::Document.new( resp.body )
    XPath.each( doc, "//artifact" ) do |r|
          puts "<dependency>"
          puts "   <groupId>#{r.elements["groupId"].text}</groupId>"
          puts "   <artifactId>#{r.elements["artifactId"].text}</artifactId>"
          puts "   <version>#{r.elements["version"].text}</version>"
          puts "</dependency>"
    end  
 
end
Rien de bien méchant, comme vous pouvez le constater, et ce script permet d'analyser rapidement une liste de jar en proposant les éléments à intégrer dans le POM. Il restera "juste" à identifier les bibliothèques qui seront passées entre les mailles du filet.

Maintenant que Maven Indexer est un projet Apache (depuis la version 3.1.0), ce serait bien d'intégrer cette fonctionnalité au plugin dependency [MDEP-269] ... ou ailleurs.

26 janvier 2011

2011, l'année du fork

2011 pourrait bien être l'année du fork.


Non, je ne parle pas du nouvel an chinois, mais de la scission d'une communauté open-source (fork).

Le premier va se dérouler du côté du serveur d'intégration continue Hudson.
Après avoir géle puis migré le projet (sans prévenir) de l'infrastructure java.net vers kenai, Oracle réclame aujourd'hui le pilotage du projet, ou en tout cas l'application de règles strictes de pilotage et de cession des droits sur les contributions. La communauté ne suit pas, prise depuis le début à rebrousse-poil, et a déjà migré sur gitHub et google-groups.

Les dernières tentatives d'accord pour trouver un arrangement acceptable, légitimant une communauté indépendante sans couper les ponts avec Oracle, ne progressent pas. On s'oriente donc à grand pas vers un changement de nom pour Hudson (la seule chose qu'Oracle possède encore c'est ... ce nom "hudson ®") qui deviendra Jenkins.

La communauté Hudson - légitime en terme de lignes de code - se retrouve donc face à Oracle qui ne lâche pas grand chose, fort de sa légitimité sur le nom "hudson" et l'historique du projet.

Le second pourrait se dérouler du côté de Maven. 
Critiqué pour son pilotage unilatéral du projet au travers de sa société Sonatype, Jason Van Zyl a claqué la porte du Project Management Committee Maven. Fondateur du projet, il ne participe donc plus à ces discussions (qui a dit "disputes" ?) et continue à bosser avec ses collègues sur l'outil qui fait vivre sa boite, mais sur gitHub plutôt que dans le SVN Apache. Le code reste opensource, accessible à tous, mais ne suit plus les règles de bonne conduite communautaire édictées par la fondation. Sans a priori sur les personnalités en présence, ce n'est pas la première fois qu'un leader se plaint du modèle Apache et finit par aller voir ailleurs [1].

Les raisons de la crise : une partie non négligeable de Maven (Aether) est désormais hébergée chez Sonatype, et bien que toujours opensource, est vécue par certains contributeurs Maven comme une perte de contrôle (nécessité de signer une CLA pour contribuer). Comme pour ajouter à la sauce, Modello et Plexus, deux projets "socle" de Maven, ont été déplacés sur le gitHub Sonatype puis fermés sur codehaus.

Jusqu'ici les échanges liés à ces frictions sont restés discrets, la fondation Apache ayant pour règle de gérer ce genre de conflit en privé. Avec la contribution de Sonatype dans la fondation Eclipse via le projet m2eclipse, un changement de license [2] sur un composant a ébruité publiquement la situation.

Il ne s'agit pas (encore) d'un fork, mais rien n'interdit à Sonatype de publier ses propres releases de Maven (mais pas Apache Maven) dans le cade de son offre Sonatype Professional, le nom n'étant pas déposé par la fondation. Le PMC doit donc trouver un compromis, définir des règles sur l'utilisation de ces composants "externes" qui constituent pourtant une part importante de Maven 3 (core), et voir comment intégrer les développements de Sonatype tout en conservant un pilotage à la Apache du projet et en continuant à assurer la maintenance des nombreux plugins qui - eux - restent un terrain de jeu équitable pour tous les contributeurs (les moins doués se contentant d'écrire des bouquins sur le sujet).

La communauté Apache Maven - légitime en terme de contribution historique et de support - se retrouve donc face à Sonatype, fort de sa légitimité sur la quasi-totalité du travail de développement de Maven 3.

Inutile de vous dire à quel point ces querelles de légitimité, de licence, de règles de pilotage sont à la fois passionnantes et barbantes pour les contributeurs qui passent un temps fou à éplucher les mailing-list abreuvées de messages enflammés. 2011 risque de ne pas être une année reposante.




[1] le développement de log4j 1.3 est quasi abandonné, englué dans des discussions sur le maintien de la compatibilité. Ceki Güclü a préféré reprendre à 0 avec l'excellent slf4j.
[2] https://github.com/sonatype/sisu, notez les deux fichiers LICENCE.txt. Sous licence EPL, le code associé n'a plus aucune chance de revenir à la fondation

09 janvier 2011

Apple, 3 mos plus tard

Il y a trois mois, je sacrifiais mon compte en banque pour commander un MacBookPro. Le refurb a même réussi à me faire croire que je faisais une économie en ne lâchant "que" 1700€... 3 mois après, que donne la migration de l'OS aux fenêtres vers celui aux pommes ? Je vous donne ça un peu en vrac, faites le tri :

MacOS est un environnement magnifique, avec de nombreux raffinements auxquels on s'habitue bien vite. Si on met évidemment un petit moment pour trouver ses marques, il se prend en main rapidement (bien plus vite qu'un Linux pour avoir déjà testé). Par contre, la légende du "tout marche out-of-the-box" est largement sur-estimée. Si on part avec un système bien plus complet que lorsqu'on vient d'installer un Windows et qu'on a tout juste un notepad, il reste bien des softs à chercher sur le Net pour compléter le système, et diverses magouilles à trouver pour tout mettre au clair. Google est ton amis, et on s'en sort tout de même assez vite.

Ces détails de prise en main réglés, le système est comme promis extrêmement stable (j'ai rebooté 3 fois depuis octobre ...) et très performant. Il faut que je lance l'encodage vidéo pour le breizhjug pour constater les syndrome du système chargé à bloc et les freeze qui vont avec (sachant que je n'ai pas cherché à limiter le processus).

Côté dev, j'ai profité de l'occasion pour passer à Idea, et pour le reste travailler sur un système type-Unix est bien appréciable. Tous les outils en ligne de commande sont présents (ou disponibles sous forme de MacPort) et on oublie les problèmes d'encodage ou de format EOL qui pénalisent toujours les environnements Windows.

MacOS est donc un environnement bien agréable, aussi bien en tant qu'utilisateur que comme développeur. Il n'en reste pas moins qu'il s'agit d'une prison dorée : rien que pour raccorder le portable à un écran externe (fonctionnalité de fou-fou) compter 29€ d'accessoire (c'est sur, un connecteur HDMI aurait dénaturé la machine). Idem pour l'extension vendue 20€ permettant de lire des fichiers MPEG avec Quicktime. Pas de doute, Apple est avant tout la fusion parfaitement réussie entre le design et le marketing. Si vous ne l'aviez pas compris en constant le prix des machines, préparez le porte-monnaie ! Bien sûr, on trouve quelques (très bons) softs opensource ou freeware pour Mac, mais ça reste un marché bien plus confidentiel. Si les softs natifs macos sont généralement aussi bien léchés que le système, le manque de choix est parfois regrettable.

Préparez-vous aussi à devoir subir les changements de politique de Steeve. On m'avait par exemple vanté les mérites d'un système qui intègre de base Java et Maven, 15jours plus tard Apple passait l'éponge sur sa JVM pour rallier OpenJDK (ou plutôt, laisser à OpenJDK le soin de combler le vide ainsi créé). On peut pour l'instant encore installer ses softs sans passer par l'Apple Store, mais qu'en sera t-il de la prochaine release ?

Soyons clairs, mon PC reste allumé uniquement pour OutLook parce que je n'ai pas réussi à accéder à ma messagerie Exchange. Cependant, je ne pense pas que le Mac soit la solution ultime pour les développeurs. Cela reste un système fermé, piloté par la vision d'un gars connu pour ses retournements de veste (demandez à ceux qui ont un Mac PowerPC), exploitant son image haut de gamme et son avance en terme de design et d'ergonomie pour justifier des tarifs doubles de la concurrence. Nous autres développeurs sommes une minorité dans le pannel des clients Apple (comparé au monde de la photo ou de la PAO par exemple), aussi le système a plus de chance de s'orienter vers du tout sous contrôle que vers de la machine de geek.

Linux est malheureusement (?) trop dispersé pour jouer sur le même front, mais reste une solution à considérer pour tirer les mêmes bénéfices en tant que développeur - à condition de ne pas avoir besoin de la suite MS Office.

Moralité : si on vous propose un Mac dans le cadre de votre boulot, c'est un réel avantage, et pas uniquement un attrape-geek. Par contre, si vous voulez juste quitter le monde Windows et devez sortir les 2000€ facturés par Apple de votre poche, regardez aussi ce qui se fait alentour avant de signer...

06 janvier 2011

RPC/Encoded avec JAX-WS

A l'époque ou SUN a voulu faire prendre à Java le train des services web, le JCP a accouché de JAX-RPC. Nous avons été nombreux à choisir l'implémentation Apache Axis pour exposer ou consommer de tels services.

Mauvaise pioche, le "marché" a par la suite adopté l'approche document, alors que JAX-RPC était un RMI pour les services web, basé sur l'approche RPC. Pour la version 2.0 de la norme, le JCP a changé son fusil d'épaule et créé JAX-WS, norme qui exclue le mode RPC/Encoded et repose sur JAXB.

Voilà pour l'historique. Aujourd'hui, que vous choisissiez Metro, JbossWSAxis2 ou Apache CXF (mon préféré), vous  partez sur une stack web-services éprouvée et interopérable ... jusqu'à ce qu'un partenaire vous expose un vieux WSDL bien naze en RPC/Encoded.

Un réflexe que j'ai constaté plusieurs fois dans ces circonstances consiste à déterrer Axis pour communiquer avec ce service web façon grand-mère. Autrement dit, partir sur un outil qui n'a plus évolué depuis 5 ans, abandonné par ses développeurs au profit d'Axis2 et ... techniquement discutable (pour avoir du déboguer un problème de namespace dedans, je vous déconseille d'essayer)

Si la norme JAX-WS exclue le support du mode RPC/Encoded, cela ne signifie pas qu'il est impossible d'invoquer un service de ce type. On peut toujours exploiter notre pile web-services, incluant ses mécanismes de sécurité, de gestion de ressources, de log et monitoring, etc. Par contre on ne bénéficiera pas des mécanisme de binding entre le flux XML et du code Java généré.

Le moyen le plus simple que j'ai trouvé (je suis ouvert à toutes suggestion) est de construire à la main la trame de requête (utiliser SoapUi pour avoir une base valide), à l'aide d'un mécanisme de template, puis d'aller piocher les éléments du flux de réponse via son arbre DOM. Ca donne ça :

// Construction de la trame requête, 
// utiliser un mécanisme de template style freemarker si besoin
String request = "<soapenv:Envelope "
  + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
  + " xmlns:xsd='http://www.w3.org/2001/XMLSchema' "
  + " xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' "
  + " xmlns:urn='urn:Naze'>"
  + "<soapenv:Header/>"
  + "<soapenv:Body>"
  + "  <urn:foo soapenv:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>"
  + "    <id xsi:type='xsd:string'>42</id>"
  + "    <query xsi:type='xsd:string'>ndeloof</query>"
  + "  </urn:foo>"
  + "</soapenv:Body>"
  + "</soapenv:Envelope>";

// Un peu de manipulation des API XML, désolé
QName serviceName = new QName( "urn:Naze", "NazeService" );
QName portName = new QName( "urn:Naze", "NazePort" );
Service service = Service.create( getWSDL(), serviceName );

// Utilisation de l'API de niveau "message" de JAX-WS pour transférer le message
Dispatch dispatch = 
   service.createDispatch( portName, Source.class, Service.Mode.MESSAGE );
dispatch.getRequestContext().put( 
   BindingProvider.USERNAME_PROPERTY, "login" );
dispatch.getRequestContext().put( 
   BindingProvider.PASSWORD_PROPERTY, "password" );
Source response = dispatch.invoke( 
   new StreamSource( new StringReader( request ) ) );

MessageFactory msgFactory = MessageFactory.newInstance();
SOAPMessage msg = msgFactory.createMessage();
SOAPPart env = msg.getSOAPPart();
env.setContent( request );

if ( msg.getSOAPBody().hasFault() )
  throw new RemoteAccessException( "oups..." );

// récupération des éléments XML qui nous intéressent
NodeList arrayOfString = 
  msg.getSOAPBody().getElementsByTagName( "result" );
Node node = arrayOfString.item( 0 );
return node.getTextContent();

Je vous accorde que c'est un peu laborieux ;)

Une autre solution, plus légère mais moins portable, consiste à appeler Spring-WS à notre secours. Les templates de Spring permettent d'invoquer un service web en manipulant directement les messages, comme nous venons de le faire, mais avec une couche de Spring pour simplifier le code. Spring-WS n'utilise pas notre  pile JAX-WS mais des appels HTTP directs avec Commons-httpclient et XPath pour extraire les données du message de réponse, avec des classes très "Spring" pour mapper les noeuds XML sur nos classes Java.

Le résultat est une très grande souplesse pour s'adapter à des services web pas trop standards (et il y en a, vous pouvez me croire, qui lisent les normes avec les pieds) :

private final WebServiceTemplate webServiceTemplate;

private final XPathOperations xpath;

public NazeClient( String url ) throws Exception {
   webServiceTemplate = new WebServiceTemplate();
   webServiceTemplate.setDefaultUri( url );
   CommonsHttpMessageSender sender = configureSender();
   webServiceTemplate.setMessageSender( sender );
   xpath = new Jaxp13XPathTemplate();
}

private CommonsHttpMessageSender configureSender()  throws Exception {
   CommonsHttpMessageSender sender = new CommonsHttpMessageSender();
   sender.setCredentials( 
       new UsernamePasswordCredentials( "login", "password" ) );
   sender.afterPropertiesSet();
   return sender;
}

public List sendAndReceive() {
   String message = ""; // idem exemple précédent
   StreamSource source = new StreamSource( new StringReader( message ) );
   Result result = new StringResult();
   webServiceTemplate.sendSourceAndReceiveToResult( source, result );

   List values = xpath.evaluate( "//result", 
       new StringSource( result.toString() ),
       new NodeMapper() {
          public String mapNode( Node node, int nodeNum ) {
              return node.getTextContent();
          }
      } );
   return values;
}

05 janvier 2011

GWT round trips

Pour bien entamer l'année je vous propose un petit point sur la phase de chargement d'une application GWT.

La page HTML hôte est chargée par le navigateur (potentiellement mise en cache) et inclut un lien vers le script de sélection, qui lui est configuré pour ne jamais être en cache. Ce script s'exécute et sélectionne la permutation qui convient à votre environnement : navigateur, langue, etc (potentiellement mise en cache) L'exécution de ce script construit l'UI de l'application web et enchaine généralement avec un (voir plusieurs si vous n'avez pas trop bien pensé votre appli) appels RPC.

Au final, on a donc 4 requêtes séquentielles avant que l'application soit disponible pour l'utilisateur.

Pour améliorer les performances du chargement d'une appli GWT, autrement dit la première impression qu'auront vos utilisateurs, il existe plusieurs techniques.

La première, consiste à utiliser une page hôte dynamique [1], une JSP qui va directement inclure le contenu du script de sélection, ainsi que le résultat du premier appel RPC (encodé au format JSON ou GWT-RPC) [2].
La page hôte dynamique nous évite 3 requêtes, contre une petite surcharge de travail côté serveur.

Une autre piste pour aller encore plus loin est proposé dans les derniers builds du compilo GWT, via l'issue 941802. Il s'agit de remplacer la sélection du script côté client par du code côté serveur. La page hôte peut alors contenir directement la permutation GWT adaptée au navigateur client. Ne vous emballez pas, cette option est totalement expérimentale et même pas complète dans le SDK : il vous faudra surcharger le Linker et développer le code d'identification de la permutation, autrement dit retrousser vos manches.


[1] http://code.google.com/intl/fr-FR/webtoolkit/articles/dynamic_host_page.html
[2] http://www.techhui.com/profiles/blogs/simpler-and-speedier-gwt-with

02 décembre 2010

En voila une bonne Idea !

Depuis des années je bosse sous Eclipse, et j'entend cet IDE se faire critiquer à tout va.

Je dois bien reconnaitre que j'ai quelques reproches à lui faire, entre autre la médiocrité de son intégration Maven pendant des années, et son incontournable "building workspace" dès qu'on touche à un fichier sur un projet un tant soit peu ambitieux.

Profitant du passage sur Mac et sous Git (@glaforge sur ou sous ?) qui me déstabilise déjà un peu, j'en profite pour essayer sérieusement Idea. La règle est simple, l'étude que je réalise en ce moment sera développée sous Idea ou ne sera pas ! L'intérêt d'une étude est qu'on réfléchit beaucoup avant de coder, alors ne pas être au top de la performance dans l'IDE n'a pas beaucoup d'impact :P

License Jug-Leader récupérée j'installe l'engin et je peine quelques jours à apprivoiser les menus, fenêtres et raccourcis. Après une première semaine, je commence à me débrouiller. Idea est clairement très différent d'Eclipse.

La philosophie d'Eclipse est d'intégrer les outils pour les rendre invisibles. Avec m2eclipse, on ne lance jamais un build Maven (à moins d'être maso), car l'IDE le lance lui-même dans le cadre de son build incrémental - bouffant au passage un bon paquet de cycles CPU. Avec WebTools, on ne lance pas un serveur d'application, l'IDE redéployant l'application à chaque modification - fonctionnalité qu'on désactive si on a pas un core i7 sous le capot. Au final, l'IDE cherche à nous faire croire que tout est magique et qu'on peut se contenter de vivre dans l'éditeur Java. Idée intéressante si nous avions tous une réserve de CPU hors norme, mais en pratique on passe beaucoup de temps à attendre que l'IDE termine ses tâches. Là où ça devient pénible, c'est qu'il interdit de sauver un fichier en cours d'édition tant que la tâche précédente n'est pas terminée, d'où les frustrations et les critiques.

Eclipse est - en gros - conçu pour des développeurs qui ne maitrisent pas leur environnement. Je ne veux pas savoir ce que fait maven lors d'un build, je ne veux pas savoir comment on déploie un war sur Tomcat, je veux juste coder. La logique "clic bouton" en est la signature, même s'il existe tout de même quelques raccourcis clavier.

La philisophie d'Idea est de proposer un environnement de pilotage des outils, et un éditeur 100% orienté développeur. De très nombreux raccourcis clavier permettent de ne (presque) jamais toucher à sa souris (ex : Pomme+W pour sélectionner des blocs logiques de plus en plus large, variable, expression logique, ligne, bloc, méthode, classe ...). L'éditeur interprète le code Java 100% à la volée sans passer par une compilation comme le fait Eclipse. Il n'y a du coup pas de notion de "sauvegarde". De très nombreux assistants ("intentions") permettent de faciliter le développement : ajouter un import statique, ajouter une dépendance Maven, ...

Lorsqu'on désire lancer un build Maven ou déployer sur le serveur d'application, il faut le demander explicitement, via l'interface dédiée à l'outil dans l'IDE. Au final, l'environnement est globalement bien plus rapide puisqu'il n'a pas ce surcout à gérer. Et même s'il faut lancer et attendre le build Maven pour avoir le résultat attendu, beaucoup de développeurs Eclipse le lancent aussi car ils sont confrontés à des couacs dans leur environnement !

Je suis encore très peu efficace sous Idea, et je découvre un nouveau raccourci clavier toutes les heures en me demandant comment je vais mémoriser tout ça, mais j'ai peur que le retour sous Eclipse que je connais bien fasse mal. Un point délicat tout de même : avec ce nom "idea", il n'est pas facile de faire des recherches Google pertinentes pour trouver de l'info (il vaut mieux ajouter "intellij"), sans compter qu'on est une minorité ! Le côté positif, c'est que Twitter est ton amis pour demander de l'aide ;)

Si vous n'avez pas de licence, demandez à votre Jug local de vous en obtenir une (s'il n'organise pas déjà un tirage au sort).

27 novembre 2010

alors, prends toi zen main

"...c'est ton destin"

En conclusion de Devoxx, les Castcodeurs ont encouragés les français à sortir de leur notoire mode "râleur" pour se prendre en main : achetez vous du bon matos, payez-vous un bouquin et un abonnement Parleys.com pour (re)découvrir tous les sujets de Devoxx 2010, etc.

Dans un domaine ou tout va très vite, il est clair que se maintenir à niveau est un travail quotidien, et qu'il ne faut pas tout attendre de nos employeurs. On peut bien sur regretter que ceux-ci ne prenne pas plus à coeur notre formation, mais soyons pragmatique : un développeur avec 10 ans d'expérience est surtout expérimenté sur 5 années d'une techno dépassée. Du point de vue d'un recruteur ce n'est pas quelque chose de recherché au premier abord, même si c'est une expérience valorisable.

Ceux qui ont développé en EJB 2 savent pas exemple pourquoi on lui préfère aujourd'hui Spring ou les EJB 3, et peuvent donc mieux appréhender ces technologies - cependant ce n'est pas une source immédiate de productivité, donc cela ne justifie pas de payer un "10ans" alors qu'un "3ans" sait faire à peu près aussi bien pour moins cher (je prend le point de vue du recruteur, dans les faits ce n'est pas aussi évident :P). Quelle plus-value avons nous à proposer ? Appréhender rapidement une nouvelle techno, être au courant de ce qui fait le buzz, avoir un réseau de connaissance. Les User Groups sont évidemment la place privilégiée pour cela !

Qu'est ce qu'un employeur est disposé à financer ? Un bouquin ou une formation en rapport avec le projet sur lequel vous êtes affecté, évidemment. Par contre, si ça sort de ce cadre il faudra ramer pour se justifier. Idem pour le matos : Si les études montrent qu'on est plus productif avec de grand / multiples écrans, nous sommes nombreux à devoir bosser sur des machines bureautiques qui atteignent  péniblement le WXGA sur un 15". Evidemment, rien ne vous oblige à investir comme moi dans un MacBook qui vous coutera un bras, mais un 22" correct c'est 200€ de nos jours, sans parler d'un vrai clavier confortable ou d'une bonne souris, investissement qui vous économisera une séance d'ostéopathe à 50€.

Il reste regrettable de constater que nous avons presque tous une meilleur infra à la maison que sur notre lieu de travail : ordinateur musclé, bien accompagné, et pas encombré d'un antivirus paranoïaque; accès Internet à haut débit (et pas une pauvre liaison ADSL partagée à plus de 100 personnes), etc. Mais, en démontrant par l'exemple qu'on peut travailler mieux avec du bon matos, peut-être arriverons nous un jour à changer cette tendance.

Petit papa noël, penses à nous :D

19 novembre 2010

Java community Q&A

Pour cette keynote, Joshua Bloch, Mark Reinhold, Stephen Colebourne, Antonio Goncalves, Juergen Hoeller et Bill Venners débattent des orientations de la plateforme Java face aux questions de la communauté.

Java doit-il rester backward compatible ou devons nous avoir le courage de casser les choses ?

La question ne fait pas l'unanimité. Rien que dans le JRE, les méthodes deprecated ne disparaissent souvent pas au cours des versions suivantes. Joshua aimerait pourtant (par exemple) que la notation "32l" pour définir un long 32 (et pas l'entier trois-cent-vingt-et-un !) ne soit pas acceptée, et remplacée par "32L" moins ambigu. Evolution simple mais déjà pas si simple d'obtenir le consensus.

Quel impact d'Oracle sur la communauté Java ?

De l'avis général, tout n'a pas été positif, mais personne n'ose explicitement mettre les pieds dans le plat. Antonio prend finalement la parole pour résumer le BOF Jug d'hier qui a été positif et les opportunités qu'Oracle nous propose.

Comment gérer le problème de licence du TCK Java ?

(rappel : Apache Harmony ne peut pas être validé "Java" pour cette raison). Mark Reinhold ne veut pas se dérober à cette question (ce qui l'obligerait à porter un chapeau ridicule en alu, c'est la règle), cependant il ne peut pas répondre officiellement... mais ne voit pas Apache obtenir une licence TCK ni à court ni à long terme.

Android peut-il être la plateforme Java mobile de facto ?

Antonio élargit le problème à la gestion des communautés Groovy, Scala, et donc Android, qui font partie de l'écosystème Java sans rentrer dans le moule. Juergen ajoute Google App Engine et défend que ces initiatives permettent de défricher l'avenir de Java et doivent avoir leur place, en tout cas être "autorisées" dans la communauté. En résumé, avoir ajouté un aspect légal sur le débat est la pire chose qu'il y avait à faire.

Qu'est ce que .Net (plateforme/communauté) pourrait nous apprendre pour améliorer Java ?

Techniquement, .Net a bénéficié de Java pour ne pas faire les mêmes erreurs. Les puzzlers de Joshua, traduits en .Net, ne produisent plus de problème par exemple. Cela nous ramène à la première question ...

Va t-on voir la fin de la gue-guerre JigSaw/OSGi ?

Oracle vend en effet des produits basés sur OSGi, alors ? OSGi est utilisé sur de gros frameworks, serveurs d'application, middlewares, etc, mais est peut être un peu compliqué pour un usage plus standard. Java 8 vise plus une unification pragmatique, pour résoudre les problèmes simples dans la JVM, ce pour lequel OSGi est sur-dimensionné.

Comment gérer les JVM legacy que nous héritons du parc installé (i.e. Websphere) ?

Le passage en Java5 n'est pas encore une généralité... alors Java 7 ! Un problème dérivé est le temps entre la finalisation d'une JSR et son implémentation. Un an après JavaEE 6 les grosses implémentations ne sont pas encore là. Peut être revoir la logique du JSR pour être plus incrémental...

Java permettra t-il d'accéder aux noms des paramètres de méthodes ?

oui ! c'est possible, reste à savoir comment ... car cela va poser un problème de compatibilité (retour à la question 1 encore une fois).

L'approche fonctionnelle est-elle si pertinente qu'elle devrait être formellement intégré à Java ?

Scala, Clojure montrent la voie, doit on avoir un langage officiel pour cela ? Retour en arrière pour rappeler l'engouement pour XML et sa désaffection (relative). L'associer très officiellement à Java aurait-il eu un intérêt ? Si l'approche fonctionnelle apporte une vision intéressante, trop de choses dans le langage risquent de le scléroser. Par contre, des facilités dans le JDK pour mieux supporter les langages fonctionnels sont une option à considérer ...

Comment Oracle espère t-il faire revivre JavaME fàce à la concurrence sans Android ?

Modular Java permettrait de faire entrer Java sur des mobiles, cependant cela reste hypothétique. La question renvoie à l'organisation du JCP, et ses nombreux représentants issus du monde mobile.

Comment corriger le JCP ?

Idéalement : construire une structure indépendante, sur le modèle de la fondation Eclipse. Mais quel intérêt pour Oracle de lâcher sa main-mise sur Java ? Antonio modère le sujet en précisant que la participation au JCP reste ouverte et que certaines JSR sont pilotées par des indépendants. Toujours plus de transparence reste cependant une priorité.
Le lien avec la position dure prise par Doug Lea sur le JCP est porté par la question suivante, mais baser Java 7 sur le seul OpenJDK ne peut être la solution. Comment savoir ce qui fait foi, comment savoir si le code d'une JVM alternative est  respecte la norme ou est juste compatible ? Des petites phares fusent, elles ne manqueront pas d'être reprises sur twitter :P

Jusqu'à quand l'historique desktop de Java va t-il encombrer le JRE ?

C'est l'une des raisons d'être de Java modularisation ! Sur le besoin de modularité, l'unanimité est faite.

La plateforme correspond elle à l'utilisateur "standard" de Java aujourd'hui ?

Joshua est partisan d'une simplification de la syntaxe et de l'élimination de nombreux tweaks qui font de Java un outil pas 100% satisfaisant pour la grande majorité de développeurs qui programment pour payer leur facture. Les geeks qui vont aux JUGs et à Devoxx sont une toute petite minorité. Qui par exemple a défini ses propres annotation ? Qui utilise les generics pour autre chose que des List ? Il manque peut être un niveau de langage dédié aux développeurs de librairies et un autre pour le développeur lamba...

Dernière ligne droite ...

Dernier jour à Devoxx, les stands se démontent, beaucoup sont déjà partis. Les survivants se regroupent à l'étage au pied des salles pour un dernier café. Ce matin, la keynote sera consacrée aux attentes de la communauté sur l'avenir de Java, synthétisées après deux BOFs les jours précédents. Antonio s'y colle pour représenter les JUGs, quand on lui tend un micro il ne sait pas résister, pire qu'un gosse :P

Suivra l'enregistrement live des castcodeurs, en parallèle des quelques sessions qui terminent cette édition, et pour moi un retour express à la gare pour ne pas louper mon Thalys.

Ce que je retiens de cette édition :

  • la force de l'approche REST. Le programme de Devoxx a été mis à disposition via une API Rest, s'en est suivi une poignée de clients pour iPhones, iPad, Android, GWT, Flex, JSF+HTML5 (et pas JavaME, tiens?). Ce petit exemple montre que REST est peut être l'approche qu'on attendait de longue date pour découpler la présentation du métier, laissant chaque couche choisir sa technologie d'implémentation.
  • le Cloud, très présent sur cette édition même si j'ai suivi peu de sessions, avec des retours d'expérience de FaceBook et Twitter pour lesquels les volumétries tiennent du délire.
  • la communauté Java qui s'organise et Oracle qui a clairement appris à l'écouter. Après un passage à vide, la reprise du flambeau par Oracle semble donc bien engagé.


Rendez-vous l'an prochain pour Devoxx 2011, si je ne vous ai pas convaincu que c'est LA conf à laquelle il faut venir, je ne peux plus rien pour vous :P Pensez aussi à l'abonnement PArleys à 79€ pour voir ou revoir toutes les sessions.

18 novembre 2010

JavaPuzzlers et BOF

Dernière session de la journée, un bon vieux Java Puzzler de Joshua Bloch. Si vous ne connaissez pas, procurez-vous le bouquin ! En gros, ce sont des fragments de code qui cachent un bug auquel on ne pense pas du tout au premier abord. Un raffinement dans la gestion du compilateur ou dans la structure des collections, bref un truc qui peut vous plomber une appli. Avec une mise en scène qui donne un style très spécifique aux présentations de Joshua Bloch, 6 puzzlers de ce type sont présentés puis décortiqués, avec à chaque fois une lesson à retenir.

Votre serviteur s'en tire avec 2 bonnes réponses (avec la bonne explication, sinon ça ne compte pas) sur 6, on va dire que la journée était rude pour me trouver une excuse ;)

On enchaine avec la dernière soirée autour des stands des sponsors, qui seront démontés dans la soirée. C'est l'occasion de récupérer tous les goodies qu'on a pas réussi à gagner par tirage au sort parce qu'il faut écouler les stocks avant de remballer - hop, une clé USB IBM et un TShirt Capgemini ;)
Ajoutons à cela quelques bières sur le stand Oracle (je ne sais pas si je vous l'ai dit, mais à Devoxx on boit pas mal de bières), et voila que je loupe le BOF JDuchess, c'est malin ...

Je me rattrape en rejoignant le BOF JUG-Leaders qui à lieu juste après. Jackie, représentant Oracle, vient renouer le lien avec les JUG-Leaders, lien qui avait été mis à mal par les petites erreurs de communications d'Oracle après sa reprise de la communauté Java. Pour résumer, après les propositions déplaisantes dont j'ai déjà parlé sur ce blog, Oracle laisse au JUGs carte blanche pour organiser leur activité, par contre il propose - au dela de ce que SUN faisait - de nous joindre aux réunions annuelles des OUG pour bénéficier :

  • d'un peu de pub sur les produits Oracle (faut bien justifier l'hotel qu'il nous réservent),
  • d'échanges privilégiés avec les représentants Oracle,
  • de temps pour échanger entre JUG-Leaders, bien plus que l'heure consacrée au BOF une fois par an à Devoxx.


Ce dernier point est important car il nous permettrait de rentrer dans une dynamique bien plus puissante que ce que nous connaissons aujourd'hui, avec des JUG qui s'entraident pas copinage. Par contre, cela suppose un minimum de structuration, une hiérarchie des JUGs pour qu'Oracle n'ai pas 200 interlocuteurs.

En pratique, ce n'est pas vraiment un problème : tous les JUG-Leaders ne sont pas disponibles pour se libérer 2 jours je ne sais où, et nous sommes déjà organisés en réseaux informels en fonction de notre taille et de notre représentativité respective. Aucun JUG-Leader français ne reprochera à Antonio de s'être exprimé en notre nom lors du premier contact avec Oracle, car il le fait en toute transparence et n'hésite pas à donner de sa personne au ParisJug pour laisser une place aux JUGs de province.

Oracle opère donc un virage à 180° et a retenu la leçon de sa communication ratée des premiers jours. Jackie est une représentante sympathique et très ouverte, prête à nous entendre et à adapter l'organisation des meetings OUG pour nous y faire une place. Et pour finir sur une touche de bonne humeur, on termine le BOF au mexicain d'à côté autour ... d'un Mojito (une fois n'est pas coutume).