Blog de Samuel Liard
RSS icon Email icon Home icon
  • Maven, JUnit et la JVM

    Ca fait longtemps que je n’ai pas fait de petit post technique où je decris la solution d’un problème simple. Et bien justement j’ai eu à en résoudre quelques uns ces derniers temps. Je vais donc les partager.

    En ce moment je travaille sur un projet qui charge beaucoup d’objets en mémoire. Il faut donc redéfinir la taille de mémoire max à allouer pour le faire tourner. Une simple option « -Xmx512m » au niveau de la JVM et les tests unitaires fonctionnent sans pb. Mais comment faire lorsqu’on lance les tests avec Maven ?

    La première solution est de redéfinir une variable d’environnement :  
    MAVEN_OPTS=-Xmx512m

    Mais dans ce cas chaque personne reprenant mon projet va devoir redéfinir cette variable. Pour moi ce n’est pas viable. En cherchant encore j’ai trouvé comment définir cela dans le pom :

    
        org.apache.maven.plugins
        maven-surefire-plugin
        
            -Xmx512m
        
    

    Et la ça fonctionne très bien.

    Malheureusement j’avais un second problème. Je fais des tests avec des comparaisons de chaînes de caractères qui contiennent des accents. Et là encore sous Eclipse pas de problème mais en ligne de commande ça ne fonctionnait pas. En plus j’avais un Warning :
    [WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!

    Pour corriger le Warning j’ai ajouter dans le pom :

    
    ISO-8859-1
    

    Et pour que mes JUnit fonctionnent j’ai encore ajouté deux paramètres :

    
    
    
          org.apache.maven.plugins
          maven-surefire-plugin
          
            -Xmx512m -Dfile.encoding=ISO-8859-1
          
        
    
          org.apache.maven.plugins
          maven-compiler-plugin
          
            1.5
            1.5
            ISO-8859-1
          
        
      
    
  • Conflit de lib Apache CXF et hibernate

    Je viens de perdre pas mal de temps à faire fonctionner mon projet qui utilise hibernate et apache CXF pour exposer des WebServices.

    Au moment de compiler j’avais l’erreur suivante :
    WARN: Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/CodeVisitor:
    at net.sf.cglib.core.KeyFactory$Generator.generateClass

    Au début ça me paraissait être un simple NoClassDefFound, mais la classe recherchée était bien dans mon CLASSPATH.

    A force de chercher j’ai fini par comprendre que c’etait un problème d’incompatibilité de version de lib cglib. Il faut donc exclure la librairie cglib récupérée avec hibernate pour en prendre une nommée : cglib-nodep.

    Voici comment faire dans votre fichier maven 2 :

    
        org.hibernate
        hibernate
        3.2.1.ga
        
            
                cglib
                cglib
            
        
    
    
        cglib
        cglib-nodep
        2.1_3
    
    
  • ActiveMQ

    Pendant une petite semaine j’ai regardé de plus près le serveur de JMS ActiveMQ. Je vais vous faire partager mes premières remarques.

    Le coeur

    ActiveMQ est un broker de message à utiliser pour le développement d’une architecture MOM (Middleware Oriente Messages). Je l’ai choisi aussi pour sa bonne intégration avec Spring et sa bonne tenue en charge.

    Son architecture est simple : (source : http://activemq.apache.org/code-overview.html)

    Read the rest of this entry »

  • Gagné !

    Je viens de recevoir une confirmation par mail pour m’informer que j’ai gagné le premier prix de la catégorie « complexe et futée »  du concours Orange Partner ! Aux vues de mes plus que médiocres compétences graphiques je ne pouvais gagner que dans cette catégorie :)

    Pour économiser mes crédits, je n’avais pas communiqué l’adresse du site. Maintenant vous pouvez l’utiliser sans problème : http://www.areuthere.net/ (jusqu’à épuisement de mes crédits bien sûr)

    C’est un service qui vous permet de géolocaliser en France des téléphones portables Orange. J’ai surtout réalisé deux fonctions innovantes :

    • Etre informé lorsqu’une personne entre dans une zone que vous avez définie.
    • Recevoir un SMS avec la liste de vos contacts à moins d’un kilomètre.

    La première est très pratique pour être informé lorsque votre enfant arrive à l’école et même indispensable pour être alerté si votre femme approche trop près de la place Vendôme ! ;)

    Pour réaliser ce service j’ai utilisé les API d’Orange de géoloc, de SMS et d’authentification. Autant les deux premières sont très simples à utiliser (un simple GET sur une URL) autant la dernière est complexe. La documentation est pourtant bien faite, il faut envoyer un sendRedirect au client avec dans l’url une commande SAML. Le problème c’est qu’il faut travailler sans filet, en cas d’erreur aucun message pour savoir si c’est une erreur dans le SAML, dans le codage en base64 ou avec le zip. Heureusement que dans la dernière version de la documentation il y a un exemple en JSP.

    Si vous êtes intéressé par un peu plus d’informations techniques j’ai mis en ligne un embryon de documentation ici.

    Le service est réalisé en GWT, j’en reparlerai dans un autre article.

    Pour en revenir au concours je compte bien aller au Partner Camp à Cape Canaveral, il reste juste à trouver un billet d’avion. Car si Orange offre l’hébergement, il faut se débrouiller pour y aller.

  • Google Developer Day à Paris

    Jeudi 18 avait lieu le google developer day à Paris. Petit résumé de la journée.

    Accueil

    Après avoir montré patte blanche deux fois, on peut enfin entrer dans le hall, un petit déjeûner est offert. C’est entre deux petits fours que je croise Grégory Weinbach d’object Direct.

    Une fois bien rassasié je continue le tour du bâtiment pour me diriger vers la salle de repos. Et pour une salle de repos c’est une belle salle de repos ! 4 écrans plats avec des Wii, deux baby-foot, un mikado géant, un domino géant, un puissance 4 géant, un jeu d’échec géant.. rien que ca ! Et le top du top c’est un tas de gros coussins aux couleurs de Google.

    Après deux parties de Wii Tennis, il est temps d’assister au discours d’ouverture.

    Message d’introduction

    Pour démarrer la journée, Patrick Chanezon nous présente très rapidement l’ensemble des outils Google :

    • Chrome
    • Gears
    • App engine
    • GWT
    • OpenSocial
    • Androide

    A chaque démo il faut switcher du Mac qui à les slides au PC, car Chrome ne fonctionne que sous Windows :) . Et en plus de ces petites démonstrations, plusieurs sociétés nous présentent leur produit basé sur des outils Google :

    • Mapeed est un outil pour fusionner des marqueurs en fonction du niveau de zoom basé sur Google Maps.
    • MYerp.com est comme son nom l’indique un ERP en ligne ecrit avec GWT. 
    • Viadeo annonce l’ouverture de ses nouvelles APIs compatible OpenSocial

    Par contre la petite démo d’android n’a pas été spectaculaire, l’application « blue dot » est beaucoup moins spectaculaire qu’à Londres où ils avaient un vrai téléphone.

    J’ai ensuite choisi de participer au code lab sur App Engine.

    Code lab App Engine

    App Engine est une solution d’hébergement fiable basé sur le langage python. Et la première question qui nous vient tous à l’esprit est bien sûr : « Pourquoi en Python ?? » Et la l’équipe google nous répond que c’est peut être en lien avec l’arrivée de Guido van Rossum chez eux… Pas très technique comme explication.

    Sinon App Engine propose plusieurs briques intéressantes :

    • Gestion de l’authentifcation Google
    • Gestion d’une base objet
    • Api d’envoi de mail

    Le Code lab est bien fait, le but est de développer une application wiki avec le kit de dev. Il permet de tester son application en local.


    En sortant du bâtiment j’ai même trouvé le scooter d’un Googler ;)

    Même si ce code lab était bien fait, je suis resté un peu sur ma faim. J’attendais beaucoup plus d’explications sur la gestion de l’hébergement.

    Repas

    J’ai profité du repas pour rencontrer Julien Dubois de spring source et Ludovic Toinel de Capgemini qui travaille sur les API Orange Partner. Un moment d’échange très intéressant.

    Ensuite j’ai participé à deux sessions sur Gear et Chrome.

    Gear

    C’est Aaron Boodman qui nous présente Gear. C’est aussi l’occasion de fêter les un an de l’application. Gear offre des fonctionnalités avancées pour les applications web et notamment de pouvoir rendre en partie l’application accessible Offline.

    Plusieurs points sont présentés :

    Desktop shortcuts

    Ca permet d’ajouter un icon sur le bureau pour ouvrir directement l’application Web. Le seul avantage par rapport à un lien http « normal » est de sauvegarder le navigateur utilisé et donc de ne pas simplement d’ouvir l’URL avec celui par défaut (intérêt très limité je trouve…)

    Gestionnaire de fichiers

    Gear offre une boite de dialogue qui permet d’utiliser des filtres et de sélectionner plusieurs fichiers. Encore mieux il gère une reprise sur erreur au niveau de l’upload de ces fichiers, très pratique en cas de transfert de gros fichiers (utilisé par Youtube bien-sûr)

    GeoLoc

    Une API de géolocalisation est aussi présente (via un GPS, une cellule GSM ou une IP)

    Chrome

    Même si le titre de la session était nommée « Google Chrome », c’était plus une présentation du moteur de JavaScripts V8.

    D’abord les objectifs de Chrome (très bien illustré dans leur superbe BD) :

    • Stabilité
    • rapidité
    • intuitivité

    Kevin Milinkin a fait la présentation la plus technique de la journée. On a même eu droit à un slide montrant le code assembler utilisé.

    Déjà pourquoi faire un nouveau moteur de JavaScript ? La réponse est simple, au début des développements de Chrome il y a deux ans, la performance des moteurs Java Script existants n’etaient pas satisfaisante. C’est pour cette raison qu’ils ont lancé la réalisation de V8.

    Il nous présente ensuite les clés de la rapidité du moteur :

    • Hidden class hidden transition
    • Inline caching
    • Dynamic Machine Code Generation
    • Efficient Garbage Collection

    Ces points sont très bien expliqués ici. V8 a aussi acceleré le temps de démarrage de la machine virtuelle en permettant le chargement d’objets en mémoire depuis un SnapShot.

    Malheureusement il n’y a toujours pas de date pour la version Mac.

    Bilan

    Même si je n’ai pas été seduit par le CodeLab, j’ai passé une excellente journée. C’est toujours intéressant d’échanger avec d’autres développeurs.

  • Fuite de threads dans Jonas

    Depuis plusieurs mois nous avions détecté que le nombre de thread de notre serveur jonas augmentait sans arrêt. Un de mes collègues a donc pris le taureau par les cornes pour trouver l’origine du problème. Après 4 jours à fouiller dans le code source de Jonas, il a trouvé le problème au niveau du connecteur Joram (notre application utilise des JMS).

    Dans la classe
    org.objectweb.joram.client.connector.ManagedConnectionFactoryImpl, on peut lire :

    public Set getInvalidConnections(Set connectionSet) throws ResourceException {
      if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
        AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
           this+" getInvalidConnections("+connectionSet+")");
        Iterator it = connectionSet.iterator();
        ManagedConnectionImpl managedCx;
        while (it.hasNext()) {
          try {
            managedCx = (ManagedConnectionImpl) it.next();
            if (managedCx.isValid())
              connectionSet.remove(managedCx);
            }
          catch (ClassCastException exc) {}
      }
      return connectionSet;
    }

    Ca met en évidence deux règles de codage Java importantes qui ne sont pas respectées :

    1. Ne pas retourner la référence d’un paramètre en valeur de retour
    2. Eviter de modifier un paramètre d’une méthode
    La méthode getInvalidConnections permet de chercher dans la liste de connexions passées en paramètre celles qu’il faut libérer. Mais au lieu de mettre les connexions invalides dans une nouvelle collection, ils suppriment les connexions valides de la collection passée en paramètre. Du coup ces connexions ne sont plus dans la liste des connexions actives, elles ne seront donc jamais libérées.

    Depuis que nous avons patché le connecteur Joram, nous n’avons plus de fuite de thread :)

    Le patch :

      public Set getInvalidConnections(Set connectionSet) throws ResourceException {
      if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
        AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
          this+" getInvalidConnections("+connectionSet+")");
      Iterator it = connectionSet.iterator();
      ManagedConnectionImpl managedCx;
      java.util.HashSet invalidConnections = new java.util.HashSet();
      while (it.hasNext()) {
        try {
          managedCx = (ManagedConnectionImpl) it.next();
          if (!managedCx.isValid())
            invalidConnections.add(managedCx);
        }
        catch (ClassCastException exc) {}
      }
      return invalidConnections;
    }