<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
xmlns:media="http://search.yahoo.com/mrss/"
> <channel><title>Blog Xebia France</title> <atom:link href="http://blog.xebia.fr/feed/" rel="self" type="application/rss+xml" /><link>http://blog.xebia.fr</link> <description>J2EE, Agilité et SOA</description> <lastBuildDate>Fri, 03 Feb 2012 08:18:30 +0000</lastBuildDate> <language>fr</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=</generator> <copyright>CC BY-NC-ND 2.0 http://creativecommons.org/licenses/by-nc-nd/2.0/fr/</copyright> <managingEditor>blog-france@xebia.com (Xebia France)</managingEditor> <webMaster>blog-france@xebia.com (Xebia France)</webMaster> <ttl>1440</ttl> <image> <url>http://blog.xebia.fr/videos/xebia-podcast.png</url><title>Blog Xebia France</title><link>http://blog.xebia.fr</link> <width>144</width> <height>144</height> </image> <itunes:new-feed-url>http://blog.xebia.fr/feed/podcast/</itunes:new-feed-url> <itunes:subtitle>Les podcasts de Xebia France vous permettent de suivre l&#039;actualité autour de Java, de l&#039;agilité, des technologies Web et bien d&#039;autres. Xebia France est une entreprise spécialisée dans les technologies Java et JEE en environnement agi[...]</itunes:subtitle> <itunes:summary>Les podcasts de Xebia France vous permettent de suivre l&#039;actualité autour de Java, de l&#039;agilité, des technologies Web et bien d&#039;autres. Xebia France est une entreprise spécialisée dans les technologies Java et JEE en environnement agile.</itunes:summary> <itunes:keywords>Xebia, Java, JEE, SOA, Agile, Méthodes, Agiles</itunes:keywords> <itunes:category text="Technology" /> <itunes:category text="Technology"> <itunes:category text="Software How-To" /> </itunes:category> <itunes:category text="Technology"> <itunes:category text="Tech News" /> </itunes:category> <itunes:author>Xebia France</itunes:author> <itunes:owner> <itunes:name>Xebia France</itunes:name> <itunes:email>blog-france@xebia.com</itunes:email> </itunes:owner> <itunes:block>no</itunes:block> <itunes:explicit>no</itunes:explicit> <itunes:image href="http://blog.xebia.fr/videos/xebia-podcast.png" /> <item><title>Spring, Hibernate, DBUnit et Surefire &#8211; Parallélisez vos tests</title><link>http://blog.xebia.fr/2012/02/03/spring-hibernate-dbunit-et-surefire-parallelisez-vos-tests/</link> <comments>http://blog.xebia.fr/2012/02/03/spring-hibernate-dbunit-et-surefire-parallelisez-vos-tests/#comments</comments> <pubDate>Fri, 03 Feb 2012 06:17:38 +0000</pubDate> <dc:creator>Jean Helou</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Tests]]></category> <category><![CDATA[dbunit]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[surefire]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10527</guid> <description><![CDATA[Les DAO (Data Access Object) ou repository des applications contiennent souvent de l&#8217;information importante sur la façon dont les données d&#8217;une base doivent être consultées. Cette information prend la forme d&#8217;une logique métier qui est encodée dans un ou plusieurs langages, souvent un langage déclaratif (SQL, HSQL, JPQL, etc.) et un langage impératif (Java, Groovy, [...]]]></description> <content:encoded><![CDATA[<p>Les DAO (<a
href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html" rel="nofollow">Data Access Object</a>) ou <a
href="http://martinfowler.com/eaaCatalog/repository.html" rel="nofollow">repository </a> des applications contiennent souvent de l&#8217;information importante sur la façon dont les données d&#8217;une base doivent être consultées. Cette information prend la forme d&#8217;une logique métier qui est encodée dans un ou plusieurs langages, souvent un langage déclaratif (SQL, HSQL, JPQL, etc.) et un langage impératif (Java, Groovy, Scala, etc.).<br
/> Tester cette logique d&#8217;accès polyglotte peut s&#8217;avérer complexe et lent car ce type de test se prète mal aux techniques classiques de mock et nécessite plutôt l&#8217;écriture de tests d&#8217;intégration qui chargent une partie du contexte réel d&#8217;exécution. Par conséquent, les tests de cette couche sont parfois délaissés, voir abandonnés.</p><p>Cet article se propose de vous montrer comment réaliser de tels tests, avec un niveau d&#8217;isolation suffisant pour la parallélisation dans un processus multithread, tout en essayant de trouver le meilleur compromis avec le temps d&#8217;exécution de chaque test. Ces tests sont présentés dans une configuration très classique utilisant Spring et JPA/Hibernate.<br
/> L&#8217;implémentation utilise une base HSQLDB et quelques bibliothèques pour faciliter l&#8217;écriture du code, en essayant de rester aussi légere que possible. Les tests sont isolés pour que vous puissiez activer l&#8217;exécution parallèle du plugin Surefire de Maven au niveau des classes de test. Vous pourrez facilement dériver l&#8217;implémentation nécessaire à isoler vos tests au niveau des méthodes si vous le souhaitez.</p><h3><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Introduction"></a>Introduction</h3><p>Un premier réflexe est de réaliser des tests contre une base de donnée existante. L&#8217;automatisation de ces tests  mène très rapidement à des problèmes de reproductibilité et d&#8217;isolation, en particulier quand les traitements testés effectuent des opérations d&#8217;écriture dans la base de données, mais également parce que la base utilisée est souvent une base de développement que les développeurs peuvent être amenés à faire évoluer de manière incontrôlée. La solution immédiate est de créer une copie du jeu de données initial et de le recharger dans la base avant chaque test. Cette problématique, et sa conséquence, la gestion des jeux de données ont amené la création d&#8217;outils tels que <a
href="http://www.dbunit.org/" rel="nofollow">DBUnit</a>.</p><p>L&#8217;utilisation d&#8217;une base de données centralisée, même si elle est spécifique aux tests, amène son propre lot de problèmes : que se passe-t-il si plusieurs développeurs jouent leurs tests en même temps ? Les uns vont insérer leur jeu de données pendant que les autres font une écriture ; les tests ne sont pas isolés. Il faut créer une base de données par développeur.</p><p>Deux options s&#8217;offrent alors, la première consiste à créer un schéma pour chacun sur le serveur. Cela amène des problèmes de latences réseaux, de charge du serveur et rend impossible le travail en cas de coupure du réseau. Il vaut mieux pencher pour la seconde option et créer une instance sur la machine de chaque développeur. Comme ce sont souvent des machines de bureautique avec des disques lents,   un SGBD complet qui n&#8217;est finalement presque pas utilisé et qui consomme de précieuses ressouces est mal venu, surtout lorsqu&#8217;il faut partager ces ressources avec un IDE, un serveur d&#8217;application, &#8230; Reste la possibilité d&#8217;utiliser une base de données embarquée comme HyperHSQL (HSQLDB), H2, Derby, etc. L&#8217;instance est créée par le processus du test et détruite lorsqu&#8217;il se termine. Il reste à y charger la structure des tables et le tour est joué.</p><p>Ces tests d&#8217;intégration joués séquentiellement peuvent encore s&#8217;avérer trop lent, surtout dans le cadre d&#8217;un <em>build</em> complet qui joue tous les tests. Il convient alors de les paralléliser.</p><h3><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Structureduprojet"></a>Structure du projet</h3><p>Partons d&#8217;un projet classique utilisant Spring et JPA/Hibernate, packagé avec maven. La structure de projet prend la forme suivante :</p><p><span
style="display: block; text-align: center"><img
src="http://blog.xebia.fr/wp-content/uploads/2012/02/structure_projet.png" style="border: 0px solid black" /></span><br
/> Dans le dossier <em>main</em>, on retrouve les entités du modèle de données, les DAOs avec respectivement une interface et une implémentation et le descripteur de l&#8217;unité de persistance JPA.</p><p>Dans le dossier <em>test</em>, les tests des deux DAOs, les fichiers de configuration XML Spring, un fichier de propriétés pour hsqldb et les deux jeux de données pour les tests au format XML.</p><h3><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Cr%C3%A9erlestestsavecspring%26dbunit"></a>Créer les tests avec spring &amp; dbunit</h3><h4><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Lecoded%27untest"></a>Le code d&#8217;un test</h4><h5><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-AddressDaoTest.java"></a>AddressDaoTest.java</h5><pre class="brush: java; gutter: true; title: ; notranslate">
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({&quot;applicationContext-test.xml&quot;})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
                         DataSetTestExecutionListener.class})
@DataSet(value = &quot;AddressDaoTest.xml&quot;)
public class AddressDaoTest {
    @Autowired
    private AddressDao addressDao;
    @Test
    public void testFindByAddressname() {
        Address user = addressDao.findByAddress(&quot;a&quot;);
        assertNotNull(user);
    }
    @Test
    public void testFindByAbsentAddressname() {
        Address user = addressDao.findByAddress(&quot;c&quot;);
        assertNull(user);
    }
}
</pre><p>Ce test est exécuté avec <code>SpringJunit4ClassRunner</code> qui créé le contexte Spring avec les fichiers indiqués dans l&#8217;annotation <code>@ContextConfiguration</code> et le met en cache.</p><p>La mise en cache est un détail important pour l&#8217;exécution de plusieurs classes de tests. Si vous avez plusieurs classes de tests, déclarant exactement la même annotation <code>@ContextConfiguration</code> qui sont lancées dans un même processus, seule la première aura besoin d&#8217;initialiser le contexte Spring. Les suivantes pourront réutiliser le contexte économisant ainsi : le parsing de la configuration, le scan du classpath à la recherche d&#8217;annotations ainsi que les diverses phases d&#8217;initialisations des beans utilisés dans le contexte.</p><p>L&#8217;annotation <code>@TestExecutionListener</code> fournie par spring-test permet d&#8217;enregistrer des classes qui peuvent se brancher dans le cycle de vie d&#8217;exécution d&#8217;un test (before test class, before test method, &#8230;). L&#8217;utilité des listeners utilisés ici est précisée un peu plus bas.</p><h4><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Laconfiguration"></a>La configuration</h4><p>Notre contexte de test contient les éléments standards d&#8217;un contexte Spring JPA/Hibernate mais quelques points méritent d&#8217;être notés pour que nous puissions revenir dessus.</p><h5><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Lad%C3%A9clarationdeladatasourcehsqldb"></a>La déclaration de la datasource hsqldb</h5><pre class="brush: xml; gutter: true; title: ; notranslate">
&lt;bean id=&quot;dataSource&quot; class=&quot;org.springframework.jdbc.datasource.DriverManagerDataSource&quot;&gt;
    &lt;property name=&quot;driverClassName&quot; value=&quot;${ds.driver=org.hsqldb.jdbcDriver}&quot;/&gt;
    &lt;property name=&quot;url&quot; value=&quot;${ds.url=jdbc:hsqldb:mem:test}&quot;/&gt;
    &lt;property name=&quot;username&quot; value=&quot;${ds.username=sa}&quot;/&gt;
    &lt;property name=&quot;password&quot; value=&quot;${ds.password=}&quot;/&gt;
&lt;/bean&gt;
</pre><h5><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Lad%C3%A9clarationdelafactoryJPA%2FHibernate"></a>La déclaration de la factory JPA/Hibernate</h5><pre class="brush: xml; gutter: true; title: ; notranslate">
&lt;bean id=&quot;jpaVendorAdapter&quot; class=&quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&quot;&gt;
    &lt;property name=&quot;databasePlatform&quot; value=&quot;${hibernate.dialect}&lt;&quot;/&gt;
&lt;/bean&gt;
&lt;bean id=&quot;emf&quot; class=&quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&quot;&gt;
    &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot;/&gt;
    &lt;property name=&quot;persistenceUnitName&quot; value=&quot;pdbunit&quot;/&gt;
    &lt;property name=&quot;jpaVendorAdapter&quot; ref=&quot;jpaVendorAdapter&quot;/&gt;
    &lt;property name=&quot;jpaProperties&quot;&gt;
        &lt;props&gt;
            &lt;prop key=&quot;hibernate.dialect&quot;&gt;${hibernate.dialect}&lt;/prop&gt;
            &lt;prop key=&quot;hibernate.hbm2ddl.auto&quot;&gt;${hibernate.hbm2ddl.auto=update}&lt;/prop&gt;
        &lt;/props&gt;
    &lt;/property&gt;
&lt;/bean&gt;
</pre><h4><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Leslisteners"></a>Les listeners</h4><h5><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-DependencyInjectionTestExecutionListener"></a>DependencyInjectionTestExecutionListener</h5><p>L&#8217;utilisation de ce listener défini par l&#8217;API <a
href="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/testing.html" rel="nofollow">spring-test</a> permet simplement d&#8217;utiliser les annotations d&#8217;injection de dépendance (<code>@Autowired</code>,<code>@Resource</code>,&#8230;) sur des éléments de la classe de test. Ainsi, dans le test de DAO vu précédemment l&#8217;instance du DAO sera injectée avant l&#8217;exécution du test.</p><h5><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-DataSetTestExecutionListener"></a>DataSetTestExecutionListener</h5><p>Ce listener est défini dans l&#8217;API <a
href="https://github.com/excilys/spring-dbunit" rel="nofollow">spring-dbunit</a> et permet l&#8217;utilisation de l&#8217;annotation <code>@Dataset</code> sur une classe ou sur une méthode de test.</p><p>Cette annotation utilise <a
href="http://www.dbunit.org/" rel="nofollow">dbunit</a> pour charger un jeu de données avant chaque test et pour le supprimer après chaque test.</p><p>Par défaut, cette annotation cherche un fichier nommé dataSet.xml dans le même package que la classe de test qui porte l&#8217;annotation. Il est possible de changer le nom du fichier, d&#8217;en charger plusieurs, bref de choisir son jeu de données.</p><h4><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Unpremierpalier"></a>Un premier palier</h4><p>À ce stade, nous avons donc des tests qui chargent leur jeu de données dans une base mémoire avant de s&#8217;exécuter. Isolés du monde extérieur ils ne risquent pas d&#8217;échouer à cause d&#8217;un changement involontaire par une autre personne, d&#8217;une perte de connexion réseau ou d&#8217;une autre exécution de la suite de test par un second développeur.</p><h3><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Parall%C3%A8liserlestestsdansmaven"></a>Parallèliser les tests dans maven</h3><p>En l&#8217;état actuel, les tests ne peuvent pas être exécutés en multi-thread au sein d&#8217;un même processus, ce que sait faire le plugin surefire de maven en charge de l&#8217;exécution des tests. Unitairement rapides, la contrainte de les exécuter en séquentiel empêche de profiter pleinement des processeurs multi-cores des ordinateurs modernes. Les tests ne sont utiles que si ils sont exécutés et ils ne sont exécutés que si ils sont suffisamment rapides.</p><h4><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Unebasededonn%C3%A9eparthread"></a>Une base de donnée par thread</h4><p>Ce qui fait échouer l&#8217;exécution en mode multi-thread, ce sont les collisions entre les différents jeux de données manipulés par dbunit (deux jeux de données chargés en même temps peuvent modifier le résultat de certaines requêtes), sans compter les opérations d&#8217;écritures potentielles des traitements testés. Il faudrait que chaque test dispose de sa propre base de donnée.</p><h5><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-ThreadUniqueDriverManagerDataSource"></a>ThreadUniqueDriverManagerDataSource</h5><pre class="brush: java; gutter: true; title: ; notranslate">
public class ThreadUniqueDriverManagerDataSource extends
  DriverManagerDataSource {
 @Override
 public String getUrl() {
  long tId = Thread.currentThread().getId();
  return super.getUrl() + tId;
 }
}
</pre><p>En utilisant cette surcharge de DriverManagerDataSource comme classe d&#8217;implémentation pour votre dataSource, chaque thread accédera à sa propre base de données mémoire.</p><pre class="brush: xml; gutter: true; title: ; notranslate">
&lt;bean id=&quot;dataSource&quot; class=&quot;fr.xebia.jdbc.datasource.ThreadUniqueDriverManagerDataSource&quot;&gt;
    &lt;property name=&quot;driverClassName&quot; value=&quot;${ds.driver=org.hsqldb.jdbcDriver}&quot;/&gt;
    &lt;property name=&quot;url&quot; value=&quot;${ds.url=jdbc:hsqldb:mem:test}&quot;/&gt;
    &lt;property name=&quot;username&quot; value=&quot;${ds.username=sa}&quot;/&gt;
    &lt;property name=&quot;password&quot; value=&quot;${ds.password=}&quot;/&gt;
&lt;/bean&gt;
</pre><p>Il reste un problème: le contexte Spring n&#8217;est chargé et initialisé qu&#8217;une seule fois, par conséquent Hibernate ne créé la structure des tables qu&#8217;une seule fois. Si nous tentions d&#8217;exécuter nos tests, le &laquo;&nbsp;premier&nbsp;&raquo; &#8211; celui dans lequel le contexte Spring est initialisé &#8211; réussirait. Les autres échoueraient en se plaignant que les tables nécessaires à l&#8217;insertion de leur jeu de données n&#8217;existent pas.</p><p>Il est possible de forcer le runner de Spring à réinitialiser un contexte pour chaque classe de test, mais cette initialisation est coûteuse et tout ce dont nous avons besoin est de créer les tables dans la base de données, tout le reste fonctionne très bien sans réinitialisation.</p><h4><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Recr%C3%A9erlastructuredelabasededonn%C3%A9esdanschaquethread."></a>Recréer la structure de la base de données dans chaque thread.</h4><p>Sachant que les listeners de test sont exécutés dans l&#8217;ordre de leur déclaration, il nous faut donc un listener qui soit exécuté après la création du contexte mais avant le chargement des données et qui se charge de recréer la structure. Nous avons déjà du code capable de recréer la structure dans Hibernate, il faut donc l&#8217;exécuter à nouveau pour chaque nouvelle base. La dernière donnée est le niveau de parallélisation, le maven-surefire-plugin est capable de paralléliser aux niveaux :  &laquo;&nbsp;classes&nbsp;&raquo;, &laquo;&nbsp;methods&nbsp;&raquo;, &laquo;&nbsp;both&nbsp;&raquo;. Il faudra adapter le listener en fonction du niveau choisi.</p><p>Dans la suite nous allons chercher à exécuter le code parallélisé au niveau &laquo;&nbsp;classes&nbsp;&raquo;, notre TestListener peut donc s&#8217;exécuter &laquo;&nbsp;beforeTestClass&nbsp;&raquo;.</p><h5><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-JpaHibernateDbSetupTestListener"></a>JpaHibernateDbSetupTestListener</h5><p>Le code du listener suivant est lié à l&#8217;utilisation JPA/Hibernate. Il ne devrait pas être très difficile de dériver un listener pour d&#8217;autres solutions de persistance, du moment que l&#8217;on sait créer la structure de la base de données.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public class JpaHibernateDbSetupTestListener extends AbstractTestExecutionListener {
    @Override
    public void beforeTestClass(TestContext testContext) throws Exception {
        super.beforeTestMethod(testContext);
        Map&lt;String, EntityManagerFactoryInfo&gt; emfsMap = testContext.getApplicationContext().getBeansOfType(
                EntityManagerFactoryInfo.class);
        for (Map.Entry&lt;String, EntityManagerFactoryInfo&gt; emfByName : emfsMap.entrySet()) {
            EntityManagerFactoryInfo entityManagerFactoryInfo = emfByName.getValue();
            String puName = entityManagerFactoryInfo.getPersistenceUnitInfo().getPersistenceUnitName();
            HibernatePersistenceCacheUnit persistenceInformation = HibernatePersistenceCache.getPersistenceInformation(puName);
            SchemaExport schemaExport = new SchemaExport(persistenceInformation.getHibernateConfiguration(),
                    persistenceInformation.getSettings());
            schemaExport.execute(false, true, false, false);
        }
    }
}
</pre><p>Cette implémentation nécessite des modifications supplémentaires à notre environnement de test. Elle repose sur la présence d&#8217;un cache des informations de persistance (<code>HibernatePersistenceCache</code>) dans lequel sont stockées les informations nécessaires à la recréation du SchemaExport.</p><p>Les informations de configuration manipulées par SchemaExport ne sont normalement pas accessibles une fois l&#8217;initialisation d&#8217;Hibernate terminée. Il faut donc les capturer lors de l&#8217;initialisation et les ajouter au cache. Pour cela nous allons devoir remplacer l&#8217;adaptateur Spring <code>org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter</code> par une implémentation maison.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public class HibernateJpaVendorParallelAdapter extends HibernateJpaVendorAdapter {
  private final PersistenceProvider persistenceProvider = new CachingHibernatePersistence();
  @Override
  public PersistenceProvider getPersistenceProvider() {
    return this.persistenceProvider;
  }
}
</pre><p>Le remplacement se fait dans le fichier de définition du contexte Spring, ce qui explique l&#8217;externalisation de la définition du jpaVendorAdapter :</p><pre class="brush: xml; gutter: true; title: ; notranslate">
&lt;bean id=&quot;jpaVendorAdapter&quot; class=&quot;fr.xebia.test.utils.parallel.jpa.hibernate.HibernateJpaVendorParallelAdapter&quot;&gt;
        &lt;property name=&quot;databasePlatform&quot; value=&quot;org.hibernate.dialect.Oracle10gDialect&quot;/&gt;
&lt;/bean&gt;
</pre><p>La capture des informations de configuration peut alors se faire dans <code>CachingHibernatePersistence</code> :</p><pre class="brush: java; gutter: true; title: ; notranslate">
public class CachingHibernatePersistence extends HibernatePersistence {
  @Override
  public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map overridenProperties) {
    Ejb3Configuration cfg = new Ejb3Configuration();
    Ejb3Configuration configured = cfg.configure(persistenceUnitName, overridenProperties);
    cacheConfig(persistenceUnitName, null, overridenProperties, configured);
    return configured != null ? configured.buildEntityManagerFactory() : null;
  }
  @Override
  public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) {
    Ejb3Configuration cfg = new Ejb3Configuration();
    Ejb3Configuration configured = cfg.configure(info, map);
    cacheConfig(info.getPersistenceUnitName(),info, map, configured);
    return configured != null ? configured.buildEntityManagerFactory() : null;
  }
  private void cacheConfig(String name, PersistenceUnitInfo info, Map map, Ejb3Configuration configured) {
    if (configured != null) {
      HibernatePersistenceCacheUnit cachedInfo = new HibernatePersistenceCacheUnit(name);
      cachedInfo.setPersistenceUnitInfo(info);
      cachedInfo.setPropertyMap(map);
      cachedInfo.setHibernateConfiguration(configured.getHibernateConfiguration());
      cachedInfo.setSettings(configured.buildSettings());
      HibernatePersistenceCache.addPersistenceInformation(cachedInfo);
    }
  }
}
</pre><p>HibernatePersistenceCacheUnit est un simple conteneur pour les données qui nous intéressent :</p><pre class="brush: java; gutter: true; title: ; notranslate">
public class HibernatePersistenceCacheUnit {
    private final String name;
    private PersistenceUnitInfo persistenceUnitInfo;
    private Map&lt;String, Object&gt; propertyMap;
    private Configuration hibernateConfiguration;
    private Settings settings;
    private SessionFactory sessionFactory;
    //...
}
</pre><p>et enfin le cache lui-même est une implémentation basique utilisant une simple HashMap :</p><pre class="brush: java; gutter: true; title: ; notranslate">
public class HibernatePersistenceCache {
  private static final Map&lt;String, HibernatePersistenceCacheUnit&gt; persistenceInformationMap = new HashMap&lt;String, HibernatePersistenceCacheUnit&gt;();
  public static void addPersistenceInformation(HibernatePersistenceCacheUnit persistenceInformation) {
    assert(persistenceInformation != null);
    assert(persistenceInformation.getName() != null);
    persistenceInformationMap.put(persistenceInformation.getName(), persistenceInformation);
  }
  public static List&lt;HibernatePersistenceCacheUnit&gt; getPersistenceInformations() {
    return new ArrayList&lt;HibernatePersistenceCacheUnit&gt;(persistenceInformationMap.values());
  }
  public static void clearPersistenceInformations() {
    persistenceInformationMap.clear();
  }
  public static HibernatePersistenceCacheUnit getPersistenceInformation(String name) {
    return persistenceInformationMap.get(name);
  }
}
</pre><p>Il ne reste plus qu&#8217;à déclarer le listener au bon endroit dans le test :</p><pre class="brush: java; gutter: true; title: ; notranslate">
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({&quot;applicationContext-test.xml&quot;})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, JpaHibernateDbSetupTestListener.class, DataSetTestExecutionListener.class})
@DataSet(value = &quot;AddressDaoTest.xml&quot;)
public class AddressDaoTest {
    @Autowired
    private AddressDao addressDao;
    @Test
    public void testFindByAddressname() {
        Address user = addressDao.findByAddress(&quot;a&quot;);
        assertNotNull(user);
    }
    @Test
    public void testFindByAbsentAddressname() {
        Address user = addressDao.findByAddress(&quot;c&quot;);
        assertNull(user);
    }
}
</pre><p>et à activer la parallélisation des tests lors de l&#8217;exécution du plugin surefire</p><pre class="brush: xml; gutter: true; title: ; notranslate">
&lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
    &lt;version&gt;2.11&lt;/version&gt;
    &lt;configuration&gt;
        &lt;parallel&gt;classes&lt;/parallel&gt;
    &lt;/configuration&gt;
&lt;/plugin&gt;
</pre><p>Vos tests sont maintenant suffisament isolés pour que surefire puisse exécuter vos classes de tests en multi-thread.</p><h5><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Autrespistesdelisteners"></a>Autres pistes de listeners</h5><p>Il existe plusieurs moyens de résoudre le problème du rechargement de la structure de la base de données dans les bases créées en mémoire. Si vous disposez d&#8217;un outil de migration comme <a
href="http://code.google.com/p/flyway/">flyway</a>, ou que votre équipe garde scrupuleusement à jour un fichier avec la totalité de la structure de données de la base, vous pouvez créer votre propre listener pour charger la base à partir de cette référence. Vous pouvez également initialiser une base de données fichier plutôt que mémoire et en créer des copies qui seront utilisées par les différents Threads.</p><h3><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Desbasesdedonn%C3%A9esetdesdialectes"></a>Des bases de données et des dialectes</h3><p>Utiliser une base de donnée mémoire n&#8217;est pas complètement anodin. Chaque SGBD parle son propre &#8216;dialecte&#8217; de SQL, souvent un sous-ensemble auquel peut s&#8217;ajouter des extensions spécifiques de l&#8217;éditeur.<br
/> L&#8217;idée dans cet article est de maximiser les gains obtenus en testant les commandes SQL qui sont partagées entre votre SGBD de production et la base mémoire utilisée. L&#8217;utilisation de moteurs ORM comme Hibernate tends à normaliser le sous-ensemble de commandes utilisées, ce qui facilite la compatibilité pour la plupart des requêtes. Il peut néanmoins être nécessaire d&#8217;utiliser des requêtes natives pour certaines optimisations ou pour certains cas d&#8217;utilisation spécifiques. Même comme ça, les cas d&#8217;incompatibilités peuvent être réduit par l&#8217;utilisation d&#8217;une base mémoire adaptée. Recherchez la base mémoire qui a un dialecte aussi proche que possible de celui de votre moteur de production pour pouvoir tester autant de requêtes que possible.</p><p>Le code qui malgré tout restera incompatible pourra être testé dans le cadre de tests d&#8217;acceptation sur un environnement complet. Respectez la <a
href="http://fr.wikipedia.org/wiki/Loi_de_Pareto" rel="nofollow">loi de Pareto</a> en dépensant 20% d&#8217;effort pour 80% des gains, et ne modifiez pas une requête optimisée pour votre moteur de production juste pour pouvoir la tester dans un moteur de test.</p><h3><a
name="Spring%2CHibernate%2CDBUnitetSurefire-Parall%C3%A9lisezvostests-Codedel%27article"></a>Code de l&#8217;article</h3><p>Vous retrouverez sur github</p><ul><li>le <a
href="https://github.com/jeantil/spring-dbunit-utils-demo/" rel="nofollow">projet de démo</a> qui a servi de base au code de l&#8217;article</li><li>un <a
href="https://github.com/jeantil/spring-dbunit-utils" rel="nofollow">projet</a> contenant l&#8217;implémentation du listener et du cache sous forme de librairie maven.</li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/02/03/spring-hibernate-dbunit-et-surefire-parallelisez-vos-tests/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Java EE 6, une plateforme simple et légère. Spring n’a qu’à bien se tenir !</title><link>http://blog.xebia.fr/2012/02/01/java-ee-6-une-plateforme-simple-et-legere-spring-na-qua-bien-se-tenir/</link> <comments>http://blog.xebia.fr/2012/02/01/java-ee-6-une-plateforme-simple-et-legere-spring-na-qua-bien-se-tenir/#comments</comments> <pubDate>Wed, 01 Feb 2012 04:20:00 +0000</pubDate> <dc:creator>Romain Schlick</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[CDI]]></category> <category><![CDATA[DeltaSpike]]></category> <category><![CDATA[EJB]]></category> <category><![CDATA[Java EE 6]]></category> <category><![CDATA[JSF]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[Weld]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10500</guid> <description><![CDATA[La plateforme Java EE conserve de nos jours encore une mauvaise réputation. Les fameux EJB 2 et conteneurs lourds démarrant en plusieurs minutes vous rappelleront quelques bons souvenirs. L&#8217;arrivée de Spring a ouvert la voie aux conteneurs légers, à l&#8217;inversion de contrôle, ou encore à l&#8217;injection de dépendances; et est devenue la solution de référence. [...]]]></description> <content:encoded><![CDATA[<p>La plateforme Java EE conserve de nos jours encore une mauvaise réputation. Les fameux EJB 2 et conteneurs lourds démarrant en plusieurs minutes vous rappelleront quelques bons souvenirs. L&#8217;arrivée de Spring a ouvert la voie aux conteneurs légers, à l&#8217;inversion de contrôle, ou encore à l&#8217;injection de dépendances; et est devenue la solution de référence. Cependant, la plateforme Java EE a beaucoup évolué entre temps.</p><p>Nous allons voir que Java EE 6 n&#8217;a maintenant rien à envier à Spring. Cette plateforme est devenue légère et simple à prendre en main. Toutes les spécifications ne seront pas abordées en détails.  Nous parlerons plutôt de conteneurs légers et testables, de managed beans, d&#8217;EJB Lite, ainsi que des nombreux services et patterns offert par la plateforme.  Nous terminerons par la spécification CDI et ses extensions portables, qui offrent de belles perspectives à la plateforme Java EE 6.</p><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-Spring%2Cc%E2%80%99estquandm%C3%AAmebienchouette%5C%21"></a>Spring, c’est quand même bien chouette!</h3><p>Spring, Spring, Spring&#8230; Oui, <a
href="http://www.springsource.org/get-started" rel="nofollow">Spring</a> est un outil qui a révolutionné nos vies de développeurs et qui s’est très rapidement installé chez nos clients. Il a apporté avec lui des paradigmes de programmation comme l’IOC (<a
href="http://fr.wikipedia.org/wiki/Inversion_de_contr%C3%B4le" rel="nofollow">Inversion Of Control</a>),  la DI (<a
href="http://en.wikipedia.org/wiki/Dependency_injection" rel="nofollow">dependency injection</a>), l&#8217;utilisation de simple POJOs, mais aussi de la simplicité avec ses xTemplate bien utiles. Arrivé en 2003, Spring s’est imposé rapidement dans les entreprises face au standard J2EE 1.4. Ce dernier était un peu Goliath J2EE. Souvenez vous de cette grosse usine à gaz avec ses EJB 2, son conteneur lourd packagé en <em>ear,</em> qui mettait des minutes à démarrer sur un serveur WAS.  Face à lui, un David nommé Spring doté de simples beans POJO, d&#8217;un conteneur léger  et d&#8217;un packaging war déployable sur un simple serveur web, comme <em>Tomcat</em>. Grâce à eux,  Spring s&#8217;est imposé dans les entreprises en quelques années .</p><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-JavaEE5%3Ad%C3%A9butdelacured%E2%80%99amaigrissement"></a>Java EE 5: début de la cure d’amaigrissement</h3><p>Mais tout cela, c’était il y a neuf ans et depuis un sacré chemin a été parcouru par la spécification Java EE. En 2006, Java EE 5 est arrivé enrichi de nouvelles transformations. Tout d&#8217;abord, son utilisation a été rendue plus simple grâce à l’utilisation massive des annotations. Les EJB 3.0 en ont bénéficié et sont devenus ainsi injectables et plus faciles à implémenter. Il y a eu aussi l’arrivée de JPA, une nouvelle API de persistance, fortement inspirée d&#8217;Hibernate qui a fait disparaître les anciens Entity EJB CMP/BMP.</p><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-JavaEE6%2C%C3%A7arocks%5C%21"></a>Java EE 6, ça rocks !</h3><p>Sortie en 2009, <a
href="http://www.oracle.com/technetwork/java/javaee/overview/index.html">Java EE 6</a> a progressé sur la voie de la simplicité avec l’utilisation massive des annotations et des POJO.  A tel point qu’on peut se demander maintenant qui est David et qui est Goliath.<br
/> Des API existantes ont encore prospéré de manière significative, comme les EJB 3.1 (dont les EJB Lite), JPA 2.0, JSF 2.0, ou encore Servlet 3.0. De nouvelles API ont fait leur apparition comme CDI 1.0, @Inject 1.0, Interceptors 1.1, JAX-RS 1.1, ou encore Bean Validation 1.0. Et, toujours dans un esprit de “light is right”, de vieilles spécifications comme JAX-RPC, JAX-R, ou JSR88 ont été déclarées “pruned” et devraient disparaître pour la prochaine version de Java EE 7.<br
/> Par ailleurs, cette version introduit enfin des noms JNDI standard et donc portables entre les différents serveurs d’application. Cette version embrasse aussi les paradigmes de <em>convention-over-configuration</em> et de <em>configuration-by-exception</em>, qui permettent de ne presque plus rien avoir à configurer, le conteneur appliquant des paramètres par défaut tant qu’il n’ y a pas d’exception. Ainsi, on obtient des applications avec très peu de fichiers de configuration xml.<br
/> Avec Servlet 3.0, le bon vieux web.xml est devenu optionnel. Ainsi, ne soyez pas étonné de ne voir qu’en tout et pour tout seulement deux fichiers de configuration dans un projet Java EE: un fichier persistence.xml pour gérer la persistance avec JPA et un fichier beans.xml (qui peut rester vide) pour les managed beans.</p><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-Unpackagingwargr%C3%A2ceauWebProfile1.0etauxEJBLite"></a>Un packaging war grâce au Web Profile 1.0 et aux EJB Lite</h3><p>L’arrivée des Profiles est une autre nouveauté majeure, ouvrant de nouvelles perspectives. En particulier, le <a
href="http://java.sun.com/developer/technicalArticles/JavaEE/JavaEE6Overview_Part3.html#tab1" rel="nofollow">Web Profile</a> qui reprend un sous-ensemble de Java EE et qui permet de packager son application dans un simple war. Le Web Profile embarque les spécifications essentielles communément requises pour développer une application web d’aujourd’hui : JSF, JSP, Servlet, EL, JSTL, EJB Lite, CDI, etc. Cependant, il a été nécessaire de créer des EJB “Lite”, qui n’implémentent pas toute la spécification EJB. Ils conservent néanmoins le principal, à savoir : les Session Beans, l’injection, les interceptors, la transaction et sécurité. Ces sont donc de simples classes POJO, qui n’implémentent pas d’interfaces (appelée ‘no-interface view’). Les EJB Lite sont ainsi déployables dans un simple war.</p><pre class="brush: java; gutter: true; title: ; notranslate">
//Exemple d'un EJB Lite avec une no-interface view
  @Stateless
   public class HelloBean {
       public String sayHello() {
           String message = propertiesBean.getProperty(&quot;hello.message&quot;);
           return message;
       }
   }
</pre><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-Desconteneursl%C3%A9gersetembarqu%C3%A9s"></a>Des conteneurs légers et embarqués</h3><p>Vous vous souvenez sans doute des serveurs d&#8217;application &laquo;&nbsp;usine à gaz&nbsp;&raquo;, qui prenaient parfois quelques minutes à démarrer et à déployer votre application Java EE, . Il était aussi très difficile de tester ces EJB et de réaliser des tests d&#8217;intégration automatisés. Ces temps là sont maintenant révolus! Aujourd&#8217;hui, nous écrivons de plus en plus des tests unitaires et d&#8217;intégration. Nous avons besoin de déployer nos applications le plus rapidement possible pour ne pas être trop pénalisé durant notre cycle de développement. Pour répondre à ces besoins, les EJB 3.1 ont introduit l&#8217;idée de conteneurs JEE embarqués. Ces conteneurs EJB implémentent l&#8217;API javax.ejb.embeddable et sont packagés dans un jar exécutable n&#8217;importe où : du code Java SE, des tests Junit, ou encore un conteneur web. Ce conteneur s’exécute donc au sein de la même JVM que votre programme. Vous pouvez ainsi débugger facilement vos applications avec votre IDE préféré.</p><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-...ettestables%5C%21"></a>&#8230;et testables!</h3><p>Voici un exemple de code Junit, où l&#8217;on peut voir comme il est simple de créer un conteneur EJB embarqué à l&#8217;aide de API <a
href="http://docs.oracle.com/javaee/6/api/javax/ejb/embeddable/EJBContainer.html" rel="nofollow">javax.ejb.embeddable.EJBContainer</a>. Des propriétés sont passées à l&#8217; EJBContainer pour préciser où sont les ressources et classes Java. Ensuite, pour récupérer l&#8217;EJB, il suffit de faire un lookup dans le contexte en utilisant le nom JNDI portable de l&#8217;EJB.</p><pre class="brush: java; gutter: true; title: ; notranslate">
private static EJBContainer ec;
private static Context ctx;
@BeforeClass
public static void createEmbeddedTestContainer() throws Exception {
       Map properties = new HashMap();
       properties.put(EJBContainer.MODULES, new File[]{new File(&quot;target/classes&quot;), new File(&quot;target/test-classes&quot;)});
       ec = EJBContainer.createEJBContainer(properties);
       ctx = ec.getContext();
}
//Pour récuperer un EJB:
ctx.lookup(&quot;java:global/classes/MyEJB&quot;)
</pre><p>Par ailleurs, il existe une manière plus évoluée pour tester son conteneur EJB à l&#8217;aide de <a
href="http://www.jboss.org/arquillian" rel="nofollow">JBoss Arquillian</a> et <a
href="http://www.jboss.org/shrinkwrap" rel="nofollow">ShrinkWrap</a>. Arquillian se pluggue sous forme de runner Junit et s&#8217;occupe de créer le conteneur pour vous. Il permet ainsi d&#8217;injecter directement avec @Inject vos beans. ShrinkWrap est un petit utilitaire qui permet quant à lui de créer une archive jar contenant les classes et fichiers ressources du projet. Arquillian à l&#8217;aide de l&#8217;annotation @Deployment va récupérer cette archive au moment de démarrer le conteneur. </p><pre class="brush: java; gutter: true; title: ; notranslate">
@RunWith(Arquillian.class)
public class MyEJBTest {
   @Deployment
   public static JavaArchive createDeployment() {
      return ShrinkWrap.create(JavaArchive.class, &quot;test.jar&quot;)
         .addClasses(MyEJB.class, AnotherClass.class);
   }
   @Inject
   private MyEJB myEJB;
</pre><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-Lesserveursd%27applicationsontmisleturbo"></a>Les serveurs d&#8217;applications ont mis le turbo</h3><p>Il existe quelques serveurs qui implémentent le Full Profile  Java  EE 6 et <a
href="http://www.oracle.com/technetwork/java/javaee/overview/compatibility-jsp-136984.html" rel="nofollow">certifiés par Oracle</a>, comme Oracle GlassFish Server 3.x,  IBM  WebSphere Application Server 8.0, ou encore Apache Geronimo 3.x. Mais grâce au Web Profile, on voit apparaitre de nombreux  serveurs Java  EE 6 Web Profile, comme: Jboss 7, Apache TomEE, ou encore Caucho   Resin.</p><p>Prenons par exemple, <a
href="http://openejb.apache.org/" rel="nofollow">Apache TomEE</a>, qui n&#8217;est autre qu&#8217;un serveur  Tomcat, auquel on a ajouté quelques jars, comme OpenWebBeans, OpenEJB,  OpenJPA et MyFaces pour qu&#8217;il soit compatible Java EE 6 Web Profile.  Comme le souligne <a
href="http://agoncal.wordpress.com/2011/10/20/o-java-ee-6-application-servers-where-art-thou/" rel="nofollow">Antonio Goncalves</a>, Java EE expert member, <b>ces serveurs démarrent très  rapidement:</b>  La plupart en moins de 4 secondes à comparer avec un simple  Tomcat qui démarre en 0,7s. On oubliera WebSphere qui reste encore d&#8217;une lenteur accablante avec un démarrage en 48s. La version Full Profile de GlassFish nous rassure avec un démarrage en à peine 3s. On voit bien que Java EE devient de plus  en plus rapide, simple à utiliser et s&#8217;oriente vers une architecture de  plus en plus modulaire. </p><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-AvecCDI%2Coninjectetoutdanstout%5C%21"></a>Avec CDI, on injecte tout dans tout!</h3><p>En parallèle de la notion de conteneur léger, l&#8217;API Managed Beans 1.0 décrit que toute classe POJO est potentiellement un bean managé par le conteneur. Ce dernier doit lui fournir un certain nombre de services simples, comme la gestion du cycle de vie du bean avec @PostConstruct et @PreDestroy, des interceptors  “à la AOP” avec le @Interceptor, et le @AroundInvoke, ou encore de l’injection de dépendances avec @Inject, et @Resource.</p><p>CDI 1.0 est une API majeure dans Java EE 6 qui permet entre autre de réaliser l&#8217;injection de dépendance et bien plus comme nous le verrons par la suite. L&#8217;implémentation de référence est <a
href="http://seamframework.org/Weld" rel="nofollow">JBoss Weld</a>. Ici, le mot d&#8217;ordre est loose coupling, strong typing. Contrairement aux beans Spring, qui sont identifiés par des String, et donc sources d&#8217;erreurs au runtime, CDI a choisi la voix du typage fort en utilisant des annotations. Tout managed bean est injectable dans un autre. Bref, maintenant on peut vraiment injecter tout dans tout ! A son chargement le conteneur CDI va scanner tous les jars de son classpath à la recherche d&#8217;un fichier beans.xml. Si un fichier est trouvé, il va créer des managed beans pour toutes les classes concernées. Ce type de chargement permet de réduire le temps de création du conteneur CDI et d&#8217;exclure facilement les jars que l&#8217;on ne veut pas manager. Par défaut, le fichier beans.xml peut rester vide, ce sont alors les annotations, qui seront utilisées. Si vous configurez le fichier, vous pourrez définir ou surcharger les propriétés d&#8217;un bean : les informations du fichier xml ayant prédominance par rapport aux annotations.</p><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-Lesscopes"></a>Les scopes</h4><p>Tout bean dispose d&#8217;un scope. Par défaut, le scope est implicitement annoté @Dependent, ce qui revient à créer une instance du bean pour chaque objet dépendant de lui. D&#8217;autres scopes sont proposés: @RequestScoped, @SessionScoped, @ApplicationScoped, ou encore @ConversationScoped. Il est possible de créer ses propres scopes métiers. Il existe également une annotation @New pour forcer l&#8217;injection d&#8217;une nouvelle instance d&#8217;un bean, même si celui-ci a un scope Application par exemple.</p><pre class="brush: java; gutter: true; title: ; notranslate">
@Inject @New Calculator calculator;
@ApplicationScoped
public class Calculator {...}
</pre><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-L%27injectionavec@Inject"></a>L&#8217;injection avec @Inject</h4><p>Ainsi, pour injecter un bean, il suffit d&#8217;annoter une classe, une propriété, ou un paramètre avec l&#8217;annotation @Inject. Les beans sont identifiés de plusieurs manières possibles. La première méthode utilise un @Qualifier. Par défaut, si l&#8217;on ne précise rien, c&#8217;est le qualifier @Default qui est appliqué.</p><pre class="brush: java; gutter: true; title: ; notranslate">
@Inject
private CustomerDao customerDao;
//Equivalent à:
@Inject @Default
private CustomerDao customerDao;
</pre><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-Identifierunbeanavec@Qualifier"></a>Identifier un bean avec @Qualifier</h4><p>Si votre bean a plusieurs implémentations et afin de prévenir des ambiguïtés au niveau d&#8217;un point d&#8217;injection, vous devrez créer votre propre qualifier. Pour cela, il suffit de créer votre propre annotation avec @Qualifier et d&#8217;annoter votre bean avec celle-ci.</p><pre class="brush: java; gutter: true; title: ; notranslate">
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD, PARAMETER})
public @interface JdbcDao {
}
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD, PARAMETER})
public @interface JPADao {
}
@JdbcDao
public class JdbcCustomerDao implements CustomerDao {...}
@JPADao
public class JPACustomerDao implements CustomerDao {...}
//Exemple d'injection avec @Qualifier:
@Inject @JdbcDao
private CustomerDao customerDao;
</pre><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-IdentifierunbeanviasonnomELavec@Named"></a>Identifier un bean via son nom EL avec @Named</h4><p>Une autre manière d&#8217;identifier un bean est d&#8217;indiquer son nom EL (Expression Language) via l&#8217;annotation @Named. Ce bean sera ainsi accessible depuis vos pages JSF en utilisant une EL. Il est possible de spécifier un nom ou par défaut c&#8217;est le nom de classe dont la première lettre passe en minuscule qui est considéré.</p><pre class="brush: java; gutter: true; title: ; notranslate">
@Named
public class Calculator {...}
//Equivalent à :
@Named(&quot;calculator&quot;)
public class Calculator {...}
//Page JSF:
&lt;h:outputLabel value=&quot;#{calculator.someMethod}&quot; /&gt;
</pre><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-D%C3%A9finiruneimpl%C3%A9mentationalternativeavec@Alternative"></a>Définir une implémentation alternative avec @Alternative</h4><p>Une autre fonctionnalité intéressante proposée dans CDI est de définir une implémentation alternative à un bean. Cette alternative doit être déclarée dans le fichier beans.xml et permet de modifier l&#8217;implémentation d&#8217;un bean au déploiement. Elle surcharge donc le bean qui aurait dû être injecté initialement.</p><pre class="brush: java; gutter: true; title: ; notranslate">
//MockCustomerDao est une implémentation alternative aux implémentations Jdbc et JPA
@Alternative
@JdbcDao
@JPADao
public class MockCustomerDao implements CustomerDao {...}
//L'implémentation alternative MockCustomerDao sera injectée à la place de JPADao:
@Inject @JPADao
private CustomerDao customerDao;
//Déclaration de l'alternative dans le beans.xml:
&lt;alternatives&gt;
   &lt;class&gt;fr.xebia.cdi.MockCustomerDao&lt;/class&gt;
&lt;/alternatives&gt;
</pre><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-Personnaliserler%C3%B4led%27unbeanavec@Stereotype"></a>Personnaliser le rôle d&#8217;un bean avec @Stereotype</h4><p>Les stéréotypes permettent de regrouper au sein d&#8217;une même annotation des modèles et des rôles communs que l&#8217;on veut implanter sur des beans. CDI fournit quelques stéréotypes de base. Ci-dessous, le stéréotype @Model représente la partie Model du pattern MVC et peut être utilisée pour les beans JSF. On voit par exemple que les beans utilisant ce stéréotype auront tous en commun un nom EL, et un scope request.</p><pre class="brush: java; gutter: true; title: ; notranslate">
@Named
@RequestScoped
@Stereotype
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface Model {}
</pre><p>On constate la richesse qu&#8217;offre CDI en plus de la simple injection de dépendances. Les qualifiers et stéréotypes permettent notamment de donner du sens métier et fonctionnel aux beans.</p><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-CDIoffredenombreuxpatternscl%C3%A9enmain"></a>CDI offre de nombreux patterns clé en main</h3><p>Outre l&#8217;injection de dépendance, CDI va plus loin en implémentant un certain nombre de patterns de programmation. Là encore, c&#8217;est à l&#8217;aide d&#8217;annotations que la magie opère.</p><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-LepatternSingletonavec@Singleton"></a>Le pattern Singleton avec @Singleton</h4><p>Tout d&#8217;abord le mythique pattern Singleton, où il suffit d&#8217;annoter un bean avec @Singleton. Ainsi, une seule instance du bean est partagée et les accès concurrents sont gérés. Il faut savoir que cette annotation est en fait un pseudo-scope, mais contrairement aux autres scopes, le conteneur injecte une référence directe au bean, et non un proxy.</p><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-LepatternFactoryavec@Produces"></a>Le pattern Factory avec @Produces</h4><p>Cette technique appelée <em>producer method</em> est une méthode permettant de créer des objets injectables. On peut produire des types primitifs, des beans ou encore des ressources telles qu&#8217;un entityManager, une connection JMS, etc. Dans l&#8217;exemple ci-dessous, notre <em>producer method</em> produit un logger. Pour créer ce logger, il est nécessaire d&#8217;indiquer le nom de la classe qui sera loggué. Pour cela, il suffit de passer en paramètre de notre méthode un objet InjectionPoint qui sera injecté par CDI. Cet objet permet de récupérer des informations de contexte, comme la classe où est injecté l&#8217;objet Logger.</p><pre class="brush: java; gutter: true; title: ; notranslate">
class LogFactory {
   @Produces Logger createLogger(InjectionPoint injectionPoint) {
       return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
   }
}
//Injection du logger:
@Inject
private Logger logger;
</pre><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-LesinterceptorsavecCDI"></a>Les interceptors avec CDI</h4><p>CDI enrichit l&#8217;API Interceptors 1.1 présente dans Java EE 6. Initialement, Interceptors permet de faire de l&#8217;interception à la &laquo;&nbsp;AOP&nbsp;&raquo; sur les managed beans ou les EJB beans. L&#8217;intercepteur déclenche alors un traitement avant et après l&#8217;invocation d&#8217;une méthode. L&#8217;annotation @AroundInvoke permet d’exécuter du code au moment de l&#8217;interception et @Interceptors indique les méthodes à intercepter. Ainsi, CDI introduit une nouvelle annotation @InterceptorBinding, qui simplifie et offre un couplage lâche avec la classe de l&#8217;interceptor.</p><pre class="brush: java; gutter: true; title: ; notranslate">
@InterceptorBinding
@Inherited
@Target( { TYPE, METHOD })
@Retention(RUNTIME)
public @interface Transactional {}
//Intercepteur qui déclare l'annotation précédente, ainsi que @Interceptor
public @Transactional @Interceptor
class TransactionInterceptor { ... }
//On applique l'intercepteur sur le bean via l'annotation.
public @SessionScoped @Transactional
class ShoppingCart implements Serializable { ... }
</pre><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-LepatternDecoratoravec@Decorator"></a>Le pattern Decorator avec @Decorator</h4><p>Les décorateurs ressemblent aux intercepteurs. Ils interceptent aussi des appels de méthodes, mais ont en plus accès à la sémantique du bean intercepté. Un décorateur est une classe abstraite (ou non) qui implémente le type du bean qu&#8217;il décore et est annoté avec @Decorator.<br
/> Le bean du décorateur s&#8217;injecte l&#8217;objet qu&#8217;il décore via les annotations  @Inject @Delegate @Any. L&#8217;annotation @Delegate indique que ce point  d&#8217;injection correspond au bean que l&#8217;on veut décorer. L&#8217;annotation  @Any permet d&#8217;intercepter tous les beans implémentant l&#8217;interface du type décoré.  Enfin, le décorateur implémente au choix les méthodes qu&#8217;il veut intercepter.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public interface Customer {
   String getName();
   ...
}
@Decorator
public abstract class CustomerDecorator
implements Customer {
   @Inject @Delegate @Any
   Customer customer;
   public String getName() {
      return &quot;decorate&quot;+ customer.getName();
   }
}
</pre><h4><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-LepatternObserver%28ouEvent%29avec@Observable"></a>Le pattern Observer (ou Event) avec @Observable</h4><p>CDI offre la possibilité aux beans de produire et de consommer des  events. Ce mécanisme permet notamment aux beans d&#8217;interagir entre eux via un couplage lâche et asynchrone sans utiliser JMS. Par ailleurs, ce  pattern permet de synchroniser et capter les changements d&#8217;état de  beans stateful. <br
/> Un event est matérialisé par un objet java (event object ou payload) et est marqué d&#8217;un ou plusieurs qualifiers (event qualifiers). Les qualifiers permettent de distinguer les events que l&#8217;on veut produire ou observer pour un type de bean donné. Techniquement, une méthode observatrice (observer method) aura le rôle de consommer  l&#8217;event object, correspondant à un ensemble de qualifiers donnés.</p><pre class="brush: java; gutter: true; title: ; notranslate">
//Permet de qualifier l'event
@Qualifier
@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface Updated {}
//Observer method pour tout type de Customer
public void onAnyCustomerEvent(@Observes Customer customer) { ... }
//Observer method pour les Customer qualifié par @Updated
public void afterCustomerUpdate(@Observes @Updated Customer customer) { ... }
//Producteur d'un event de type Customer qualifié par @Updated
@Inject @Updated Event&lt;Customer&gt; customerEvent;
public void someMethod(Event&lt;Customer&gt; customerEvent) {
   ...
   customerEvent.fire(customer);
}
</pre><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-LesextensionsCDI%2Cl%E2%80%99avenirdeJavaEE%3F"></a>Les extensions CDI, l’avenir de Java EE ?</h3><p>De base, les patterns et les fonctionnalités qu&#8217;offre CDI sont riches et nombreux. Mais, cela va encore plus loin. Le cœur de CDI a été conçu tel  un bus d’événements. Au moment du chargement du conteneur, celui-ci  envoie ses informations de contexte (détection d&#8217;annotations, de beans,  etc.) dans un bus. Il est alors possible de capter ces événements via  une SPI, contenu dans le package <a
href="http://docs.jboss.org/cdi/api/1.0/javax/enterprise/inject/spi/Extension.html" rel="nofollow">javax.enterprise.inject.spi</a>. En  implémentant cette SPI, il est ainsi possible de capter ces informations  et d&#8217;effectuer des traitements propres. Cette architecture rend CDI  modulaire et permet le développement d&#8217;extensions CDI portables.</p><p>Les développeurs de <a
href="http://seamframework.org/Seam3" rel="nofollow">Seam 3</a> ont bien compris l’intérêt des extensions CDI et ont conçu leur framework comme un ensemble d&#8217;extensions à CDI. Si vous avez besoin d&#8217;une certaine fonctionnalité, il suffit d&#8217;ajouter le module concerné. Cela ouvre la voix à l&#8217;intégration d&#8217;api third-party et permet d&#8217;enrichir considérablement la plateforme Java EE,  de la même manière que Spring le fait avec ses modules et ses templates.</p><p>Par ailleurs, un projet très ambitieux encore en incubation chez Apache, nommé <a
href="http://wiki.apache.org/incubator/DeltaSpikeProposal" rel="nofollow">DeltaSpike </a>a pour but de standardiser un ensemble d&#8217;extensions CDI,  développé et maintenu par la communauté Java. Et éventuellement, ces  extensions pourront être intégrées aux spécifications Java SE et EE. Les premiers contributeurs ont offert les &laquo;&nbsp;code base&nbsp;&raquo; de JBoss Seam3, Apache MyFaces CODI et CDISource. A terme, JBoss Seam 3 et consorts disparaitront pour laisser DeltaSpike la seule source d&#8217;extensions CDI portables et standards. L&#8217;avenir de Java EE passera donc aussi par le développement des extensions CDI.</p><h3><a
name="JavaEE6%2Cuneplateformesimpleetl%C3%A9g%C3%A8re.Springn%E2%80%99aqu%E2%80%99%C3%A0biensetenir%21-Conclusion"></a>Conclusion</h3><p>Cet article avait pour vocation de démontrer que la plateforme Java EE 6 est aboutie et apporte des nouveautés majeures. Il n&#8217;a pas abordé toutes les spécifications, telles que JPA 2, Bean Validation 1.1 ou encore JSF 2.0.  Comme nous avons pu le voir, cette plateforme a rattrapé son retard par rapport au géant Spring. L&#8217;arrivée du Web Profile et des EJB Lite ouvre la voie à des conteneurs légers et testables.</p><p>Néanmoins, il y a quelques petites déceptions: par exemple, la gestion de la configuration et celle des profiles sont inexistantes contrairement à spring. On peut aussi regretter que le profile web  n&#8217;inclue pas JMS, JAX-RS et JAX-WS. Enfin, <b>la</b> réussite de Java EE 6 est sans doute l&#8217;API CDI, qui apporte enfin l&#8217;injection de dépendances, de la modularité, et même plus avec ses extensions. Le projet Delta Spike qui consiste à devenir le catalogue de référence des extensions CDI est à surveiller de près.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/02/01/java-ee-6-une-plateforme-simple-et-legere-spring-na-qua-bien-se-tenir/feed/</wfw:commentRss> <slash:comments>23</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2012/01/31/revue-de-presse-xebia-2012-05/</link> <comments>http://blog.xebia.fr/2012/01/31/revue-de-presse-xebia-2012-05/#comments</comments> <pubDate>Tue, 31 Jan 2012 15:55:59 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[JavaFX]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[jQ Mobi]]></category> <category><![CDATA[JQuery Mobile]]></category> <category><![CDATA[Twitter]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10488</guid> <description><![CDATA[La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia. Actualité éditeurs / SSII jq.Mobi, jQuery Mobile réécrit et optimisé (Par Jean Helou) RIA JavaFX disponible sur Linux (Par Diego Lemos) Le coin de la technique Twitter Bootstrap 2.0 (Par Aurélien Maury) Actualité éditeurs / SSII jq.Mobi, jQuery Mobile réécrit et optimisé jQ.Mobi est [...]]]></description> <content:encoded><![CDATA[<p><img
src="http://blog.xebia.fr/wp-content/uploads/2007/06/revuedepresse.png" alt="Revue de Presse Xebia" style="margin: 1em 1em 1em 1em; float: right;" /><br
/> <em>La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia.</em></p><p><strong>Actualité  éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/31/revue-de-presse-xebia-2012-05#RevuedePresseXebia-jq.Mobi%2CjQueryMobiler%C3%A9%C3%A9critetoptimis%C3%A9">jq.Mobi, jQuery Mobile réécrit et optimisé</a> <em>(Par <a
href="https://twitter.com/#!/jeanhelou" rel="nofollow">Jean Helou</a>)</em></li></ul><p><strong>RIA</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/31/revue-de-presse-xebia-2012-05#RevuedePresseXebia-JavaFXdisponiblesurLinux">JavaFX disponible sur Linux</a> <em>(Par <a
href="https://twitter.com/#!/dlresende" rel="nofollow">Diego Lemos</a>)</em></li></ul><p><strong>Le coin de la technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/31/revue-de-presse-xebia-2012-05#RevuedePresseXebia-TwitterBootstrap2.0">Twitter Bootstrap 2.0</a> <em>(Par <a
href="http://blog.xebia.fr/author/amaury/" rel="nofollow">Aurélien Maury</a>)</em></li></ul><h3><a
name="RevuedePresseXebia-Actualit%C3%A9%C3%A9diteurs%2FSSII"></a>Actualité  éditeurs / SSII</h3><h4><a
name="RevuedePresseXebia-jq.Mobi%2CjQueryMobiler%C3%A9%C3%A9critetoptimis%C3%A9"></a>jq.Mobi, jQuery Mobile réécrit et optimisé</h4><p><a
href="http://www.jqmobi.com/" rel="nofollow">jQ.Mobi</a> est un concurrent de <a
href="http://jquerymobile.com/download/" rel="nofollow">jQuery Mobile</a>, développé spécifiquement pour les plateformes mobiles et optimisé pour HTML5. Ces axes d&#8217;optimisation permettent à la version minifiée de jQ.Mobi d&#8217;être environ 10 fois plus petite que celle de jQuery Mobile, son téléchargement est donc bien plus rapide, accélérant d&#8217;autant le chargement des pages. L&#8217;optimisation pour le html5 simplifie le code en plus de l&#8217;alléger et permet de gagner également en vitesse d&#8217;exécution (facteur 3 sur Android, 2.2 sur iOS d&#8217;après <a
href="http://jsperf.com/jqm3/4" rel="nofollow">Jsperf</a>).</p><p>La syntaxe de jQ.Mobi est identique à celle de JQuery, l&#8217;api des plugins est également compatible mais jQ.Mobi ne contient qu&#8217;un sous-ensemble des fonctionnalités de JQuery, celles utilisées par appMobi, société qui a développé le framework avant de le mettre à disposition en open source.</p><p>jQ.Mobi est séparé en trois composants:</p><ul><li>jQ (le coeur)</li><li>jQ.UI (l&#8217;interface)</li><li>jQ.plugin (plugins pour les navigateurs (WebKit)</li></ul><p><a
href="http://www.appmobi.com/" rel="nofollow">appMobi</a> explique le développement de son framework par la volonté de véritablement le spécialiser pour les plateformes mobiles quitte à être incomaptible avec les navigateurs &laquo;&nbsp;desktop&nbsp;&raquo;, l&#8217;objectif étant d&#8217;améliorer autant que possible l&#8217;expérience utilisateur sur mobile.<br
/> Le reponsable de JQuery mobile, Todd Parker a reconnu certains des problèmes et l&#8217;équipe du framework semble se réorienter pour les prendre en compte.</p><h3><a
name="RevuedePresseXebia-RIA"></a>RIA</h3><h4><a
name="RevuedePresseXebia-JavaFXdisponiblesurLinux"></a>JavaFX disponible sur Linux</h4><p>Cette semaine, la communauté JavaFX a reçu une nouvelle depuis longtemps attendue. Finalement, Oracle a annoncé sur le <a
href="http://blogs.oracle.com/javafx/entry/javafx_2_0_is_cross" rel="nofollow">blog JavaFX</a> une version Linux (32-bits!) du SDK JavaFX 2.1. La toute  nouvelle version a été testée par Oracle sur Ubuntu 10.04 avec un JDK 7u2. Néanmoins, Oracle fait comprendre que le JDK JavaFX devrait fonctionner sans problème sur d&#8217;autres distributions Linux.</p><p>Pour  rappel, JavaFX est une plateforme de développement pour la création  d&#8217;applications internet riches (RIA). Avec JavaFX, il est possible de  développer des applications desktop, web et mobile. JavaFX est aussi le  nom du langage de script utilisé pour le développement sur la plateforme du même nom. Le code est compilé en bytecode Java et peut donc être  exécuté sur une JVM.</p><h3><a
name="RevuedePresseXebia-Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="RevuedePresseXebia-TwitterBootstrap2.0"></a>Twitter Bootstrap 2.0</h4><p>Pour ceux qui ne connaissent pas encore cette librairie, il s&#8217;agit d&#8217;un framework CSS/JS <a
href="https://github.com/twitter/bootstrap" rel="nofollow">ouvert sur GitHub</a> par Twitter à la communauté OpenSource (sous licence Apache 2.0). Il intègre notamment une grille de placement et des styles pour un grand nombre d&#8217;éléments de formulaires, de messages aux utilisateurs, d&#8217;onglets de mise en page, de menus déroulants, etc. La cuvée 2.0 devrait sortir officiellement dans la semaine (sortie annoncée pour le&#8230; aujourd&#8217;hui si tout va bien). En avant première la documentation est déjà en ligne sur <a
href="http://markdotto.com/bs2/docs/index.html" rel="nofollow">le blog d&#8217;un des développeurs</a>. Jetez y un oeil, ça vaut le détour. Au menu des nouveautés :</p><ul><li>Amélioration du support cross-browser, annoncé &laquo;&nbsp;cross-everything&nbsp;&raquo;</li><li>Plugins JQuery spécifiquement adaptés</li><li>Prêt pour le <a
href="http://www.designspartan.com/tutoriels/responsive-design-definition-fonctionnement-ressources-et-tutoriels/" rel="nofollow">Responsive webdesign</a></li><li>Plus d&#8217;exemples, une meilleure documentation</li><li>Beaucoup plus de composants, notamment des barres de progression et des menus de navigations supplémentaires</li></ul><p>C&#8217;est une expérience à vivre. Je vous le conseille fortement pour votre prochain prototype. Si vous voulez avoir une idée de ce que certains ont réalisé avec la version 1.4, visitez le <a
href="http://builtwithbootstrap.com/" rel="nofollow">Tumblr non officiel BuiltWithBootstrap</a>.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/31/revue-de-presse-xebia-2012-05/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Atelier performance avec Kirk Pepperdine</title><link>http://blog.xebia.fr/2012/01/26/atelier-performance-avec-kirk-pipperdine/</link> <comments>http://blog.xebia.fr/2012/01/26/atelier-performance-avec-kirk-pipperdine/#comments</comments> <pubDate>Thu, 26 Jan 2012 04:11:09 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[Tech Events]]></category> <category><![CDATA[java]]></category> <category><![CDATA[Performances]]></category> <category><![CDATA[vidéo]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10423</guid> <description><![CDATA[Avec cette vidéo vous allez découvrir comment Kirk a procédé lors de cet atelier pour identifier les points d&#8217;amélioration d&#8217;un système et la manière de les résoudre. Tout cela sans préparation initiale ni code source : du live optimizing ! Écoutez également Kirk interviewé par Cyrille Le Clerc la veille de cet atelier. Tous les [...]]]></description> <content:encoded><![CDATA[<p>Avec cette vidéo vous allez découvrir comment Kirk a procédé lors de <a
href="http://blog.xebia.fr/2011/11/07/atelier-performance-avec-kirk-pepperdine" rel="nofollow">cet atelier</a> pour identifier les points d&#8217;amélioration d&#8217;un système et la manière de les résoudre. Tout cela sans préparation initiale ni code source : du <em>live optimizing</em> !<br
/> Écoutez également <a
href="http://blog.xebia.fr/2012/01/12/interview-de-kirk-pepperdine-sur-les-performances-en-java-par-cyrille-le-clerc" rel="nofollow">Kirk interviewé par Cyrille Le Clerc</a> la veille de cet atelier.</p><div
align="center"> <iframe
src="http://player.vimeo.com/video/35387464?title=0&amp;byline=0&amp;portrait=0&amp;color=800079" width="720" height="405" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></div><hr/> <strong>Tous les podcasts Xebia France :</strong></p><ul><li><a
href="itpc://blog.xebia.fr/feed/podcast/" title="Subscribe to the Podcast Feed with iTunes"><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/itunes.png" class="podpress_feed_buttons" alt="Subscribe with iTunes"></a></li><li><a
href="http://blog.xebia.fr/feed/podcast/" title="Les podcasts de Xebia France vous permettent de suivre l'actualité autour de Java, de l'agilité, des technologies Web et bien d'autres. Xebia France est une entreprise spécialisée dans les technologies Java et JEE en environnement agile."><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/feed_button-rss-podcast.png" class="podpress_feed_buttons" alt="Xebia France Podcast Feed"></a></li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/26/atelier-performance-avec-kirk-pipperdine/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <enclosure
url="http://xebia-video.s3-website-eu-west-1.amazonaws.com/2012-01-pepperdine-performance.mov" length="2147483647" type="video/quicktime" /> <itunes:duration>0:55:14</itunes:duration> <itunes:subtitle>Avec cette vidéo vous allez découvrir comment Kirk a procédé lors de cet atelier pour identifier les points d&#8217;amélioration d&#8217;un système et la manière de les résoudre. Tout cela sans préparation initiale ni code source : du live optimizin[...]</itunes:subtitle> <itunes:summary>Avec cette vidéo vous allez découvrir comment Kirk a procédé lors de cet atelier pour identifier les points d&#8217;amélioration d&#8217;un système et la manière de les résoudre. Tout cela sans préparation initiale ni code source : du live optimizing !
Écoutez également Kirk interviewé par Cyrille Le Clerc la veille de cet atelier.
Tous les podcasts Xebia France : </itunes:summary> <itunes:keywords>Performance</itunes:keywords> <itunes:author>Xebia France</itunes:author> <itunes:explicit>no</itunes:explicit> <itunes:block>no</itunes:block> </item> <item><title>Xebia accueille la 19ème soirée du Paris Scala User Group</title><link>http://blog.xebia.fr/2012/01/25/xebia-accueille-la-19eme-soiree-du-paris-scala-user-group/</link> <comments>http://blog.xebia.fr/2012/01/25/xebia-accueille-la-19eme-soiree-du-paris-scala-user-group/#comments</comments> <pubDate>Wed, 25 Jan 2012 05:38:52 +0000</pubDate> <dc:creator>David Galichet</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[akka]]></category> <category><![CDATA[Gatling]]></category> <category><![CDATA[Netty]]></category> <category><![CDATA[Paris Scala User Group]]></category> <category><![CDATA[scala]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10405</guid> <description><![CDATA[La prochaine session du Paris Scala User Group aura lieu jeudi 26 Janvier à 19h30 dans les locaux de Xebia. À cette occasion, Stéphane Landelle nous présentera Gatling qui est un outil de stress test écrit en Scala et reposant sur les frameworks akka et Netty. En seconde partie, il nous donnera un retour d&#8217;expérience sur l&#8217;utilisation de Scala [...]]]></description> <content:encoded><![CDATA[<p><span
style="float: right"><img
src="http://blog.xebia.fr/wp-content/uploads/2012/01/scala-logo.png" style="border: 0px solid black; margin: 1em;" /></span></p><p>La prochaine session du <a
href="http://groups.google.com/group/paris-scala-user-group" rel="nofollow">Paris Scala User Group</a> aura lieu <b>jeudi 26 Janvier à 19h30</b> dans les locaux de <b>Xebia</b>.</p><p>À cette occasion, <a
href="https://github.com/slandelle" rel="nofollow">Stéphane Landelle</a> nous présentera <a
href="http://gatling-tool.org/" rel="nofollow">Gatling</a> qui est un outil de stress test écrit en <em>Scala</em> et reposant sur les frameworks <a
href="http://akka.io/" rel="nofollow">akka</a> et <a
href="http://www.jboss.org/netty" rel="nofollow">Netty</a>. En seconde partie, il nous donnera un retour d&#8217;expérience sur l&#8217;utilisation de Scala pour développer l&#8217;outil.</p><p>Il reste encore des places. Si vous souhaitez y assister, pensez à vous <a
href="http://www.doodle.com/2g7fazb4e6rem7n7" rel="nofollow">inscrire</a> pour la logistique.</p><p>Notez bien l&#8217;adresse :<br
/> <b>Xebia</b><br
/> <b>156 boulevard Haussmann à Paris</b><br
/> <b>Immeuble A &#8211; 7e étage</b></p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/25/xebia-accueille-la-19eme-soiree-du-paris-scala-user-group/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2012/01/24/revue-de-presse-xebia-2012-04/</link> <comments>http://blog.xebia.fr/2012/01/24/revue-de-presse-xebia-2012-04/#comments</comments> <pubDate>Tue, 24 Jan 2012 08:30:17 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[AWS]]></category> <category><![CDATA[CommonCrawl]]></category> <category><![CDATA[Dynamo]]></category> <category><![CDATA[DynamoDB]]></category> <category><![CDATA[SimpleDB]]></category> <category><![CDATA[Visuwall]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10387</guid> <description><![CDATA[La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia. Actualité éditeurs / SSII Amazon dévoile DynamoDB (Par Alexandre Dutra) Sortie de Visuwall 0.3 (Par Julien Smadja et Arnaud Lemaire) Evénements de notre communauté en France et à l&#8217;étranger Common Crawl Corpus : le web disponible sur les disques d&#8217;Amazon Web Service (Par Bertrand [...]]]></description> <content:encoded><![CDATA[<p><img
src="http://blog.xebia.fr/wp-content/uploads/2007/06/revuedepresse.png" alt="Revue de Presse Xebia" style="margin: 1em 1em 1em 1em; float: right;" /><br
/> <em>La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia.</em></p><p><strong>Actualité  éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/24/revue-de-presse-xebia-2012-04#Revuedepresse-Amazond%C3%A9voileDynamoDB">Amazon dévoile DynamoDB</a> <em>(Par <a
href="https://twitter.com/#!/alexdut">Alexandre Dutra</a>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/24/revue-de-presse-xebia-2012-04#Revuedepresse-SortiedeVisuwall0.3">Sortie de Visuwall 0.3</a> <em>(Par <a
href="http://blog.xebia.fr/author/jsmadja/">Julien Smadja</a> et <a
href="http://blog.xebia.fr/author/alemaire/">Arnaud Lemaire</a>)</em></li></ul><p><strong>Evénements de notre communauté en France et à l&#8217;étranger</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/24/revue-de-presse-xebia-2012-04#Revuedepresse-CommonCrawlCorpus%3Alewebdisponiblesurlesdisquesd%27AmazonWebService">Common Crawl Corpus : le web disponible sur les disques d&#8217;Amazon Web Service</a> <em>(Par <a
href="http://blog.xebia.fr/author/bdechoux/">Bertrand Dechoux</a>)</em></li></ul><h3><a
name="Revuedepresse-Actualit%C3%A9%C3%A9diteurs%2FSSII"></a>Actualité  éditeurs / SSII</h3><h4><a
name="Revuedepresse-Amazond%C3%A9voileDynamoDB"></a>Amazon dévoile DynamoDB</h4><p>Il était difficile, cette semaine, de passer à côté de la nouvelle: après les <a
href="http://pandodaily.com/2012/01/17/good-news-for-ec2-customers-amazon-may-launch-new-cloud-search-tomorrow/" rel="nofollow">rumeurs les plus folles</a> et un teasing maîtrisé, Amazon mit fin au suspense le 18 janvier dernier en dévoilant un nouveau service baptisé <a
href="http://aws.amazon.com/fr/dynamodb//177-7357257-5640903" rel="nofollow">Amazon DynamoDB</a>.</p><p>Bon nombre de nos confrères ont relayé l&#8217;information: <a
href="http://techcrunch.com/2012/01/18/amazon-database-dynamodb/" rel="nofollow">TechCrunch</a>, <a
href="http://www.readwriteweb.com/cloud/2012/01/amazon-enters-the-nosql-market.php" rel="nofollow">ReadWriteCloud</a> ou encore <a
href="http://www.informationweek.com/news/software/info_management/232500104" rel="nofollow">InformationWeek</a> y sont allés de leur plume, mais c&#8217;est <a
href="http://www.allthingsdistributed.com/2012/01/amazon-dynamodb.html" rel="nofollow">dans son blog</a> que Werner Vogels, CTO d&#8217;Amazon, revient longuement sur les choix qui l&#8217;ont poussé à mettre au point DynamoDB.</p><p>Sans surprise, DynamoDB serait le fruit d&#8217;un double retour d&#8217;expérience: celui de Dynamo d&#8217;une part, la solution NoSQL <a
href="http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf" rel="nofollow">mise au point par Amazon</a> dès 2007 et qui est à l&#8217;origine d&#8217;Apache Cassandra, Voldemort, Riak et de bien d&#8217;autres solutions NoSQL orientées clé-valeur; et celui de <a
href="http://aws.amazon.com/fr/simpledb/" rel="nofollow">SimpleDB</a> d&#8217;autre part, une autre solution non-relationnelle également développée par Amazon depuis 2007.</p><p>Dynamo, on le sait, fut une des toutes premières solutions non-relationnelles à s&#8217;attaquer aux principes des systèmes massivement distribués, hautement scalables et fiables. De l&#8217;aveu de Vogels, ce fut une réussite technique incontestable, mais le succès auprès des développeurs n&#8217;a jamais atteint le niveau escompté, sans doute en raison de la complexité du système.</p><p>SimpleDB, en revanche, était plus limitée mais aussi plus flexible et plus facile d&#8217;administration, et a fini par l&#8217;emporter en popularité auprès des développeurs. Un brin rancunier, Vogels explique qu&#8217;en préférant SimpleDB à Dynamo &laquo;&nbsp;les développeurs on choisi la simplicité plutôt que la précision&nbsp;&raquo; en &laquo;&nbsp;votant avec leurs pieds&nbsp;&raquo; (sic). En somme &laquo;&nbsp;les développeurs voulaient un service&nbsp;&raquo;, non une infrastructure.</p><p>Amazon DynamoDB, selon Vogels, est un peu le meilleur des deux mondes: un service cloud bâti sur les principes solides dérivés de Dynamo (scalabilité incrémentale, haute performance prévisible), tout en gardant la facilité d&#8217;administration et le côté &laquo;&nbsp;clé-en-mains&nbsp;&raquo; qui ont fait le succès de SimpleDB.</p><p>Selon Vogels toujours, DynamoDB compte les avantages suivants sur ses prédécesseurs:</p><ul><li>Facilité d&#8217;administration: DynamoDB se charge de la complexité engendrée par les réplications et les partitionnements de données.</li><li>Scalabilité: DynamoDB est conçu pour allouer automatiquement les ressources nécessaires à l&#8217;application, et ce jusqu&#8217;à des centaines, voire des milliers de noeuds répartis sur plusieurs Availability Zones. DynamoDB corrige ici une erreur de design souvent reprochée à SimpleDB: l&#8217;allocation au préalable des <em>Domains</em>, espaces mémoire à la capacité finie.</li><li>Rapidité: DynamoDB fournit un très haut débit et une latence très basse grâce à l&#8217;usage de disques SSD (<em>Solid State Drives</em>).</li><li>Prévisibilité des performances: DynamoDB répond à cette problématique par la notion de &laquo;&nbsp;Débit provisionné&nbsp;&raquo; (<em>Provisioned Throughput</em>): le client peut désormais spécifier le débit requis par l&#8217;application, pour une table donnée; DynamoDB alloue les ressources nécessaires de manière transparente afin de garantir un niveau de performances stable.</li><li>Disponibilité: DynamoDB réplique ses données sur différents data centers afin de minimiser les risques de défaillance.</li><li>Flexibilité: s&#8217;inspirant ici davantage de SimpleDB, DynamoDB n&#8217;impose pas de contrainte de schéma pour le modèle de données (d&#8217;ailleurs plus riche qu&#8217;un simple modèle clé-valeur comme celui de Dynamo), bien qu&#8217;il soit possible d&#8217;y appliquer un certain nombre de contraintes d&#8217;intégrité.</li></ul><p>Enfin, le pricing a été complètement revu. Finies les obscures &laquo;&nbsp;heures machine&nbsp;&raquo; de SimpleDB, place à une grille tarifaire simple:</p><ul><li>Le stockage est proposé à $1 par gigaoctet et par mois.</li><li>La bande passante est facturée en fonction du débit provisionné:<ul><li>$0.01 par heure pour chaque 10 unités de capacité en écriture (<em>Write Capacity</em>);</li><li>$0.01 par heure pour chaque 50 unités de capacité en lecture (<em>Read Capacity</em>) fortement consistantes (les lectures potentiellement consistantes &#8211; <em>eventually consistent</em> &#8211; sont à moitié prix).</li></ul></li></ul><p>(Une unité de capacité en lecture ou écriture correspond, selon Vogel, respectivement à une capacité de lecture ou d&#8217;écriture par seconde pour des objets allant jusqu&#8217;à 1 kilo-octet en taille.)</p><p>Enfin, il faudrait noter que DynamoDB est intimement lié aux services Elastic MapReduce proposés par Amazon: il sera donc possible d&#8217;utiliser DynamoDB dans des opérations MapReduce, ce qui ouvre des perspectives intéressantes pour le traitement en quasi temps réel de grands volumes de données, directement sur la base de données de production, et donc en phase avec l&#8217;approche BigData.</p><h4><a
name="Revuedepresse-SortiedeVisuwall0.3"></a>Sortie de Visuwall 0.3</h4><p>La version 0.3 de Visuwall est sortie la semaine dernière. Pour rappel, cet outil avait déjà fait l&#8217;objet d&#8217;un article dans notre blog : <a
href="http://blog.xebia.fr/2011/12/02/visuwall-mixer-vos-outils-de-build-et-de-qualite/" rel="nofollow">Visuwall &#8211; Mixer vos outils de build et de qualité</a>. Vous pouvez dès à présent télécharger cette nouvelle version <a
href="http://repo1.maven.org/maven2/net/awired/visuwall/visuwall-web/0.3/visuwall-web-0.3.war" rel="nofollow">ici</a> sur le repository Maven.</p><p>Cette version apporte son lot de nouveautés :</p><ul><li>Support des projets autres que Maven.</li><li>Ajout d&#8217;un nouveau plugin pour les utilisateurs de Continuum.</li><li>Support de l&#8217;authentification des outils d&#8217;Intégration Continue et de Sonar.</li><li>Message d&#8217;information concernant la compatibilité du plugin Sonar (Visuwall est disponible exclusivement pour les versions de Sonar supérieures à 1.3).</li><li>Auto suppression de la base de données en cas de montée de version de Visuwall (la migration est prévue dans une version ultérieure).</li><li>Ajout d&#8217;un logo en fond lorsqu&#8217;aucun projet n&#8217;est encore affiché.</li><li>Les paramètres de configuration de l&#8217;interface graphique sont sauvegardés en cookie.</li><li>Lorsque le build d&#8217;un projet est en échec, les photos des développeurs apparaissent (Visuwall utilise Gravatar).</li><li>Une configuration à base de TeamCity &amp; Sonar est désormais possible.</li></ul><p>Le <a
href="https://raw.github.com/awired/visuwall/develop/CHANGELOG.txt" rel="nofollow">changelog</a> complet est disponible pour également suivre la correction des bugs.</p><p>La version 0.4 est dores et déjà en développement, toutes propositions d&#8217;évolution ou de rapport de bugs sont les bienvenues via un mail à cette adresse: <a
href="mailto:visuwall.ci@gmail.com" rel="nofollow">visuwall.ci@gmail.com</a> ou directement via l&#8217;<a
href="https://github.com/awired/visuwall/issues" rel="nofollow">issue tracker Github du projet</a>.</p><p>Vous pouvez également nous suivre sur Twitter : <a
href="https://twitter.com/visuwallci" rel="nofollow">@visuwallci</a> et nous soumettre des photos de <a
href="http://awired.github.com/visuwall/photos.html" rel="nofollow">Visuwall en action</a> comme ci-dessous :</p><p><img
src="http://awired.github.com/visuwall/photo_tn/6488348309_0a4b56bc4d_b.jpg" style="border: 1px solid black" /></p><h3><a
name="Revuedepresse-Ev%C3%A9nementsdenotrecommunaut%C3%A9enFranceet%C3%A0l%27%C3%A9tranger"></a>Evénements de notre communauté en France et à l&#8217;étranger</h3><h4><a
name="Revuedepresse-CommonCrawlCorpus%3Alewebdisponiblesurlesdisquesd%27AmazonWebService"></a>Common Crawl Corpus : le web disponible sur les disques d&#8217;Amazon Web Service</h4><p><a
href="http://hadoop.apache.org/" rel="nofollow">Hadoop</a> a été historiquement développé pour distribuer <a
href="http://nutch.apache.org/" rel="nofollow">Nutch</a>, un moteur de recherche open source. Hadoop vous permet désormais d&#8217;analyser facilement de gros volumes de données tel que l&#8217;ensemble des pages web. Obtenir celles-ci demande cependant plus d&#8217;effort. Il faut en effet mettre en place votre infrastructure pour crawler les sites qui vous intéressent et ceci n&#8217;est pas trivial. La fondation <a
href="http://www.commoncrawl.org/" rel="nofollow">Common Crawl</a> s&#8217;est donnée pour but de construire et maintenir un crawl de l&#8217;ensemble du web afin de créer une nouvelle vague d&#8217;innovation, d&#8217;éducation et de recherche. En effet, le web est une mine d&#8217;informations mais pour l&#8217;instant son exploitation se fait par un cercle restreint d&#8217;acteurs : Google, Bing, Yahoo&#8230;</p><p>Depuis le 20 janvier, le <a
href="http://aws.amazon.com/datasets/4174056542375970" rel="nofollow">corpus Common Crawl</a> est disponible au sein d&#8217;<a
href="http://aws.amazon.com/" rel="nofollow">Amazon Web Services</a>. Certains pourront s&#8217;étonner qu&#8217;il ne s&#8217;agisse pas d&#8217;un simple lien téléchargeable, mais la solution se veut pragmatique: en effet la taille du corpus (60 téraoctets) impose de stocker ces informations à proximité de leur lieu de traitement. Amazon, en tant que leader dans les solutions IaaS (EC2/MapReduce), est alors un choix qui se justifie. Le corpus contient 5 milliards de pages web. Ceci représente une fraction du web dont <a
href="http://www.worldwidewebsize.com/" rel="nofollow">la véritable taille reste à estimer</a>. Cet ensemble de données est donc amené à grossir davantage. Le corpus Common Crawl n&#8217;est pas un projet isolé et rejoint de <a
href="http://aws.amazon.com/datasets/" rel="nofollow">nombreux datasets hébergés également par Amazon</a> traitant de sujets variés allant des <a
href="http://aws.amazon.com/datasets/4383" rel="nofollow">variations du génome humain</a> au <a
href="http://aws.amazon.com/datasets/5621954952932508" rel="nofollow">graphe social de l&#8217;univers Marvel</a>.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/24/revue-de-presse-xebia-2012-04/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc &#8211; Épisode 4</title><link>http://blog.xebia.fr/2012/01/23/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-le-clerc-episode-4/</link> <comments>http://blog.xebia.fr/2012/01/23/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-le-clerc-episode-4/#comments</comments> <pubDate>Mon, 23 Jan 2012 07:20:11 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Cloud / NoSQL]]></category> <category><![CDATA[Tech Events]]></category> <category><![CDATA[cloud]]></category> <category><![CDATA[CloudBees]]></category> <category><![CDATA[Sacha Labourey]]></category> <category><![CDATA[vidéo]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10378</guid> <description><![CDATA[Voici le quatrième et dernier épisode de la série de questions/réponses échangées lors de la soirée Cloud organisée par Cyrille Le Clerc avec Sacha Labourey. Tous les podcasts Xebia France : Les vidéos de la soirées : Vidéo de la présentation de Sacha Labourey sur le Cloud Questions-Réponses sur le Cloud avec Sacha Labourey et [...]]]></description> <content:encoded><![CDATA[<p>Voici le quatrième et dernier épisode de la série de questions/réponses échangées lors de <a
href="http://blog.xebia.fr/2011/11/10/soiree-cloud-avec-sacha-labourey-ceo-and-founder-cloudbees" rel="nofollow">la soirée Cloud</a> organisée par <a
href="http://blog.xebia.fr/author/cleclerc" rel="nofollow">Cyrille Le Clerc</a> avec Sacha Labourey.</p><div
align="center"> <iframe
src="http://player.vimeo.com/video/35303253?title=0&amp;byline=0&amp;portrait=0&amp;color=800079" width="640" height="360" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></div><hr/> <strong>Tous les podcasts Xebia France :</strong></p><ul><li><a
href="itpc://blog.xebia.fr/feed/podcast/" title="Subscribe to the Podcast Feed with iTunes"><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/itunes.png" class="podpress_feed_buttons" alt="Subscribe with iTunes"></a></li><li><a
href="http://blog.xebia.fr/feed/podcast/" title="Les podcasts de Xebia France vous permettent de suivre l'actualité autour de Java, de l'agilité, des technologies Web et bien d'autres. Xebia France est une entreprise spécialisée dans les technologies Java et JEE en environnement agile."><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/feed_button-rss-podcast.png" class="podpress_feed_buttons" alt="Xebia France Podcast Feed"></a></li></ul><p><strong>Les vidéos de la soirées :</strong></p><ul><li><a
href="http://blog.xebia.fr/2011/12/08/video-de-la-presentation-de-sacha-labourey-sur-le-cloud/">Vidéo de la présentation de Sacha Labourey sur le Cloud</li><li><a
href="http://blog.xebia.fr/2011/12/16/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-1/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 1</li><li><a
href="http://blog.xebia.fr/2011/12/22/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-2/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 2</li><li><a
href="http://blog.xebia.fr/2012/01/05/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-3/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 3</li><li><a
href="http://blog.xebia.fr/2012/01/23/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-le-clerc-episode-4/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 4</li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/23/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-le-clerc-episode-4/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <enclosure
url="http://xebia-video.s3-website-eu-west-1.amazonaws.com/2012-01-qr-cloud-labourey-le-clerc-ep4.mp4" length="463841184" type="audio/mpeg" /> <itunes:duration>0:28:27</itunes:duration> <itunes:subtitle>Voici le quatrième et dernier épisode de la série de questions/réponses échangées lors de la soirée Cloud organisée par Cyrille Le Clerc avec Sacha Labourey.
Tous les podcasts Xebia France :
Les vidéos de la soirées :
Vidéo de la présen[...]</itunes:subtitle> <itunes:summary>Voici le quatrième et dernier épisode de la série de questions/réponses échangées lors de la soirée Cloud organisée par Cyrille Le Clerc avec Sacha Labourey.
Tous les podcasts Xebia France :
Les vidéos de la soirées :
Vidéo de la présentation de Sacha Labourey sur le Cloud
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 1
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 2
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 3
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 4 </itunes:summary> <itunes:author>Xebia France</itunes:author> <itunes:explicit>no</itunes:explicit> <itunes:block>no</itunes:block> </item> <item><title>Interview de Jean-Louis Rigau sur les coulisses de l&#8217;atelier &#171;&#160;Continuous Deployment et Java PaaS avec CloudBees&#160;&#187; par Cyrille Le Clerc</title><link>http://blog.xebia.fr/2012/01/19/interview-de-jean-louis-rigau-sur-les-coulisses-de-latelier-continuous-deployment-et-java-paas-avec-cloudbees-par-cyrille-le-clerc/</link> <comments>http://blog.xebia.fr/2012/01/19/interview-de-jean-louis-rigau-sur-les-coulisses-de-latelier-continuous-deployment-et-java-paas-avec-cloudbees-par-cyrille-le-clerc/#comments</comments> <pubDate>Thu, 19 Jan 2012 07:38:45 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Cloud / NoSQL]]></category> <category><![CDATA[Tech Events]]></category> <category><![CDATA[CloudBees]]></category> <category><![CDATA[Continuous Deployment]]></category> <category><![CDATA[PaaS]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10362</guid> <description><![CDATA[Cyrille Le Clerc interviewe Jean-Louis Rigau sur les coulisses des atelier Java PaaS et Continuous Deployment avec CloudBees. Au programme : Les objectifs. L&#8217;organisation. Le déroulement : Le programme. Les réactions des participants face à la plateforme CloudBees. La suite : Comment nous avons utilisé CloudBees sur le terrain. Les prochains ateliers Java PaaS que [...]]]></description> <content:encoded><![CDATA[<p><span
style="float: right"><img
src="http://blog.xebia.fr/wp-content/uploads/2012/01/rigau-leclerc.png" style="border: 0px solid black; margin: 1em;" /></span><br
/> <a
href="http://blog.xebia.fr/author/cleclerc/" rel="nofollow">Cyrille Le Clerc</a> interviewe <a
href="http://blog.xebia.fr/author/jlrigau/" rel="nofollow">Jean-Louis Rigau</a> sur les coulisses des <a
href="http://blog.xebia.fr/2011/10/28/atelier-java-paas-et-continuous-deployment-avec-cloudbees/" rel="nofollow">atelier Java PaaS et Continuous Deployment avec CloudBees</a>.</p><p>Au programme :</p><ul><li>Les objectifs.</li><li>L&#8217;organisation.</li><li>Le déroulement :<ul><li>Le programme.</li><li>Les réactions des participants face à la plateforme CloudBees.</li></ul></li><li>La suite :<ul><li>Comment nous avons utilisé CloudBees sur le terrain.</li><li>Les prochains ateliers Java PaaS que nous préparons chez Xebia.</li></ul></li></ul><p><span
style="float: right"><img
src="http://blog.xebia.fr/wp-content/uploads/2012/01/logo-cloudbees.png" style="border: 0px solid black; margin: 1em;" /></span></p><p>Bonne écoute !<br
/>&nbsp;<br
/>&nbsp;</p><p></p><div
id='continuous-depoloyment-java-paas-cloud-rigau-le-clerc'></div><p><script type="text/javascript">jwplayer('continuous-depoloyment-java-paas-cloud-rigau-le-clerc').setup({
    	flashplayer: '/videos/player.swf',
	    'id': 'playerID',
    	'width': '560',
	    'height': '24',
	    'file': '/videos/continuous-depoloyment-java-paas-cloud-rigau-le-clerc.mp3',
	    'controlbar': 'bottom'
	});</script></p><p>&nbsp;<br
/>&nbsp;</p><hr/> <strong>Tous les podcasts Xebia France :</strong></p><ul><li><a
href="itpc://blog.xebia.fr/feed/podcast/" title="Subscribe to the Podcast Feed with iTunes"><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/itunes.png" class="podpress_feed_buttons" alt="Subscribe with iTunes"></a></li><li><a
href="http://blog.xebia.fr/feed/podcast/" title="Les podcasts de Xebia France vous permettent de suivre l'actualité autour de Java, de l'agilité, des technologies Web et bien d'autres. Xebia France est une entreprise spécialisée dans les technologies Java et JEE en environnement agile."><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/feed_button-rss-podcast.png" class="podpress_feed_buttons" alt="Xebia France Podcast Feed"></a></li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/19/interview-de-jean-louis-rigau-sur-les-coulisses-de-latelier-continuous-deployment-et-java-paas-avec-cloudbees-par-cyrille-le-clerc/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <enclosure
url="http://blog.xebia.fr/videos/continuous-depoloyment-java-paas-cloud-rigau-le-clerc.mp3" length="30181169" type="audio/mpeg" /> <itunes:duration>0:31:26</itunes:duration> <itunes:subtitle> Cyrille Le Clerc interviewe Jean-Louis Rigau sur les coulisses des atelier Java PaaS et Continuous Deployment avec CloudBees.
Au programme :
Les objectifs.
L&#8217;organisation.
Le déroulement :
Le programme.
Les réactions des participants face à[...]</itunes:subtitle> <itunes:summary> Cyrille Le Clerc interviewe Jean-Louis Rigau sur les coulisses des atelier Java PaaS et Continuous Deployment avec CloudBees.
Au programme :
Les objectifs.
L&#8217;organisation.
Le déroulement :
Le programme.
Les réactions des participants face à la plateforme CloudBees.
La suite :
Comment nous avons utilisé CloudBees sur le terrain.
Les prochains ateliers Java PaaS que nous préparons chez Xebia.
Bonne écoute !&#160;&#160;
&#160;&#160;
Tous les podcasts Xebia France : </itunes:summary> <itunes:author>Xebia France</itunes:author> <itunes:explicit>no</itunes:explicit> <itunes:block>no</itunes:block> </item> <item><title>Xebia vous présente ses meilleurs vœux pour l’année 2012 &#8230;</title><link>http://blog.xebia.fr/2012/01/18/xebia-vous-presente-ses-meilleurs-voeux-pour-lannee-2012/</link> <comments>http://blog.xebia.fr/2012/01/18/xebia-vous-presente-ses-meilleurs-voeux-pour-lannee-2012/#comments</comments> <pubDate>Wed, 18 Jan 2012 16:20:05 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Xebia recrute !]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10351</guid> <description><![CDATA[&#8230; et se propose de vous aider à réaliser vos bonnes résolutions 2012 2011 &#59;&#45;&#41; Envoyer nous votre CV à recrutement@xebia.fr ou via le formulaire de contact.]]></description> <content:encoded><![CDATA[<p><strong>&#8230; et se propose de vous aider à réaliser vos bonnes résolutions <strike>2012</strike> 2011 &#59;&#45;&#41;</strong></p><p><span><img
src="http://blog.xebia.fr/wp-content/uploads/2012/01/resolutions-20112.jpg" /></span></p><p>Envoyer nous votre CV à <a
href="mailto:recrutement@xebia.fr">recrutement@xebia.fr</a> ou via le <a
href="http://blog.xebia.fr/rejoignez-nous/">formulaire de contact</a>.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/18/xebia-vous-presente-ses-meilleurs-voeux-pour-lannee-2012/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/</link> <comments>http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#comments</comments> <pubDate>Tue, 17 Jan 2012 05:39:54 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[BigData]]></category> <category><![CDATA[Firebug]]></category> <category><![CDATA[Firefox]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JUG]]></category> <category><![CDATA[Redis]]></category> <category><![CDATA[scala]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring Data]]></category> <category><![CDATA[Spring Integration]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10296</guid> <description><![CDATA[La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia. Actualité éditeurs / SSII Spring Integration 2.1 (Par Bertrand Dechoux) Spring Data Redis 1.0.0 (Par Bertrand Dechoux &#38; Mathieu Bigorne) &#171;&#160;Big Data&#160;&#187; par Nathan Marz et Sam Ritchie est disponible en MEAP (Par Bertrand Dechoux) Scalding, une API Scala pour Cascading par Twitter (Par [...]]]></description> <content:encoded><![CDATA[<p><img
src="http://blog.xebia.fr/wp-content/uploads/2007/06/revuedepresse.png" alt="Revue de Presse Xebia" style="margin: 1em 1em 1em 1em; float: right;" /><br
/> <em>La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia.</em></p><p><strong>Actualité  éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-SpringIntegration2.1">Spring Integration 2.1</a> <em>(Par <a
href="http://blog.xebia.fr/author/bdechoux/" rel="nofollow">Bertrand Dechoux</a>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-SpringDataRedis1.0.0">Spring Data Redis 1.0.0</a> <em>(Par <a
href="http://blog.xebia.fr/author/bdechoux/" rel="nofollow">Bertrand Dechoux</a> &amp; <a
href="https://twitter.com/#!/mbigorne" rel="nofollow">Mathieu Bigorne</a>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-%22BigData%22parNathanMarzetSamRitchieestdisponibleenMEAP">&laquo;&nbsp;Big Data&nbsp;&raquo; par Nathan Marz et Sam Ritchie est disponible en MEAP</a> <em>(Par <a
href="http://blog.xebia.fr/author/bdechoux/" rel="nofollow">Bertrand Dechoux</a>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-Scalding%2CuneAPIScalapourCascadingparTwitter">Scalding, une API Scala pour Cascading par Twitter</a> <em>(Par <a
href="http://blog.xebia.fr/author/bdechoux/" rel="nofollow">Bertrand Dechoux</a>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-Firefox10sortiraenversionESR">Firefox 10 sortira en version ESR</a> <em>(Par Benoit Lemoine)</em></li><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-Firebug1.9.0">Firebug 1.9.0</a> <em>(Par <a
href="http://blog.xebia.fr/author/bdechoux/" rel="nofollow">Bertrand Dechoux</a>)</em></li></ul><p><strong>Le coin de la technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-Seren%3ASerializationEnhancer">Seren : Serialization Enhancer</a> <em>(Par <a
href="https://twitter.com/#!/jeanhelou" rel="nofollow">Jean Helou</a>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-Apologiedeslambdasdeblockspourjavascript">Apologie des lambdas de blocks pour javascript</a> <em>(Par <a
href="https://twitter.com/#!/jeanhelou" rel="nofollow">Jean Helou</a>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-Verbosit%C3%A9deslangagesdeprogrammation">Verbosité des langages de programmation</a> <em>(Par <a
href="http://blog.xebia.fr/author/omichallat/" rel="nofollow">Olivier Michallat</a>)</em></li></ul><p><strong>Evénements de notre communauté en France et à l&#8217;étranger</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-L%27artisanat%2Cunm%C3%A9tierd%27avenir">L&#8217;artisanat, un métier d&#8217;avenir</a> <em>(Par <a
href="http://blog.xebia.fr/author/xbucchiotty/" rel="nofollow">Xavier Bucchiotty</a>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/#Revuedepresse-UnesemainerichepourlesUserGroups">Une semaine riche pour les User Groups</a></li></ul><h3><a
name="Revuedepresse-Actualit%C3%A9%C3%A9diteurs%2FSSII"></a>Actualité  éditeurs / SSII</h3><h4><a
name="Revuedepresse-SpringIntegration2.1"></a>Spring Integration 2.1</h4><p>Un an après la sortie en <a
href="http://blog.springsource.org/2010/11/23/spring-integration-2-0-ga-released" rel="nofollow">2.0</a>, <a
href="http://www.springsource.org/spring-integration" rel="nofollow">Spring Integration</a> est désormais disponible en version <a
href="http://blog.springsource.org/2012/01/09/spring-integration-2-1-is-now-ga" rel="nofollow">2.1</a>. On notera un <a
href="http://static.springsource.org/spring-integration/docs/2.1.x/reference/htmlsingle/#scripting" rel="nofollow">meilleur support des scripts</a> (Groovy, Ruby/JRuby, Python/Jython, et JavaScript) grâce à la <a
href="http://www.jcp.org/en/jsr/detail?id=223" rel="nofollow">JSR-223</a>. Il est ainsi possible de définir des &#8216;filters, splitters, routers, transformers&#8217; directement dans vos fichiers de configuration ou par l&#8217;intermédiaire de ressources, permettant de cette manière de recharger vos scripts à chaud. On notera également une meilleure intégration avec RabbitMQ/AMQP, GemFire, Redis et MongoDB.</p><h4><a
name="Revuedepresse-SpringDataRedis1.0.0"></a>Spring Data Redis 1.0.0</h4><p><a
href="http://www.springsource.org/spring-data/redis" rel="nofollow">Spring Data Redis</a> est sortie le mois dernier dans sa première version stable. Redis est une base de données clé-valeur avec d&#8217;excellentes performances qui peut stocker les types de données classiques (chaîne de caractères, liste, map &#8230;). Spring Data Redis fournit un niveau d&#8217;abstraction supplémentaire qui facilite l&#8217;interaction avec Redis. Cette version permet également d&#8217;utiliser Redis comme implémentation d&#8217;un cache via <a
href="http://static.springsource.org/spring-data/redis/docs/1.0.0.RELEASE/reference/redis.html#redis:support:cache-abstraction" rel="nofollow">l&#8217;abstraction de Spring</a>. Il s&#8217;agit de la première solution NoSql KeyValue supportée par <a
href="http://www.springsource.org/spring-data" rel="nofollow">Spring Data</a> mais <a
href="http://www.springsource.org/spring-data/riak" rel="nofollow">Riak</a> ne devrait pas se faire attendre longtemps.</p><h4><a
name="Revuedepresse-%22BigData%22parNathanMarzetSamRitchieestdisponibleenMEAP"></a>&laquo;&nbsp;Big Data&nbsp;&raquo; par Nathan Marz et Sam Ritchie est disponible en MEAP</h4><p>Big Data est un univers à part entière et rend non triviale la conception d&#8217;une architecture à la fois rapide (&laquo;&nbsp;temps réel&nbsp;&raquo;) et supportant de grandes volumétries. Deux ingénieurs de Twitter, Nathan Marz -créateur de <a
href="http://blog.xebia.fr/2011/11/07/storm-hadoop-map-reduce-en-temps-reel/" rel="nofollow">Storm</a>- et Sam Ritchie en dévoilent les principes dans <a
href="http://www.manning.com/marz/" rel="nofollow">&laquo;&nbsp;Big Data, Principles and best practices of scalable realtime data systems&nbsp;&raquo;</a>. Le livre n&#8217;est pour l&#8217;instant pas finalisé mais est disponible en MEAP (Manning Early Access Program). Le code bd50 vous permet de disposer d&#8217;une réduction de 50%.</p><h4><a
name="Revuedepresse-Scalding%2CuneAPIScalapourCascadingparTwitter"></a>Scalding, une API Scala pour Cascading par Twitter</h4><p><a
href="http://hadoop.apache.org/" rel="nofollow">Hadoop</a> est un acteur incontournable du BigData. Pour autant, peu vous vanteront la concision des traitements de données implémentés en se basant uniquement sur son API Java. De nombreuses solutions apparaissent pour combler ce manque. Certaines introduisent un nouveau langage comme <a
href="http://pig.apache.org/" rel="nofollow">Pig</a> et <a
href="http://hive.apache.org/" rel="nofollow">Hive</a>. D&#8217;autres proposent une API plus succincte, mais en gardant un langage complet, comme c&#8217;est le cas de <a
href="http://www.cascading.org/" rel="nofollow">Cascading</a>. Mecredi 11 Janvier, Twitter a rendu open source <a
href="https://dev.twitter.com/blog/scalding" rel="nofollow">Scalding</a>, son API Scala pour Cascading, simplifiant encore plus l&#8217;usage de MapReduce dans un environnement Scala. Pour les fans de Clojure, <a
href="https://github.com/nathanmarz/cascalog" rel="nofollow">Cascalog</a> est une solution similaire mais encore plus succincte. La version <a
href="http://groups.google.com/group/cascalog-user/browse_thread/thread/79e601af1ca9d3f1" rel="nofollow">1.8.5</a> est sortie le 4 Janvier.</p><h4><a
name="Revuedepresse-Firefox10sortiraenversionESR"></a>Firefox 10 sortira en version ESR</h4><p>La <a
href="http://blog.mozilla.com/blog/2012/01/10/delivering-a-mozilla-firefox-extended-support-release/" rel="nofollow">fondation Mozilla</a> a finalement décidé de maintenir 2 versions de Firefox en parallèle : la première suivra le cycle de livraison actuel (toutes les 6 semaines); alors que la seconde, plutôt à destination des entreprises, aura un cycle de livraison d&#8217;un an. Cette version ESR (Extended Support Release), dont Firefox 10 sera le premier représentant, sera maintenue avec les mises à jour de sécurité uniquement, le moteur de rendu et la gestion de plugin n&#8217;évoluant pas.</p><h4><a
name="Revuedepresse-Firebug1.9.0"></a>Firebug 1.9.0</h4><p>Pour les inconditionnels de Firefox, la <a
href="http://blog.getfirebug.com/2012/01/06/firebug-1-9-0" rel="nofollow">version 1.9.0 de Firebug</a> vient de sortir. On notera entre autres la possibilité de renvoyer les requêtes HTTP ou encore de visualiser les headers des réponses contenues dans le cache.</p><h3><a
name="Revuedepresse-Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="Revuedepresse-Seren%3ASerializationEnhancer"></a>Seren : Serialization Enhancer</h4><p><a
href="http://thecodersbreakfast.net/" rel="nofollow">Olivier Croisier</a> a annoncé cette semaine SEREN, une bibliothèque destinée à accélérer la sérialisation des objets en améliorant le traitement des wrappers numériques et des chaînes de caractères.<br
/> Prenant la forme d&#8217;un agent pour la JVM, SEREN peut s&#8217;utiliser sans modifier le code existant et peut être ajouté ou supprimé simplement en redémarrant la JVM.</p><p>Comme toute amélioration de performance, il s&#8217;agit d&#8217;un compromis: SEREN propose d&#8217;augmenter un peu la taille du flux binaire sérialisé en échange d&#8217;un gain de vitesse, un compromis que l&#8217;auteur recommande pour la sérialisation mémoire en citant EHCache. Il est possible de configurer les classes &laquo;&nbsp;améliorées&nbsp;&raquo; par SEREN au travers des fichiers de configuration et d&#8217;un mécanisme de filtre qui peut être étendu au besoin.</p><p>Retrouvez l&#8217;introduction de SEREN sur <a
href="http://thecodersbreakfast.net/index.php?post/2012/01/09/Introducing-Seren-the-serialization-speed-enhancer" rel="nofollow">son blog</a> et le code sur <a
href="https://github.com/oliviercroisier/seren" rel="nofollow">github</a>.</p><h4><a
name="Revuedepresse-Apologiedeslambdasdeblockspourjavascript"></a>Apologie des lambdas de blocks pour javascript</h4><p>Le working group ECMA, responsable de la définition du standard ECMAScript implémenté par javascript <a
href="http://wiki.ecmascript.org/doku.php?id=strawman:block_lambda_revival" rel="nofollow">envisage l&#8217;ajout de lambdas de blocks à javascript</a>, un ajout que <a
href="http://yehudakatz.com/" rel="nofollow">Yehuda Katz</a> défend dans un <a
href="http://yehudakatz.com/2012/01/10/javascript-needs-blocks/" rel="nofollow">article de blog</a> parfaitement illustré comparant ruby et javascript sur le terrain du <a
href="http://www.amazon.com/exec/obidos/ASIN/0137098731/wrrrldwideweb" rel="nofollow">principe de correspondance de Tennent</a>, des lambdas de fonctions et des lambdas de blocks.<br
/> Les exemples utilisés présentent des refactorings d&#8217;une forme canonique vers des formes idiomatiques dans les deux langages pour illustrer les principes mis en œuvre, une excellente introduction au sujet.</p><h4><a
name="Revuedepresse-Verbosit%C3%A9deslangagesdeprogrammation"></a>Verbosité des langages de programmation</h4><p>À l&#8217;heure où les comparaisons entre langages tournent souvent en guerres de clochers, <a
href="http://rethrick.com/#about" rel="nofollow">Dhanji R. Prasanna</a> (ancien employé de Google et membre du projet Guice) se livre à une analyse plus posée et réfléchie sur l&#8217;équilibre entre expressivité et lisibilité. Cet article se démarque par son pragmatisme, la pertinence des exemples choisis, et le recul évident de l&#8217;auteur sur un grand nombre de langages.</p><p>Lire <a
href="http://www.informit.com/articles/article.aspx?p=1824790" rel="nofollow">Languages, Verbosity, and Java</a>.</p><h3><a
name="Revuedepresse-Ev%C3%A9nementsdenotrecommunaut%C3%A9enFranceet%C3%A0l%27%C3%A9tranger"></a>Evénements de notre communauté en France et à l&#8217;étranger</h3><h4><a
name="Revuedepresse-L%27artisanat%2Cunm%C3%A9tierd%27avenir"></a>L&#8217;artisanat, un métier d&#8217;avenir</h4><p>Plusieurs réflexions ont lieu en ce moment au sein de la communauté pour définir ce qu&#8217;est le métier de développeur. On en a parlé lors du <a
href="http://www.parisjug.org/xwiki/bin/view/Meeting/20111011" rel="nofollow">Paris JUG d&#8217;Octobre 2011</a>. Le mouvement de fond associé est bien sûr celui du Software Craftsmanship. Nous mettons cette semaine en avant deux entrées de blog pour nous aider à avancer sur le sujet.<br
/> Le <a
href="http://qahatesyou.com/wordpress/2012/01/software-development-is-neither-art-nor-science/" rel="nofollow">premier</a> article postule que le développement informatique ne peut-être vu ni comme un art ni une science. Pour l&#8217;auteur de ce blog, au titre provocateur, notre métier n&#8217;est pas purement un art car <b>le produit fini fait quelque chose</b> ni totalement une science car <b>il n&#8217;y a pas de loi universelle sur le développement, il peut y avoir autant de réponse qu&#8217;il y a de développeurs</b>. On peut accepter ces arguments ou pas. Mais au delà du pur débat d&#8217;idées on se rend compte qu&#8217;il est difficile d&#8217;expliquer un métier si complexe à une personne extérieure.</p><p>L&#8217;auteur revient aussi sur le caractère unique des réalisations informatiques, et unique dans sa réalisation comme ses défauts. Il porte l&#8217;empreinte des personnes qui l&#8217;ont réalisé. Nous avons tous notre propre expérience sur des outils, des méthodes, des technologies, et nous expérimentons quelques fois de nouvelles façons de faire. Cela rend la manière de réaliser le travail éphémère et inscrite dans un contexte.<br
/> C&#8217;est peut-être cela la différence entre produire et écrire du code. Une vision &laquo;&nbsp;industrialiste&nbsp;&raquo; de la production du code induit une idée de volume, de quantitatif. La production serait le résultat d&#8217;un processus établi au résultat attendu, le développeur n&#8217;étant que l&#8217;élément interchangeable de transformation de la spécification à la réalisation.<br
/> L&#8217;autre vision s&#8217;attache plus à l&#8217;aspect qualitatif et humain. Le travail est confié à une personne et est un élément prépondérant dans la rédaction d&#8217;une solution au problème donné. L&#8217;auteur d&#8217;un travail d&#8217;écriture de code se voit assigné une ligne directrice, à lui ensuite de tracer le meilleur chemin.</p><p>Le <a
href="http://www.hiltmon.com/blog/2012/01/11/it-should-only-take-you-a-few-hours-dot-dot-dot/" rel="nofollow">second billet</a> revient sur l&#8217;importance de s&#8217;appuyer sur des personnes qui savent faire les choses. Créer une table de toutes pièces pour le commun des mortels ne semble pas compliqué. Un menuisier professionnel aura lui une toute autre vision de la réalisation. Il pensera à adapter au mieux son savoir-faire au besoin précis du client, anticipera bien plus de problèmes, choisira avec soin les outils et matériaux employés.<br
/> Nous sommes dans un contexte qui nous oblige à réduire le temps nécessaire pour mettre à disposition de nouvelles fonctionnalités. Comment alors expliquer à un utilisateur que le changement de formule de calcul d&#8217;un champ dans un rapport peut prendre plusieurs heures? Échangeons alors sur nos visions des choses. Si le client ne veut pas d&#8217;une table qui dure un siècle, il n&#8217;y a pas de raison de la fabriquer. Si par contre, il n&#8217;en a pas conscience, discutons ensemble pour trouver la meilleure façon de la réaliser. C&#8217;est en travaillant ensemble que le résultat sera celui attendu.</p><h4><a
name="Revuedepresse-UnesemainerichepourlesUserGroups"></a>Une semaine riche pour les User Groups</h4><p>Cette semaine est riche en événements proposés par les UG. Il y en aura pour tous les goûts.</p><p>Ce soir, mardi 17 :</p><ul><li>Le <a
href="http://www.lyonjug.org/" rel="nofollow">Lyon JUG</a> propose une soirée <a
href="http://www.lyonjug.org/evenements/perf-serveur" rel="nofollow">Performance des serveurs en Java</a> animée par <a
href="https://twitter.com/#!/ludomp" rel="nofollow">Ludovic Poitou</a>.</li><li>Le <a
href="http://www.normandyjug.org/" rel="nofollow">Normandie JUG</a> propose une <a
href="http://www.normandyjug.org/2012/01/09/soiree-annotation-avec-olivier-croisier-2/" rel="nofollow">soirée Annotation</a> animée par <a
href="https://twitter.com/#!/oliviercroisier" rel="nofollow">Olivier Croisier</a>.</li></ul><p>Le mercredi 18, <a
href="http://www.alpesjug.org/" rel="nofollow">l&#8217;Alpes JUG</a> propose une soirée <a
href="http://www.jugevents.org/jugevents/event/show.html?id=43468" rel="nofollow">Objectif Cloud</a> avec <a
href="https://twitter.com/#!/paulsandoz" rel="nofollow">Paul Sandoz</a> et <a
href="https://twitter.com/#!/ndeloof" rel="nofollow">Nicolas De Loof</a>.</p><p>Le jeudi 19 :</p><ul><li>Le <a
href="http://www.meetup.com/Paris-Groovy-Grails/" rel="nofollow">Paris Groovy and Grails User Group</a> accueille<a
href="https://it.twitter.com/#!/CedricChampeau" rel="nofollow">Cédric Champeau</a> sur le thème <a
href="http://www.meetup.com/Paris-Groovy-Grails/events/45108892/" rel="nofollow">Groovy 2.0 : un pas vers le typage statique</a>.</li><li>Le <a
href="http://toulousejug.org/" rel="nofollow">Toulouse JUG</a> organise une <a
href="http://toulousejug.org/2012/01/05/soiree-grails-le-1901-a-lepitech/" rel="nofollow">soirée Grails</a> animée par <a
href="https://twitter.com/#!/chipeau" rel="nofollow">Vincent Barrier</a> et <a
href="http://www.linkedin.com/pub/franck-silvestre/22/737/107" rel="nofollow">Franck Silvestre</a>.</li><li>Le <a
href="http://www.meetup.com/Android-Paris/" rel="nofollow">Paris Android User Group</a> propose une <a
href="http://www.meetup.com/Android-Paris/events/46922312/" rel="nofollow">conférence sur Ice Cream Sandwich</a> animée par <a
href="http://leo.cacheux.net/" rel="nofollow">Léo Cacheux</a> et <a
href="https://twitter.com/#!/madCdan" rel="nofollow">Daniel Fages</a>.</li><li>Le <a
href="http://bordeauxjug.org/" rel="nofollow">Bordeaux JUG</a> accueilleura <a
href="https://twitter.com/#!/rmat0n" rel="nofollow">Romain Maton</a> pour une soirée <a
href="http://bordeauxjug.org/20120119_Optimisez_votre_site_mobile" rel="nofollow">Optimisez votre site web sur mobile</a>.</li><li>Le <a
href="http://www.marsjug.org/" rel="nofollow">Mars JUG</a> propose une <a
href="http://www.jugevents.org/jugevents/event/show.html?id=43373" rel="nofollow">soirée EclipseLink</a> animée par <a
href="https://twitter.com/#!/shaunmsmith" rel="nofollow">Shaun Smith</a>.</li></ul><p>Pour vous tenir à jour, suivez le <a
href="https://sites.google.com/site/duchessfr/calendrier-conferences" rel="nofollow">calendrier de conférences maintenu par Duchess France</a>.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/17/revue-de-presse-xebia-2012-03/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Soirée &#8211; Concevez une application DataGrid-NoSQL hautement scalable avec Nati Shalom, fondateur et CTO Gigaspaces</title><link>http://blog.xebia.fr/2012/01/12/soiree-concevez-une-application-datagrid-nosql-hautement-scalable-avec-nati-shalom-fondateur-et-cto-gigaspaces/</link> <comments>http://blog.xebia.fr/2012/01/12/soiree-concevez-une-application-datagrid-nosql-hautement-scalable-avec-nati-shalom-fondateur-et-cto-gigaspaces/#comments</comments> <pubDate>Thu, 12 Jan 2012 12:20:00 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Cloud / NoSQL]]></category> <category><![CDATA[Tech Events]]></category> <category><![CDATA[Gigaspace]]></category> <category><![CDATA[Grid]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10265</guid> <description><![CDATA[Vous aimez regarder les présentations NoSQL et Data Grid sur Internet ? Nous aussi ! C’est pourquoi nous avons demandé à Nati Shalom, CTO &#38; fondateur Gigaspaces, et à ses ingénieurs de venir animer une  session de design d’une application DataGrid / NoSQL en reprenant un cas d’utilisation de la vraie vie : Twitter recodé avec Gigaspaces [...]]]></description> <content:encoded><![CDATA[<p> <img
src="http://blog.xebia.fr/wp-content/uploads/2011/10/logo-giga-spaces.png" style="border: 0px solid black" /><br
/> Vous aimez regarder les présentations NoSQL et Data Grid sur Internet ?</p><p><span
style="float: right"><img
src="http://blog.xebia.fr/wp-content/uploads/2011/10/nati-shalom.png" style="border: 0px solid black; margin: 1em;" /></span></p><p>Nous aussi ! C’est pourquoi nous avons demandé à <a
href="http://www.gigaspaces.com/ExecutiveManagement" rel="nofollow">Nati Shalom</a>, CTO &amp; fondateur <a
href="http://www.gigaspaces.com/" rel="nofollow">Gigaspaces</a>, et à ses ingénieurs de venir animer une  <b>session de design d’une application DataGrid / NoSQL en reprenant un cas d’utilisation de la vraie vie : Twitter recodé avec Gigaspaces et Cassandra.</b></p><p>Ce ne sera pas la conception d’un autre, ce sera notre design influencé par une des stars du domaine !</p><p>Les participants feront chacun leur tour du <b>&laquo;&nbsp;pair-design&nbsp;&raquo; avec Nati Shalom et un coding dojo avec un ingénieur R&amp;D de Gigaspaces</b>.</p><p>Cette soirée gratuite aura lieu le 25 Janvier. Comme d&#8217;habitude, c&#8217;est à 19 heures chez Xebia ; l&#8217;inscription et les détails se trouvent sur <a
href="http://xfr-design-with-nati-shalom.eventbrite.com/" rel="nofollow">EventBrite</a> ! </p><p>Le <em>matériel</em> de la soirée :</p><ul><li> L&#8217;analyse de Dotan Horovits sur l&#8217;étude de cas :<br
/> <a
href="http://horovits.wordpress.com/2012/01/27/analytics-for-big-data-venturing-with-the-twitter-use-case/" rel="nofollow">Analytics for Big Data – Venturing with the Twitter Use Case</a></li><li>Les slides de Nati Shalom <a
href="http://www.slideshare.net/giganati/real-time-analytics-for-big-dataa-twitter-casestudy-v3-i-pad/" rel="nofollow">Real time analytics for big data a twitter casestudy</a>,</li><li>Le <a
href="https://github.com/dotanh/rt-analytics" rel="nofollow">code source de l&#8217;implémentation avec Gigaspaces et Cassandra</a></li><li>Vidéo : en cours de post production &#8230;.</li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/12/soiree-concevez-une-application-datagrid-nosql-hautement-scalable-avec-nati-shalom-fondateur-et-cto-gigaspaces/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Interview de Kirk Pepperdine sur les performances en Java par Cyrille Le Clerc</title><link>http://blog.xebia.fr/2012/01/12/interview-de-kirk-pepperdine-sur-les-performances-en-java-par-cyrille-le-clerc/</link> <comments>http://blog.xebia.fr/2012/01/12/interview-de-kirk-pepperdine-sur-les-performances-en-java-par-cyrille-le-clerc/#comments</comments> <pubDate>Thu, 12 Jan 2012 07:49:47 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[Tech Events]]></category> <category><![CDATA[interview]]></category> <category><![CDATA[java]]></category> <category><![CDATA[Performances]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10255</guid> <description><![CDATA[Cyrille Le Clerc a profité du passage de Kirk Pepperdine à Paris pour l&#8217;interviewer sur les performances en Java ; au programme de ces discussions : Comment troubleshooter des problèmes de performances : les points d&#8217;entrées de l&#8217;investigation, Nouveaux langages sur la JVM : Scala, Clojure, &#8230; Cloud computing et virtualisation, JVM et appliances Java [...]]]></description> <content:encoded><![CDATA[<p><span
style="float: right"><img
src="http://blog.xebia.fr/wp-content/uploads/2012/01/pepperdine-leclerc.png" style="border: 0px solid black; margin: 1em 1em 1em 1em;" /></span><br
/> <a
href="http://blog.xebia.fr/author/cleclerc/" rel="nofollow">Cyrille Le Clerc</a> a profité du passage de <a
href="http://kirk.blog-city.com/" rel="nofollow">Kirk Pepperdine</a> à Paris pour l&#8217;interviewer sur les performances en Java ; au programme de ces discussions :</p><ul><li>Comment <em>troubleshooter</em> des problèmes de performances : les points d&#8217;entrées de l&#8217;investigation,</li><li>Nouveaux langages sur la JVM : Scala, Clojure, &#8230;</li><li>Cloud computing et virtualisation,</li><li>JVM et <em>appliances</em> Java : Hotspot, jRockit, IBM J9, Azul, ExaLogic, &#8230;</li><li>Support des <em>large heaps</em> : G1, Direct Memory, &#8230;</li><li>&#8230; et quelques recommandations de programmation en Java.</li></ul><p>Bonne écoute !</p><p></p><div
id='kirk-pepperdine-java-performances-cyrille-le-clerc'></div><p><script type="text/javascript">jwplayer('kirk-pepperdine-java-performances-cyrille-le-clerc').setup({
    	flashplayer: '/videos/player.swf',
	    'id': 'playerID',
    	'width': '560',
	    'height': '24',
	    'file': '/videos/kirk-pepperdine-java-performances-cyrille-le-clerc.mp3',
	    'controlbar': 'bottom'
	});</script></p><hr/> <strong>Tous les podcasts Xebia France :</strong></p><ul><li><a
href="itpc://blog.xebia.fr/feed/podcast/" title="Subscribe to the Podcast Feed with iTunes"><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/itunes.png" class="podpress_feed_buttons" alt="Subscribe with iTunes"></a></li><li><a
href="http://blog.xebia.fr/feed/podcast/" title="Les podcasts de Xebia France vous permettent de suivre l'actualité autour de Java, de l'agilité, des technologies Web et bien d'autres. Xebia France est une entreprise spécialisée dans les technologies Java et JEE en environnement agile."><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/feed_button-rss-podcast.png" class="podpress_feed_buttons" alt="Xebia France Podcast Feed"></a></li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/12/interview-de-kirk-pepperdine-sur-les-performances-en-java-par-cyrille-le-clerc/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <enclosure
url="http://blog.xebia.fr/videos/kirk-pepperdine-java-performances-cyrille-le-clerc.mp3" length="34756986" type="audio/mpeg" /> <itunes:duration>0:36:12</itunes:duration> <itunes:subtitle> Cyrille Le Clerc a profité du passage de Kirk Pepperdine à Paris pour l&#8217;interviewer sur les performances en Java ; au programme de ces discussions :
Comment troubleshooter des problèmes de performances : les points d&#8217;entrées de l[...]</itunes:subtitle> <itunes:summary> Cyrille Le Clerc a profité du passage de Kirk Pepperdine à Paris pour l&#8217;interviewer sur les performances en Java ; au programme de ces discussions :
Comment troubleshooter des problèmes de performances : les points d&#8217;entrées de l&#8217;investigation,
Nouveaux langages sur la JVM : Scala, Clojure, &#8230;
Cloud computing et virtualisation,
JVM et appliances Java : Hotspot, jRockit, IBM J9, Azul, ExaLogic, &#8230;
Support des large heaps : G1, Direct Memory, &#8230;
&#8230; et quelques recommandations de programmation en Java.
Bonne écoute !
Tous les podcasts Xebia France : </itunes:summary> <itunes:keywords>Performance</itunes:keywords> <itunes:author>Xebia France</itunes:author> <itunes:explicit>no</itunes:explicit> <itunes:block>no</itunes:block> </item> <item><title>Scala &#8211; jouer avec le pattern matching</title><link>http://blog.xebia.fr/2012/01/11/scala-jouer-avec-le-pattern-matching/</link> <comments>http://blog.xebia.fr/2012/01/11/scala-jouer-avec-le-pattern-matching/#comments</comments> <pubDate>Wed, 11 Jan 2012 05:47:56 +0000</pubDate> <dc:creator>François Sarradin</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[scala]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10242</guid> <description><![CDATA[Combien de fois vous êtes vous senti engoncé dans votre frustration parce que vous étiez incapable d’utiliser des chaînes de caractères dans vos switch-case ? À défaut de pouvoir utiliser Java 7, une telle possibilité serait très utile pour par exemple traiter les arguments de votre application, pour analyser un fichier ou le contenu d’une [...]]]></description> <content:encoded><![CDATA[<p>Combien de fois vous êtes vous senti engoncé dans votre frustration parce que vous étiez incapable d’utiliser des chaînes de caractères dans vos <em>switch-case</em> ? À défaut de pouvoir utiliser Java 7, une telle possibilité serait très utile pour par exemple traiter les arguments de votre application, pour analyser un fichier ou le contenu d’une chaîne. En fait, pour y arriver, vous devez écrire une série de <em>if-else-if</em>. Mais vous pourriez aussi utiliser une table de hachage, où les clés sont les chaînes de caractères et les valeurs sont les traitements réifiés par des <em>Runnable</em>, des <em>Callable</em> ou des <em>Function</em> de Guava.</p><p>Si le <em>switch-case</em> acceptant des chaînes de caractères est pour vous une chouette invention, le <b>pattern matching</b> de Scala nous indique que ce n’est pas suffisant ! En effet, il y a d’autres cas où une série de <em>if-else_if-else_if&#8230;</em> serait sympathiquement transformée en une sorte de structure plus ou moins équivalente au <em>switch-case</em>. Par exemple, ce serait bien de pouvoir simplifier une série de compositions entre des <em>instanceof</em> et des <em>class cast</em> enfermés dans cette série de <em>if-else_if-&#8230;</em> en vue de réaliser des traitements spécifiques selon le type d’un paramètre (en attendant le <a
href="http://en.wikipedia.org/wiki/Multiple_dispatch" rel="nofollow">multi-méthode</a>).</p><p>Dans cet article, nous allons voir ce que peut apporter le pattern matching de Scala dans différents cas.</p><p>Note : le pattern matching tel qu’il apparaît dans le langage Scala n’est pas nouveau. Cette caractéristique existe déjà dans des langages comme OCaml et Haskell. On le retrouve aussi dans des dialectes de Lisp. Prolog propose aussi une sorte de pattern matching, mais celui-ci utilise en fait un mécanisme assez différent (on parle d’<em>unification</em> dans ce cas).</p><h3><a
name="DRAFT-Scala-joueraveclepatternmatching-Approcheclassique"></a>Approche classique</h3><p>Le pattern matching de Scala possède un cas d’utilisation qui est similaire aux <em>switch-case</em> de Java et de C : chaque entrée se base sur un entier ou tout autre scalaire. Voici un exemple :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def toYesOrNo(choice: Int): String = choice match {
  case 1 =&gt; &quot;yes&quot;
  case 0 =&gt; &quot;no&quot;
  case _ =&gt; &quot;error&quot;
}
</pre><p>Si vous appelez <em>toYesOrNo(1)</em>, Scala répond <code>"yes"</code>. Et si vous entrez <em>toYesOrNo(2)</em>, Scala répond <code>"error"</code>. Ici, le symbole _ est utilisé pour indiquer le cas par défaut. On peut remarquer que nous n’utilisons pas l’instruction <em>break</em>. Cette instruction est d’une certaine manière implicite.</p><p>Maintenant, si vous souhaitez que la fonction réponde <code>"yes"</code> non seulement pour la valeur 1, mais aussi pour les valeurs 2 et 3, on écrira :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def toYesOrNo(choice: Int): String = choice match {
  case 1 | 2 | 3 =&gt; &quot;yes&quot;
  case 0 =&gt; &quot;no&quot;
  case _ =&gt; &quot;error&quot;
}
</pre><p>Jusque là, rien de vraiment nouveau.</p><p>Utilisons des chaînes de caractères en entrée, comme le permet Java 7. Utiliser des chaînes est intéressant par exemple lorsque vous devez analyser les arguments passés à votre programme :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def parseArgument(arg: String) = arg match {
  case &quot;-h&quot; | &quot;--help&quot;    =&gt; displayHelp
  case &quot;-v&quot; | &quot;--version&quot; =&gt; displayVerion
  case whatever =&gt; unknownArgument(whatever)
}
</pre><p>Si vous entrez <code>parseArgument("-h")</code> ou <code>parseArgument("--help")</code>, Scala appellera la fonction <code>displayHelp</code>. Et si vous entrez <code>parseArgument("hein?")</code>, Scala appellera la fonction <code>unknownArgument("hein?")</code>. Dans la fonction <code>parseArgument</code>, nous n’avons pas utilisé &#8216;_&#8217; pour le cas par défaut. En fait, lorsque le cas par défaut est utilisé, contrairement aux fonctions précédentes, on a la possibilité de lui donner un nom.</p><h3><a
name="DRAFT-Scala-joueraveclepatternmatching-Patterntyp%C3%A9"></a>Pattern typé</h3><p>Parfois en Java, vous devez faire face à une variable déclarée en tant que <em>Object</em> ou toute autre interface ou classe de haut niveau. Malheureusement, après avoir vérifié que la variable n’est pas nulle, vous devez en plus utiliser une série de <em>if-else</em> incluant des tests avec <em>instanceof</em> et <em>cast</em>. Tout ça dans le but de vérifier la classe ou l’interface d’une instance, avant de l’utiliser et de la traiter comme il se doit. C’est le cas, par exemple, lorsque vous devez redéfinir la méthode <em>equals()</em> en Java.</p><p>Voici comment Scala voit la chose :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def f(x: Any): String = x match {
  case i:Int =&gt; &quot;integer: &quot; + i
  case _:Double =&gt; &quot;a double&quot;
  case s:String =&gt; &quot;I want to say &quot; + s
}
</pre><p>On obtient alors les résultats suivants :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
f(1) → &quot;integer: 1&quot;
f(1.0) → &quot;a double&quot;
f(&quot;hello&quot;) → &quot;I want to say hello&quot;
</pre><p>N’est-ce pas mieux qu’une succession de <em>if+instanceof+cast</em> ?</p><p>Ce type de pattern matching est utile pour traverser une structure utilisant le design pattern composite. Par exemple, vous pouvez l’utiliser pour explorer plus aisément le DOM d’un document XML ou le modèle objet d’un message JSON.</p><h3><a
name="DRAFT-Scala-joueraveclepatternmatching-Approchefonctionnelledupatternmatching"></a>Approche fonctionnelle du pattern matching</h3><p>Une particularité d’une telle structure, c’est qu’elle offre une approche alternative pour écrire des fonctions. Par exemple, considérons la fonction factorielle. Si nous choisissons la version récursive, habituellement nous la définirions ainsi :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def fact(n: Int): Int =
  if (n == 0) 1
  else n * fact(n - 1)
</pre><p>Mais, on peut aussi utiliser le pattern matching de Scala dans ce cas :</p><pre class="brush: java; gutter: true; title: ; notranslate">
def fact(n: Int): Int = n match {
  case 0 =&gt; 1
  case n =&gt; n * fact(n - 1)
}
</pre><p>Notez l’utilisation de la variable <em>n</em> ci-dessus. Elle est mise en correspondance avec toutes les valeurs qui n’apparaissent pas dans les cas précédents. Il faut comprendre que le <em>n</em> du dernier cas n’est pas le même que celui utilisé dans la signature de la fonction. Si vous voulez utiliser directement le paramètre <em>n</em> et non pas une autre variable du même nom, vous devez délimiter le nom de la variable par des guillemets inversés dans la déclaration du case, comme ceci : <code>`n`</code></p><p>Sinon, voici un moyen simple de définir la fonction factorielle en Scala :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def fact(n) = (1 to n).foldLeft(1) { _ * _ }
</pre><p>Où foldLeft est une opération visant à &laquo;&nbsp;réduire&nbsp;&raquo; une collection par rapport à une fonction et <code>{ _ * _ }</code> est une fonction anonyme qui équivaut à <code>{ case (x: Int, y: Int) =&gt; x * y }</code>, autrement dit une fonction qui prend deux entiers et effectue la multiplication de ces deux entiers.</p><h3><a
name="DRAFT-Scala-joueraveclepatternmatching-Patternmatchingetcollection%3Al%E2%80%99approchepar%22similarit%C3%A9%22"></a>Pattern matching et collection : l’approche par &laquo;&nbsp;similarité&nbsp;&raquo;</h3><p>Le pattern matching peut être appliqué aux collections. Ci-dessous, vous avez une fonction qui calcule la longueur d’une liste sans pattern matching :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def length[A](list: List[A]): Int = {
  if (list.isEmpty) 0
  else 1 + length(list.tail)
}
</pre><p>Maintenant, voici la même fonction avec le pattern matching :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def length[A](list: List[A]): Int = list match {
  case Nil =&gt; 0
  case _ :: tail =&gt; 1 + length(tail)
}
</pre><p>Dans cette fonction, il y a deux cas (ou plutôt deux <em>case</em>). Le premier vérifie si la liste est vide grâce à la valeur <code>Nil</code>. Le second vérifie si il y a au moins un élément dans la liste. La notation <code>_::tail</code> doit être interprétée comme « une liste ayant au moins un élément, sachant qu’on ne s’intéresse qu’au reste de la liste qui est représenté par la variable <em>tail</em> ». Ici, le reste peut être <em>Nil</em> (ie. la liste vide) ou n’importe quelle liste non vide.</p><p>On peut utiliser cette approche par similarité avec des tuples afin d’améliorer la méthode <em>parserArgument</em> vue auparavant :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def parseArgument(arg : String, value: Any) = (arg, value) match {
  case (&quot;-l&quot;, lang) =&gt; setLanguageTo(lang)
  case (&quot;-o&quot; | &quot;--optim&quot;, n : Int) if ((0 &lt; n) &amp;&amp; (n &lt;= 5))
    =&gt; setOptimizationLevelTo(n)
  case (&quot;-o&quot; | &quot;--optim&quot;, badLevel) =&gt; badOptimizationLevel(badLevel)
  case (&quot;-h&quot; | &quot;--help&quot;, _) =&gt; displayHelp()
  case bad =&gt; badArgument(bad)
}
</pre><p>Notez en premier lieu l’utilisation de l’opérateur | qui permet de mettre en correspondance des formes alternatives de <em>arg</em> au sein d’un tuple. Notez aussi l’utilisation de deux patterns pour les options <code>-o</code> et <code>--optim</code>. Ces patterns se distinguent par l’utilisation d’un prédicat qu’on appelle une garde. Une garde vous permet d’affiner vos <em>case</em> lorsque le pattern ne suffit pas.</p><h3><a
name="DRAFT-Scala-joueraveclepatternmatching-PatternMatchingavanc%C3%A9%3Acaseclass"></a>Pattern Matching avancé : case class</h3><p>Les <b>case classes</b> sont des classes dont une partie du comportement est prédéfinie afin de faciliter leur construction et leur utilisation dans des patterns. Les cases classes vous permettent de manipuler des symboles paramétrés, provenant par exemple de l’analyse d’un compilateur ou de votre DSL interne.</p><p>L’exemple ci-dessous montre comment utiliser les case classes et le pattern matching afin de représenter simplement des expressions mathématiques, de les évaluer et d’en calculer la dérivée. Commençons par définir les symboles que nous utiliserons : la variable X, la constante, l’addition, la multiplication et la négation (pour le fun !). Ici, <em>sealed</em> signifie qu’aucune classe fille de <em>Expression</em> n’apparaîtra en dehors de l’espace de nom courant.</p><pre class="brush: scala; gutter: true; title: ; notranslate">
sealed abstract class Expression
case object X extends Expression
case class Const(value: Int) extends Expression
case class Add(left: Expression, right: Expression) extends Expression
case class Mult(left: Expression, right: Expression) extends Expression
case class Neg(expr: Expression) extends Expression
</pre><p>Maintenant, définissons une fonction qui évalue une expression avec une valeur donnée pour la variable X, en utilisant le pattern matching.</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def eval(expression: Expression, xValue: Int): Int = expression match {
  case X =&gt; xValue
  case Const(cst) =&gt; cst
  case Add(left, right) =&gt; eval(left, xValue) + eval(right, xValue)
  case Mult(left, right) =&gt; eval(left, xValue) * eval(right, xValue)
  case Neg(expr) =&gt; - eval(expr, xValue)
}
</pre><p>Essayons la fonction <em>eval</em> :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
// 1 + 2 * X*X
val expr = Add(Const(1), Mult(Const(2), Mult(X, X)))
assert(eval(expr, 3) == 19)
</pre><p>Maintenant, définissons une fonction qui calcule la dérivée (non réduite) par rapport à X d’une expression :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
def deriv(expression: Expression): Expression = expression match {
  case X =&gt; Const(1)
  case Const(_) =&gt; Const(0)
  case Add(left, right) =&gt; Add(deriv(left), deriv(right))
  case Mult(left, right) =&gt; Add(Mult(deriv(left), right), Mult(left, deriv(right)))
  case Neg(expr) =&gt; Neg(deriv(expr))
}
</pre><p>Essayons notre fonction <em>deriv</em> :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
val df = deriv(expr)
</pre><p>Voici à quoi ressemble <em>df</em> :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
Add(Const(0),
  Add(Mult(Const(0),Mult(X,X)),
    Mult(Const(2),
      Add(Mult(Const(1),X),
        Mult(X,Const(1))))))
// = 0 + (0 * X*X + 2 * (1*X + X*1)) = 4 * X
</pre><p>Et en utilisant les deux fonctions conjointement :</p><pre class="brush: scala; gutter: true; title: ; notranslate">
assert(eval(df, 3), 12)
</pre><h3><a
name="DRAFT-Scala-joueraveclepatternmatching-Autresutilisationsavanc%C3%A9esdupatternmatching"></a>Autres utilisations avancées du pattern matching</h3><p>Il y a d’autres notations particulières utilisables dans le pattern matching de Scala. Scala permet ainsi de déclarer des alias sur tout ou partie d’un pattern qui pourront être exploités par la suite. L’alias doit apparaître avant le pattern séparé d’un @. Par exemple, dans l’expression <code>address @ Address(_, _, "Paris", "France")</code>, nous acceptons dans <em>address</em> toutes les adresses en France à Paris, mais peu importe la rue et le numéro.</p><p>Il y a une notation spécifique pour faire correspondre des séquences avec _*. Cette notation prend en compte zéro élément, un élément ou plus dans une séquence.</p><p>En Scala, le pattern matching n’apparaît pas seulement après la fonction <em>match</em>. Vous pouvez utiliser le pattern matching pour les paramètres de closures et dans les blocs <em>catch</em>.</p><p>Il est possible aussi de personnaliser le comportement du pattern matching au moyen des <em><a
href="http://www.scala-lang.org/node/112" rel="nofollow">extractor</a></em>. Pour cela, vous devez définir la méthode <em>unapply</em> (et/ou <em>unapplySeq</em> pour une séquence) au niveau des objets que vous utiliserez dans les pattern matching.</p><h3><a
name="DRAFT-Scala-joueraveclepatternmatching-Conclusion"></a>Conclusion</h3><p>Dans cet article, nous avons vu différentes manières d’utiliser le pattern matching de Scala. Le principal avantage de cet outil est de fournir une manière simple de construire des structures alternatives basées sur la mise en correspondance de valeurs scalaires, de chaînes de caractères, de collections, mais aussi de symboles paramétrés et de types. Pour moi, le pattern matching est l’une des alternatives les plus sexy à la structure <em>if</em> ! Une bonne utilisation du pattern matching peut rendre votre programme plus lisible et vous aider à mettre en oeuvre un DSL interne.</p><p><em>Cet article est une traduction libre, faite avec l’autorisation de l’auteur, de «</em> <em><a
href="http://kerflyn.wordpress.com/2011/02/14/playing-with-scalas-pattern-matching/" rel="nofollow">Playing with Scala’s pattern matching</a></em> <em>» publié par François Sarradin le 14/02/2011 sur</em> <em><a
href="http://kerflyn.wordpress.com/" rel="nofollow">http://kerflyn.wordpress.com/</a></em><em>.</em></p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/11/scala-jouer-avec-le-pattern-matching/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2012/01/10/revue-de-presse-xebia-2012-02/</link> <comments>http://blog.xebia.fr/2012/01/10/revue-de-presse-xebia-2012-02/#comments</comments> <pubDate>Tue, 10 Jan 2012 05:49:57 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[CouchBase]]></category> <category><![CDATA[CouchDB]]></category> <category><![CDATA[Duchess]]></category> <category><![CDATA[Infinitest]]></category> <category><![CDATA[Paris JUG]]></category> <category><![CDATA[Paris Software Craftsmanship Community]]></category> <category><![CDATA[scala]]></category> <category><![CDATA[Sécurité]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10225</guid> <description><![CDATA[La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia. Le coin de la technique Infinitest supporte scala CouchBase et CouchDB (par Xavier Bucchiotty) Alerte de sécurité sur la quasi totalité des serveurs web (par Pierre Laporte) Evénements de notre communauté en France et à l&#8217;étranger Lancement de la communauté Software Craftsmanship de Toulouse [...]]]></description> <content:encoded><![CDATA[<p><img
src="http://blog.xebia.fr/wp-content/uploads/2007/06/revuedepresse.png" alt="Revue de Presse Xebia" style="margin: 1em 1em 1em 1em; float: right;" /><br
/> <em>La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia.</em></p><p><strong>Le coin de la technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/10/revue-de-presse-xebia-2012-02/#Infinitestsupportescala">Infinitest supporte scala</a></li><li><a
href="http://blog.xebia.fr/2012/01/10/revue-de-presse-xebia-2012-02/#CouchBaseetCouchDB">CouchBase et CouchDB</a> <em>(par</em> <em><a
href="http://blog.xebia.fr/author/xbucchiotty/" rel="nofollow">Xavier Bucchiotty</a></em><em>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/10/revue-de-presse-xebia-2012-02/#Alertedes%C3%A9curit%C3%A9surlaquasitotalit%C3%A9desserveursweb">Alerte de sécurité sur la quasi totalité des serveurs web</a> <em>(par</em> <em><a
href="https://twitter.com/#!/pingtimeout" rel="nofollow">Pierre Laporte</a></em><em>)</em></li></ul><p><strong>Evénements de notre communauté en France et à l&#8217;étranger</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/10/revue-de-presse-xebia-2012-02/#Lancementdelacommunaut%C3%A9SoftwareCraftsmanshipdeToulouse">Lancement de la communauté Software Craftsmanship de Toulouse</a></li><li><a
href="http://blog.xebia.fr/2012/01/10/revue-de-presse-xebia-2012-02/#Cesoir%2C10janvier%2CParisJUGDevOpsetAvantJUGdesDuchess">Ce soir, 10 janvier, Paris JUG DevOps et Avant JUG des Duchess</a></li><li><a
href="http://blog.xebia.fr/2012/01/10/revue-de-presse-xebia-2012-02/#IntroductionauxDSLenGroovyauNantesJUGlejeudi12janvier">Introduction aux DSL en Groovy au Nantes JUG le jeudi 12 janvier</a></li></ul><h3><a
name="Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="Infinitestsupportescala"></a>Infinitest supporte scala</h4><p>Les dernières versions d&#8217;infinitest apportent des corrections pour intellij IDEA 11 et le support des projets Scala. Infinitest est <a
href="http://infinitest.github.com/" rel="nofollow">disponible sur github</a>.</p><h4><a
name="CouchBaseetCouchDB"></a>CouchBase et CouchDB</h4><p><a
href="http://damienkatz.net/2009/12/about_me.html" rel="nofollow">Damien Katz</a> est un des fondateurs du projet <a
href="http://couchdb.apache.org/" rel="nofollow">Apache CouchDB</a>. CouchDB fait partie de l&#8217;univers NoSQL, écrit en Erlang, orienté &#8216;document&#8217; avec des API basées sur Javascript et JSON. Dans <a
href="http://damienkatz.net/2012/01/the_future_of_couchdb.html" rel="nofollow">son blog</a>, il indique qu&#8217;une grande partie de l&#8217;équipe ainsi que lui-même quittent le projet pour fonder <a
href="http://www.couchbase.com/products-and-services/overview" rel="nofollow">Couchbase Server</a>, le successeur.<br
/> Ce changement signifie aussi que les produits Couchbase ne seront plus sous licence Apache. Damien Katz ne dénigre pas cette fondation, à qui le succès de CouchDB est intimement lié. Les produits CouchBase sont payants, et selon Damien Katz, l&#8217;approche par consensus des développeurs, si chère à Apache, est un frein à la compétitivité du produit.<br
/> Cette approche permet donc à l&#8217;équipe de servir au mieux ses clients avec une plus grande réactivité. Il assure cependant que l&#8217;équipe continue de contribuer à CouchDB qui se porte plutôt bien. Son but actuel est de porter la version 2.0 de CouchBase avec un portage d&#8217;une partie du code d&#8217;Erlang vers C/C++.<br
/> Affaire à suivre.</p><h4><a
name="Alertedes%C3%A9curit%C3%A9surlaquasitotalit%C3%A9desserveursweb"></a>Alerte de sécurité sur la quasi totalité des serveurs web</h4><p>Deux chercheurs en sécurité, Alexander Klink et Julian Wälde, ont relevé une faille de sécurité algorithmique dans la plupart des serveurs web du marché. Sont concernées, les plateformes Java, Python, Ruby, PHP, Node.JS et ASP.NET.</p><p>La vulnérabilité détectée est de type <a
href="http://perl.enstimac.fr/DocFr/perlsec.html#attaques par complexité algorithmique" rel="nofollow">attaque par complexité algorithmique</a>. Elle consiste à rechercher le pire scénario possible dans l’implémentation d’une fonctionnalité. Ici, les <a
href="http://en.wikipedia.org/wiki/Hash_table" rel="nofollow">hash tables</a> sont la cible de l’attaque.</p><p>Le principe est le suivant : lorsqu’un serveur reçoit une requête http qui contient n paramètres, il crée un tableau associatif avec pour clé, le nom du paramètre, et pour valeur, l’ensemble des valeurs reçues. La hash table résultante utilise le hachage du nom du paramètre pour déterminer son emplacement.</p><p>Dans le meilleur des cas, c&#8217;est-à-dire lorsqu’il n’existe pas deux paramètres ayant le même hachage, l’insertion d’un élément se fait en temps constant (en O( 1 )). Dans le pire des cas, elle se fait en temps linéaire (en O( n )).</p><p>Mais revenons à notre attaque. Il suffit de construire une requête HTTP avec un grand nombre de paramètres ayant tous le même hachage. Le serveur sera contraint de passer systématiquement par le pire des cas possibles pour l’insertion dans sa hash table. En prenant n paramètres, on arrive à une complexité de n(O( n )), c&#8217;est-à-dire O( n² ), la complexité quadratique. Il est donc possible de bloquer le CPU d’un serveur à 100% d’utilisation pendant plusieurs minutes.</p><p>A l’heure actuelle, certains serveurs ont été mis à jour pour limiter le nombre de paramètres HTTP pouvant être reçus par un serveur (1&#8217;000 pour <a
href="http://technet.microsoft.com/en-us/security/bulletin/ms11-100.mspx" rel="nofollow">ASP.NET</a>, 10&#8217;000 pour <a
href="http://www.kb.cert.org/vuls/id/DWAN-8PYMUS" rel="nofollow">Tomcat</a>, valeur non connue pour <a
href="http://www.php.net/archive/2011.php#id2011-12-25-1" rel="nofollow">PHP</a>). La vulnérabilité n’est donc pas totalement corrigée mais ses effets sont considérablement réduits. La correction complète impliquerait de rendre aléatoire le hachage des chaînes de caractères selon les plateformes par l’inclusion d’un seed. De ce fait, il ne serait plus possible de construire de telles collisions.</p><p>Notons qu’une correction est également en cours pour <a
href="http://www.securitytracker.com/id/1026476" rel="nofollow">Glassfish</a> et sera mise à disposition avec le prochain patch de sécurité.</p><h3><a
name="Ev%C3%A9nementsdenotrecommunaut%C3%A9enFranceet%C3%A0l%27%C3%A9tranger"></a>Evénements de notre communauté en France et à l&#8217;étranger</h3><h4><a
name="Lancementdelacommunaut%C3%A9SoftwareCraftsmanshipdeToulouse"></a>Lancement de la communauté Software Craftsmanship de Toulouse</h4><p>La semaine dernière, <a
href="http://antoine.vernois.net/dotclear" rel="nofollow">Antoine Vernois</a> et <a
href="https://twitter.com/#!/thierrycros" rel="nofollow">Thierry Cros</a> ont organisé à Toulouse une réunion autour du Software Craftsmanship qui a réuni 15 personnes. Cette réunion marque le lancement de la <a
href="http://groups.google.com/group/software-craftsmanship-toulouse?pli=1" rel="nofollow">communauté Software Craftsmanship de Toulouse et de ses environs</a>.<br
/> Un premier événement est <a
href="http://www.doodle.com/fmaump9exenmypmz" rel="nofollow">en cours de planification</a> : Un <b>coding dojo au format randori</b>.<br
/> Vous trouverez plus de détails sur le blog d’Antoine : <a
href="http://antoine.vernois.net/dotclear/index.php?post/2012/01/09/Software-Craftsmanship-%C3%A0-Toulouse" rel="nofollow">La communauté Software Craftsmanship à Toulouse</a>.</p><h4><a
name="Cesoir%2C10janvier%2CParisJUGDevOpsetAvantJUGdesDuchess"></a>Ce soir, 10 janvier, Paris JUG DevOps et Avant JUG des Duchess</h4><p>Ce soir, le <a
href="http://parisjug.org/xwiki/bin/view/Meeting/20120110" rel="nofollow">premier Paris JUG de l’année</a> sera consacré à <a
href="http://blog.xebia.fr/tag/devops/" rel="nofollow">DevOps</a> avec une session <b>Packaging natif</b> par <a
href="http://parisjug.org/xwiki/bin/view/Speaker/GomezHenri" rel="nofollow">Henri Gomez</a> et une session <b>Puppet</b> par <a
href="http://parisjug.org/xwiki/bin/view/Speaker/SanchezCarlos" rel="nofollow">Carlos Sanchez</a>.<br
/> Les <a
href="http://jduchess.org/duchess-france/" rel="nofollow">Duchess</a> reprennent également les bonnes habitudes avec le <a
href="http://jduchess.org/duchess-france/blog/avant-jug-2012-01/" rel="nofollow">premier Avant JUG de l’année</a>.</p><h4><a
name="IntroductionauxDSLenGroovyauNantesJUGlejeudi12janvier"></a>Introduction aux DSL en Groovy au Nantes JUG le jeudi 12 janvier</h4><p>Le <a
href="https://sites.google.com/site/nantesjug/Home" rel="nofollow">Nantes JUG</a> commence l’année 2012 ce jeudi 12 avec une soirée <b>Introduction aux DSL (Domain Specific Languages) en Groovy</b> présentée par <a
href="https://twitter.com/#!/CedricChampeau" rel="nofollow">Cédric Champeau</a>, senior software developer chez <a
href="http://www.springsource.com/fr" rel="nofollow">SpringSource</a>.<br
/> <a
href="http://jugevents.org/jugevents/event/43326" rel="nofollow">Les inscriptions sont ouvertes sur JUG Events</a>.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/10/revue-de-presse-xebia-2012-02/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Mise en place d&#8217;une organisation DevOps</title><link>http://blog.xebia.fr/2012/01/09/mise-en-place-d-une-organisation-devops/</link> <comments>http://blog.xebia.fr/2012/01/09/mise-en-place-d-une-organisation-devops/#comments</comments> <pubDate>Mon, 09 Jan 2012 07:38:41 +0000</pubDate> <dc:creator>Cyrille Le Clerc</dc:creator> <category><![CDATA[Exploitation]]></category> <category><![CDATA[DevOps]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10219</guid> <description><![CDATA[Comme le mouvement Agile a rapproché donneurs d&#8217;ordre et équipes de réalisation autour d&#8217;une vision commune orientée &#171;&#160;produit&#160;&#187;, le mouvement DevOps rapproche aujourd&#8217;hui les équipes de développement (DEV) et d&#8217;exploitation (OPS) autour d&#8217;une vision commune orientée &#171;&#160;service&#160;&#187;, afin de mieux concilier réactivité et qualité de service. DevOps aborde le paradoxe entre des équipes projets qui [...]]]></description> <content:encoded><![CDATA[<p>Comme le mouvement Agile a rapproché donneurs d&#8217;ordre et équipes de réalisation autour d&#8217;une vision commune orientée &laquo;&nbsp;produit&nbsp;&raquo;, le mouvement DevOps rapproche aujourd&#8217;hui les équipes de développement (DEV) et d&#8217;exploitation (OPS) autour d&#8217;une vision commune orientée &laquo;&nbsp;service&nbsp;&raquo;, afin de mieux concilier réactivité et qualité de service.</p><p>DevOps aborde le paradoxe entre des équipes projets qui cherchent à livrer toujours plus fréquemment des nouvelles fonctionnalités d&#8217;une part et d&#8217;autre part des équipes d&#8217;exploitation qui cherchent à stabiliser et fiabiliser les systèmes tout en maitrisant leur coût.</p><p>On peut décrire DevOps selon trois axes :</p><ul><li><b>Aligner l&#8217;exploitation sur les enjeux métiers</b> comme l&#8217;agilité a déjà aligné le développement sur le métier.</li><li><b>Aligner le développement sur les réalités de l&#8217;exploitation</b> pour rendre possible la mise en production, la disponibilité et la fiabilité des fonctionnalités métier.</li><li>La <b>transformation du métier d&#8217;OPS</b> pour gérer des topologies chaque jour plus grosses et plus complexes avec l&#8217;adoption d&#8217;<em><a
href="http://www.agileweboperations.com/the-implications-of-infrastructure-as-code" rel="nofollow">infrastructure as code</a></em> et d&#8217;outils comme <a
href="http://www.opscode.com/chef/" rel="nofollow">Chef</a> ou <a
href="http://puppetlabs.com/puppet/puppet-enterprise/" rel="nofollow">Puppet</a>. <b>Les nouveaux OPS sont des programmeurs !</b> Ils débattent à la machine à café de <a
href="http://shop.oreilly.com/product/0636920020042.do" rel="nofollow">TDD</a>, de <a
href="http://wiki.opscode.com/display/chef/FAQ#FAQ-HowisChefdifferentthanPuppet%3F" rel="nofollow">Ruby vs. DSL</a>, <a
href="http://puppetlabs.com/blog/geppetto-a-puppet-ide/" rel="nofollow">de choix d&#8217;IDE</a>, de Git vs. SVN, &#8230;</li></ul><p>DevOps est souvent associé à la mise en place d&#8217;un processus de <a
href="http://java.dzone.com/articles/8-principles-continuous" rel="nofollow">Continuous Delivery</a> qui, dans la mouvance <em>Lean</em>, vise à déployer les fonctionnalités en production au plus vite et de maximiser les feedbacks. Nous reviendrons dans un autre billet sur les processus de Continuous Delivery.</p><p>La mise en place d&#8217;une culture DevOps touche les humains, les processus et les outils. Nous proposons une démarche englobant ces trois aspects en prenant comme point d&#8217;entrée les processus et, de proche en proche, faire évoluer les humains et les outils.</p><h3><a
name="DRAFT-MiseenplaceduneorganisationDevOps-Lesprocessus"></a>Les processus</h3><p>Tous les processus impliquant la collaboration des équipes de développement et d&#8217;exploitation sont sujets à la mise en place d&#8217;une culture &laquo;&nbsp;DevOps&nbsp;&raquo;. Nous  proposons pour la première étape de nous focaliser sur les processus de livraison, de déploiement et de <em>troubleshooting</em>.</p><h4><a
name="DRAFT-MiseenplaceduneorganisationDevOps-Processusdelivraison"></a>Processus de livraison</h4><p>Le processus de livraison (aka processus de <em>packaging</em> de la <em>release</em>) est la première interaction entre les équipes de développement et de production. Ses défauts causent l&#8217;allongement des projets et des interruptions de service. A l&#8217;inverse, <b>l&#8217;automatisation du processus de livraison concilie</b> <b><em>&laquo;&nbsp;time to market&nbsp;&raquo;</em> et diminution des risques en déployant plus fréquemment des changements au périmètre limité.</b></p><p>Nous proposons d&#8217;accorder les équipes de développement et d&#8217;exploitation sur les points suivants :</p><ul><li><b>Périmètre du</b> <b><em>package</em></b> pour éviter les transformations et manipulations de mise en production : binaires identiques sur tous les environnements, fichiers de configurations épurées, etc.</li><li><b>Rôles et responsabilités des équipes de développement et d&#8217;exploitation dans le</b> <b><em>packaging</em></b> : binaires pour les développeurs, scripts et paramètres de configuration gouvernés par l&#8217;exploitation, etc.</li><li><b>Définition des outils et techniques de</b> <b><em>packaging</em></b> : tag Subversion/Git, build Maven, <em>repository</em> Maven Nexus, etc.</li><li><b>Alignement des environnements</b> de développement, d&#8217;intégration et de production pour éviter les écarts dev/prod : on doit tester sur un environnement le plus <em>iso-prod</em> possible.</li></ul><h4><a
name="DRAFT-MiseenplaceduneorganisationDevOps-Processus%26nbsp%3Bd%C3%A9ploiement%26nbsp%3B"></a>Processus déploiement </h4><p>Une fois le <em>packaging</em> clarifié, nous proposons d&#8217;<b>automatiser et d&#8217;unifier les processus de déploiement du</b> <b><em>dev</em></b> <b>à la</b> <b><em>prod</em></b>. Les bénéfices sont :</p><ul><li><b>L&#8217;accélération des</b> <b><em>feedbacks</em></b> des équipes de Q&amp;A par des déploiements plus fréquents sur les environnements de validation.</li><li><b>La fiabilisation des déploiements</b> en les testant avant la mise en production.</li></ul><p>L&#8217;objectif est la banalisation : <b>les déploiements deviennent des &laquo;&nbsp;non événements&nbsp;&raquo;</b>.</p><h4><a
name="DRAFT-MiseenplaceduneorganisationDevOps-Processusdetroubleshootingetdediagnostique"></a>Processus de <em>troubleshooting</em> et de diagnostique</h4><p>Réussir l&#8217;analyse de problèmes en production nécessite une préparation et un entrainement conjoints des équipes d&#8217;exploitation et de développement.</p><p>Des répétitions impliquant à la fois OPS et DEV permettront de valider :</p><ul><li>Que les applications sont <em>debuggables</em> : clarté des messages de log, clarté des exceptions, indicateurs de monitoring (JMX), etc.</li><li>Que les outils de diagnostique sont installés : activation et collecte de logs, accès sans problèmes de firewall, disponibilité des outils sur les serveurs (curl, screen, jstat, jmap, etc.).</li><li>Que les OPS et les DEV ont les bons outils de collaboration lors de problèmes en production : accès en lecture seule pour les DEV, messagerie instantanée, partage d&#8217;écran, micro-casques, etc.</li></ul><h3><a
name="DRAFT-MiseenplaceduneorganisationDevOps-Am%C3%A9liorationcontinuedev%2Fprod"></a>Amélioration continue <em>dev/prod</em></h3><p>Les sujets d&#8217;amélioration continue transverse développement / exploitation sont gérés à la fois dans la continuité avec des réunions &laquo;&nbsp;dev/prod&nbsp;&raquo;, et lors d&#8217;événements particuliers sous forme de points &laquo;&nbsp;<em>post mortem</em>&nbsp;&raquo; (panne, mise en production importante, etc.). Les sujets abordés relèvent d&#8217;enjeux à court, moyen et long terme :</p><ul><li><b>Monitoring &amp; KPI</b> : mise en place d&#8217;indicateurs techniques et métiers de bonne santé des applications (choix des outils, adaptation du code métier, <em>health checks</em>, etc.).</li><li><b>Gestion des logs et des exceptions</b> : amélioration des messages, outils de concentration et d&#8217;analyse de logs.</li><li><b>Robustesse, tenue à la charge et</b> <b><em>capacity planning</em></b> : suppression des points de faiblesse, mise en place de modes dégradés et de mécanismes de protection contre les saturations (e.g. : <em>circuit breaker pattern</em>), plans d&#8217;action de test en charge, plan d&#8217;ajout de capacité.</li><li><b>Sécurité</b> : <em>patchs</em> à appliquer, règles de sécurité de l&#8217;entreprise, etc.</li><li><b>Fiabilisation des mises en production</b> : activation progressive (<em><a
href="http://martinfowler.com/bliki/FeatureToggle.html" rel="nofollow">feature toggle</a></em><em>)</em> ou partielle (<em>canary testing</em>) de fonctionnalités, etc.</li><li><b>Processus et outillage</b> : amélioration des processus dev/prod, alignement et partage des outils.</li><li><b>Suivi du schéma directeur</b> : gestion des montées de version des middlewares, migrations techniques, rationalisation des environnements.</li><li><b>Evolutions de l&#8217;application et de l&#8217;infrastructure</b> : <em>refactoring</em> de l&#8217;infrastructure, introduction de nouvelles technologies, plan de montée en compétence.</li></ul><h3><a
name="DRAFT-MiseenplaceduneorganisationDevOps-L%27organisation%3AYoubuildit%2Cyourunit%3F"></a>L&#8217;organisation : <em>You build it, you run it</em> ?</h3><p>L&#8217;organisation est le sujet le plus complexe à aborder dans la mise en place d&#8217;une culture &laquo;&nbsp;DevOps&nbsp;&raquo;. Certaines entreprises comme Amazon ont intégré les équipes de développement et de production au point d&#8217;avoir pour devise &laquo;&nbsp;You build it, you run it&nbsp;&raquo;.</p><p>Un point essentiel est de s&#8217;assurer que les objectifs des différents acteurs soient alignés vers une amélioration de la disponibilité et de l&#8217;évolutivité des applications. Si les intérêts des uns et des autres sont contradictoires et ne sont pas alignés sur ce même objectif, l&#8217;adoption d&#8217;une culture &laquo;&nbsp;DevOps&nbsp;&raquo; touchera vite ses limites.</p><p>Nous proposons d&#8217;étudier les changement organisationnels au fur et à mesure de la mise en place des principes DevOps dans les processus que nous avons cité en veillant à prendre en compte les réalités de chaque entreprise.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/09/mise-en-place-d-une-organisation-devops/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc &#8211; Épisode 3</title><link>http://blog.xebia.fr/2012/01/05/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-3/</link> <comments>http://blog.xebia.fr/2012/01/05/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-3/#comments</comments> <pubDate>Thu, 05 Jan 2012 07:40:37 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Cloud / NoSQL]]></category> <category><![CDATA[Tech Events]]></category> <category><![CDATA[cloud]]></category> <category><![CDATA[CloudBees]]></category> <category><![CDATA[Sacha Labourey]]></category> <category><![CDATA[vidéo]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10201</guid> <description><![CDATA[Voici le troisième épisode de la série de questions/réponses échangées lors de la soirée Cloud organisée par Cyrille Leclerc avec Sacha Labourey. Tous les podcasts Xebia France : Les vidéos de la soirées : Vidéo de la présentation de Sacha Labourey sur le Cloud Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc [...]]]></description> <content:encoded><![CDATA[<p>Voici le troisième épisode de la série de questions/réponses échangées lors de <a
href="http://blog.xebia.fr/2011/11/10/soiree-cloud-avec-sacha-labourey-ceo-and-founder-cloudbees" rel="nofollow">la soirée Cloud</a> organisée par <a
href="http://blog.xebia.fr/author/cleclerc" rel="nofollow">Cyrille Leclerc</a> avec <a
href="http://www.cloudbees.com/company-team.cb">Sacha Labourey</a>.</p><div
align="center"> <iframe
src="http://player.vimeo.com/video/34106427?color=6d0091" width="600" height="338" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></div><hr/> <strong>Tous les podcasts Xebia France :</strong></p><ul><li><a
href="itpc://blog.xebia.fr/feed/podcast/" title="Subscribe to the Podcast Feed with iTunes"><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/itunes.png" class="podpress_feed_buttons" alt="Subscribe with iTunes"></a></li><li><a
href="http://blog.xebia.fr/feed/podcast/" title="Les podcasts de Xebia France vous permettent de suivre l'actualité autour de Java, de l'agilité, des technologies Web et bien d'autres. Xebia France est une entreprise spécialisée dans les technologies Java et JEE en environnement agile."><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/feed_button-rss-podcast.png" class="podpress_feed_buttons" alt="Xebia France Podcast Feed"></a></li></ul><p><strong>Les vidéos de la soirées :</strong></p><ul><li><a
href="http://blog.xebia.fr/2011/12/08/video-de-la-presentation-de-sacha-labourey-sur-le-cloud/">Vidéo de la présentation de Sacha Labourey sur le Cloud</li><li><a
href="http://blog.xebia.fr/2011/12/16/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-1/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 1</li><li><a
href="http://blog.xebia.fr/2011/12/22/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-2/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 2</li><li><a
href="http://blog.xebia.fr/2012/01/05/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-3/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 3</li><li><a
href="http://blog.xebia.fr/2012/01/23/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-le-clerc-episode-4/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 4</li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/05/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-3/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <enclosure
url="http://xebia-video.s3-website-eu-west-1.amazonaws.com/2012-01-qr-cloud-labourey-le-clerc-ep3.mp4" length="272980141" type="audio/mpeg" /> <itunes:duration>0:30:39</itunes:duration> <itunes:subtitle>Voici le troisième épisode de la série de questions/réponses échangées lors de la soirée Cloud organisée par Cyrille Leclerc avec Sacha Labourey.
Tous les podcasts Xebia France :
Les vidéos de la soirées :
Vidéo de la présentation de Sacha [...]</itunes:subtitle> <itunes:summary>Voici le troisième épisode de la série de questions/réponses échangées lors de la soirée Cloud organisée par Cyrille Leclerc avec Sacha Labourey.
Tous les podcasts Xebia France :
Les vidéos de la soirées :
Vidéo de la présentation de Sacha Labourey sur le Cloud
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 1
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 2
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 3
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 4 </itunes:summary> <itunes:author>Xebia France</itunes:author> <itunes:explicit>no</itunes:explicit> <itunes:block>no</itunes:block> </item> <item><title>2 Février : Xebia accueille le CEO de 10Gen pour un Mongo Day</title><link>http://blog.xebia.fr/2012/01/04/2-fevrier-xebia-accueille-le-ceo-de-10gen-pour-un-mongo-day/</link> <comments>http://blog.xebia.fr/2012/01/04/2-fevrier-xebia-accueille-le-ceo-de-10gen-pour-un-mongo-day/#comments</comments> <pubDate>Wed, 04 Jan 2012 08:17:36 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Cloud / NoSQL]]></category> <category><![CDATA[10gen]]></category> <category><![CDATA[Grails]]></category> <category><![CDATA[java]]></category> <category><![CDATA[MongoDB]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Play!]]></category> <category><![CDATA[scala]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10188</guid> <description><![CDATA[Xebia a le plaisir d&#8217;organiser un Paris Mongo Day avec Dwight Merriman et 10gen le 2 Février ! 09h30 &#8211; 11h30 : Rencontrez Dwight Merriman, CEO de 10Gen Venez rencontrer le CEO d&#8217;une des startups les plus en vue du monde NoSQL. 09h30 &#8211; 11h00 : présentation de l&#8217;univers NoSQL par Dwight Merriman, suivie d&#8217;une [...]]]></description> <content:encoded><![CDATA[<p><span
style="display: block; text-align: center"><img
src="http://blog.xebia.fr/wp-content/uploads/2012/01/mongodb-10gen.png" style="border: 0px solid black" /></span></p><p>Xebia a le plaisir d&#8217;organiser un Paris Mongo Day avec <a
href="http://www.10gen.com/team" rel="nofollow">Dwight Merriman</a> et <a
href="http://www.10gen.com/" rel="nofollow">10gen</a> le 2 Février !</p><h3><a
name="DRAFT-2F%C3%A9vrier-XebiaaccueilleleCEOde10GenpourunMongoDay%21-09h3011h30%3ARencontrezDwightMerriman%2CCEOde10Gen"></a>09h30 &#8211; 11h30 : Rencontrez Dwight Merriman, CEO de 10Gen</h3><p><img
src="http://blog.xebia.fr/wp-content/uploads/2012/01/team-dwight-merriman.jpg" style="border: 0px solid black; margin: 1em 1em 1em 1em; float: right;" /></p><p>Venez rencontrer le CEO d&#8217;une des startups les plus en vue du monde NoSQL.</p><ul><li>09h30 &#8211; 11h00 : présentation de l&#8217;univers NoSQL par <a
href="https://twitter.com/#!/dmerr" rel="nofollow">Dwight Merriman</a>, suivie d&#8217;une session de questions/réponses avec l&#8217;auditoire préparée et modérée par <a
href="http://blog.xebia.fr/author/jlmorlhon/" rel="nofollow">Jean-Laurent de Morlhon</a>.</li><li>11h00 &#8211; 11h30 : petit déjeuner pour faire connaissance avec l&#8217;équipe 10gen.</li></ul><p><em>Inscriptions pour la rencontre avec Dwight Merriman de 9h30 à 11h30 </em><em><a
href="http://www.10gen.com/events/meet-the-ceo---dwight-merriman-ceo-and-co-founder-of-mongodb" rel="nofollow">ici</a></em><em>.</em></p><h3><a
name="DRAFT-2F%C3%A9vrier-XebiaaccueilleleCEOde10GenpourunMongoDay%21-11h3018h00%3AMongoDBdud%C3%A9v%C3%A0laprod"></a>11h30 &#8211; 18h00 : Mongo DB du dév à la prod</h3><p>De 11h30 à 18h30, 2 tracks MongoDB en parallèle autour du développement, de l&#8217;exploitation et des retours d&#8217;expérience <em>(</em><em>)</em>.</p><ul><li><b>MONGO</b> <em>(track commune)</em><ul><li>La roadmap de MongoDB par <a
href="https://twitter.com/#!/dmerr" rel="nofollow">Dwight Merriman</a>, CEO de 10gen.</li><li>Les internes de MongoDB par 10gen.</li></ul></li></ul><ul><li><b>DEV</b><ul><li>MongoDB en <b>Java</b> par <a
href="http://blog.xebia.fr/author/karesti/" rel="nofollow">Katia Aresti</a> <em>(90 mins)</em>.</li><li>MongoDB avec <b>Play! Framework</b> par <a
href="http://www.parisjug.org/xwiki/bin/view/Speaker/BortGuillaume" rel="nofollow">Guillaume Bort</a> <em>(60 mins)</em>.</li><li>MongoDB en <b>Scala</b> par <a
href="http://blog.xebia.fr/author/omichallat/" rel="nofollow">Olivier Michallat</a> <em>(60 mins)</em>.</li><li>MongoDB avec <b>Grails</b> par <a
href="http://blog.xebia.fr/author/amaury/" rel="nofollow">Aurélien Maury</a> <em>(60 mins)</em>.</li><li>MongoDB en <b>PHP</b> par <a
href="https://twitter.com/#!/theodo" rel="nofollow">Fabrice Bernhard</a> <em>(60 mins)</em>.</li></ul></li></ul><ul><li><b>OPS</b><ul><li>Partir en production avec MongoDB par <a
href="http://www.linkedin.com/in/alvinrichards" rel="nofollow">Alvin Richard</a> (10Gen) : <em>mise en place, monitoring, backups, haute disponibilité, support, &#8230;</em></li><li>MongoDB vs. MySQL vu par des DevOps par <a
href="https://twitter.com/#!/octplane" rel="nofollow">Pierre Baillet</a> et <a
href="http://www.linkedin.com/profile/view?id=608546" rel="nofollow">Mathieu Poumeyrol</a> <em>(</em><em><a
href="http://en.wikipedia.org/wiki/Fotopedia" rel="nofollow">fotopedia</a></em><em>)</em>.</li></ul></li></ul><p>Un buffet déjeuner sera offert à 12h30.</p><p><em>Inscriptions pour le Mongo Day 11h30-18h30</em> <em><a
href="http://www.10gen.com/events/discover-mongodb-workshops-with-10gen-and-xebia" rel="nofollow">ici</a></em><em>.</em></p><h3><a
name="DRAFT-2F%C3%A9vrier-XebiaaccueilleleCEOde10GenpourunMongoDay%21-19h0022h00%3AMeetupavecleParisMongoDBUserGroup"></a>19h00 &#8211; 22h00 : Meetup avec le Paris MongoDB User Group</h3><p>De 19h00 à 22h00 Meetup avec le <a
href="http://www.meetup.com/Paris-MongoDB-User-Group/" rel="nofollow">Paris MongoDB User Group</a>, <a
href="https://twitter.com/#!/dmerr" rel="nofollow">Dwight Merriman</a> et toutes les équipes de 10gen.</p><p>Un buffet dinatoire sera offert durant le meetup.</p><p><em>Inscriptions pour le Meetup de 19h00 à 22h00</em> <em><a
href="http://www.meetup.com/Paris-MongoDB-User-Group/" rel="nofollow">ici</a></em><em>.</em></p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/04/2-fevrier-xebia-accueille-le-ceo-de-10gen-pour-un-mongo-day/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2012/01/03/revue-de-presse-xebia-2012-01/</link> <comments>http://blog.xebia.fr/2012/01/03/revue-de-presse-xebia-2012-01/#comments</comments> <pubDate>Tue, 03 Jan 2012 22:06:07 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[Gatling]]></category> <category><![CDATA[Hadoop]]></category> <category><![CDATA[JavaFX]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10176</guid> <description><![CDATA[La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia. Actualité éditeurs / SSII Hadoop 1.0 (par Bertrand Dechoux) JavaFx 2.0.2 inclut dans Java 7u2 (par Romain Schlick) Sortie de Gatling 1.0 (par David Galichet) Actualité éditeurs / SSII Hadoop 1.0 Après six ans de gestation, Hadoop est enfin en 1.0.0! Cette release fut [...]]]></description> <content:encoded><![CDATA[<p><img
src="http://blog.xebia.fr/wp-content/uploads/2007/06/revuedepresse.png" alt="Revue de Presse Xebia" style="margin: 1em 1em 1em 1em; float: right;" /><br
/> <em>La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia.</em></p><p><strong>Actualité  éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2012/01/03/revue-de-presse-xebia-2012-01/#Revuedepresse-Hadoop1.0">Hadoop 1.0</a> <em>(par <a
href="http://blog.xebia.fr/author/bdechoux/">Bertrand Dechoux</a>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/03/revue-de-presse-xebia-2012-01/#Revuedepresse-JavaFx2.0.2inclusdansJava7u2">JavaFx 2.0.2 inclut dans Java 7u2</a> <em>(par <a
href="http://blog.xebia.fr/author/rschlick/">Romain Schlick</a>)</em></li><li><a
href="http://blog.xebia.fr/2012/01/03/revue-de-presse-xebia-2012-01/#Revuedepresse-SortiedeGatling1.0">Sortie de Gatling 1.0</a> <em>(par <a
href="http://blog.xebia.fr/author/dgalichet/">David Galichet</a>)</em></li></ul><h3><a
name="Revuedepresse-Actualit%C3%A9%C3%A9diteurs%2FSSII"></a>Actualité  éditeurs / SSII</h3><h4><a
name="Revuedepresse-Hadoop1.0"></a>Hadoop 1.0</h4><p>Après six ans de gestation, Hadoop est enfin en 1.0.0! Cette release fut réalisée à partir de la version 0.20-security. On notera que:</p><ul><li><a
href="http://web.mit.edu/kerberos/www/" rel="nofollow">Kerberos </a> peut être utilisé pour contrôler les accès;</li><li><a
href="http://hortonworks.com/webhdfs-%E2%80%93-http-rest-access-to-hdfs/" rel="nofollow">webhdfs, une API Rest sécurisée</a> permet un accès plus simple à HDFS;</li><li>l&#8217;accès aux fichiers locaux par <a
href="http://hbase.apache.org/" rel="nofollow">HBase </a> est plus performant.</li></ul><p>Diverses améliorations de performance, corrections de bug et fonctionnalités font également partie de cette mouture, dont le détail se trouve dans les <a
href="http://hadoop.apache.org/common/docs/r1.0.0/releasenotes.html" rel="nofollow">notes de release</a>.</p><h4><a
name="Revuedepresse-JavaFx2.0.2inclusdansJava7u2"></a>JavaFx 2.0.2 inclut dans Java 7u2</h4><p>Décidément, ça bouge beaucoup du côté de <a
href="http://javafx.com/" rel="nofollow">JavaFx 2</a>. Après une <em>early access release</em> de la version 2.1 <a
href="http://fxexperience.com/2011/12/javafx-2-1-early-access-for-windows-build-06-now-available/" rel="nofollow">sortie récemment</a>, une nouvelle <a
href="http://www.infoq.com/news/2011/12/javafx-java7" rel="nofollow">annonce</a> vient d&#8217;être faite. JavaFx est intégré directement dans la nouvelle version de Java 7 update 2.<br
/> Ainsi, le JDK intègre le SDK de JavaFx, pendant que le JRE intègre son runtime.</p><p>Oracle a toujours l&#8217;intention de rendre open source l&#8217;intégralité de ce projet en l&#8217;intégrant à OpenJDK sous le nom de <a
href="http://openjdk.java.net/projects/openjfx/" rel="nofollow">OpenJFX</a>. Une JSR dédiée devrait même apparaître pour Java SE 9.</p><p>L&#8217;avenir des applications web semble se tourner vers HTML 5. On voit aussi que les RIA tel que Flex ou Silverlight sont en perte de vitesse. On peut se demander si JavaFx n&#8217;arrive pas trop tard ? La réponse serait que JavaFx se destine principalement aux applications desktop, qui ont toujours un rôle à jouer surtout que les API comme Swing ou SWT se font vieillissantes.</p><h4><a
name="Revuedepresse-SortiedeGatling1.0"></a>Sortie de Gatling 1.0</h4><p><a
href="https://github.com/excilys/gatling" rel="nofollow">Gatling</a> est un outil de test de stress (comme <a
href="http://jmeter.apache.org/" rel="nofollow">JMeter</a> ou <a
href="http://tsung.erlang-projects.org/" rel="nofollow">Tsung</a>).</p><p>Gatling est écrit en <a
href="http://www.scala-lang.org/" rel="nofollow">Scala</a>, utilise <a
href="http://www.jboss.org/netty" rel="nofollow">Netty</a> et <a
href="http://akka.io/" rel="nofollow">Akka</a>. Les scénarios de test peuvent être générés à l&#8217;aide d&#8217;un outil (non recommandé), écrits à l&#8217;aide d&#8217;une <a
href="http://en.wikipedia.org/wiki/Domain-specific_language" rel="nofollow">DSL</a> ou encore implémentés directement en Scala. Cette dernière option offre un grand nombre de possibilités comme requêter une base de données pour récupérer des données et constituer des jeux de test par exemple.</p><p>Gatling a été conçu dès le départ comme une solution de test haute performance, ce qui lui permet de simuler un grand nombre de clients tout en consommant peu de ressources. Il comble un défaut souvent reproché à JMeter qui était de consommer parfois plus de ressources que la cible que l&#8217;on souhaite tester.</p><p>Gatling enregistre les différentes sessions de test dans un fichier de log qui est ensuite analysé pour générer une série de graphes montrant les différents temps de réponse (global, par type de requête), les erreurs, les taux de succès etc&#8230; Vous trouverez de plus amples informations dans son <a
href="https://github.com/excilys/gatling/wiki/Basic-Usage" rel="nofollow">aide en ligne</a>.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2012/01/03/revue-de-presse-xebia-2012-01/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Java Puzzler</title><link>http://blog.xebia.fr/2011/12/28/java-puzzler/</link> <comments>http://blog.xebia.fr/2011/12/28/java-puzzler/#comments</comments> <pubDate>Wed, 28 Dec 2011 07:42:37 +0000</pubDate> <dc:creator>Nabil Gasri</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[java]]></category> <category><![CDATA[puzzler]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10163</guid> <description><![CDATA[Avant de commencer l&#8217;année 2012, je vous propose un petit quiz adapté d&#8217;un cas réel. Un programme standalone parse un fichier et insère les données parsées dans une base de données. Le même programme est exécuté dans trois régions différentes à savoir l&#8217;Europe, l&#8217;Amérique et l&#8217;Asie. Les entités persistées ont toutes un champ uid unique. [...]]]></description> <content:encoded><![CDATA[<p>Avant de commencer l&#8217;année 2012, je vous propose un petit quiz adapté d&#8217;un cas réel.</p><p>Un programme standalone parse un fichier et insère les données parsées dans une base de données. Le même programme est exécuté dans trois régions différentes à savoir l&#8217;Europe, l&#8217;Amérique et l&#8217;Asie. Les entités persistées ont toutes un champ uid unique. La valeur de ce champ doit être sous la forme &#8216;E-1234&#8242; ce qui est interprété comme l&#8217;enregistrement n° 1234 d&#8217;Europe. La base de données est la même pour les trois régions.</p><p>Lorsqu&#8217;on lance le programme dans les trois régions en parallèle, une exception est levée, laquelle et pourquoi est-elle levée ?</p><p>La solution sera détaillée sur cette même page dans les jours à venir.</p><p>N.B. certaines parties du code ont été omises pour garder la simplicité.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public class Region {
        public static final char EUROPE = 'E';
        public static final char AMERICA = 'U';
        public static final char ASIA = 'A';
}
public class UIDGenerator {
    private static Map&lt;Character, Integer&gt; ids = new HashMap&lt;Character, Integer&gt;();
        public static String generateRegionUid(char regionCode) {
            Integer lastId = 0;
            if(ids.containsKey(regionCode)) {
                lastId = ids.get(regionCode);
            }
            int nextId = lastId++;
            ids.put(regionCode, nextId);
            return new StringBuilder(regionCode).append('-').append(nextId).toString();
        }
        public static void main(String[] args) {
            String ordersFileName = args[1];
            char region = getRegion(args);
            List&lt;Object&gt; parsedOrders = parseOrder(ordersFileName );
            for(Order order:parsedOrders) {
                order.setUid(UIDGenerator.generateRegionUid(region));
            }
            //persist orders into dataBase.
    }
}
</pre>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/12/28/java-puzzler/feed/</wfw:commentRss> <slash:comments>22</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2011/12/27/revue-de-presse-xebia-2011-53/</link> <comments>http://blog.xebia.fr/2011/12/27/revue-de-presse-xebia-2011-53/#comments</comments> <pubDate>Tue, 27 Dec 2011 08:00:00 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[Ceylon]]></category> <category><![CDATA[MongoDB]]></category> <category><![CDATA[Spring Data]]></category> <category><![CDATA[WebStorm]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10159</guid> <description><![CDATA[La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia. Actualité éditeurs / SSII Ceylon &#171;&#160;Newton&#160;&#187; M1 est disponible WebStorm 3.0 est disponible &#33; Google sera le moteur de recherche par défaut de Firefox pour 3 ans Spring est sur GitHub Sortie de Spring Data Mongo 1.0 Actualité éditeurs / SSII Ceylon &#171;&#160;Newton&#160;&#187; M1 [...]]]></description> <content:encoded><![CDATA[<p><img
src="http://blog.xebia.fr/wp-content/uploads/2007/06/revuedepresse.png" alt="Revue de Presse Xebia" style="margin: 1em 1em 1em 1em; float: right;" /><br
/> <em>La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia.</em></p><p><strong>Actualité  éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2011/12/27/revue-de-presse-xebia-2011-53/#Revuedepresse-Ceylon%22Newton%22M1estdisponible">Ceylon &laquo;&nbsp;Newton&nbsp;&raquo; M1 est disponible</a></li><li><a
href="http://blog.xebia.fr/2011/12/27/revue-de-presse-xebia-2011-53/#Revuedepresse-WebStorm3.0estdisponible%5C%21">WebStorm 3.0 est disponible &#33;</a></li><li><a
href="http://blog.xebia.fr/2011/12/27/revue-de-presse-xebia-2011-53/#Revuedepresse-Googleseralemoteurderecherchepard%C3%A9fautdeFirefoxpour3ans">Google sera le moteur de recherche par défaut de Firefox pour 3 ans</a></li><li><a
href="http://blog.xebia.fr/2011/12/27/revue-de-presse-xebia-2011-53/#Revuedepresse-SpringestsurGitHub">Spring est sur GitHub</a></li><li><a
href="http://blog.xebia.fr/2011/12/27/revue-de-presse-xebia-2011-53/#Revuedepresse-SortiedeSpringDataMongo1.0">Sortie de Spring Data Mongo 1.0</a></li></ul><h3><a
name="Revuedepresse-Actualit%C3%A9%C3%A9diteurs%2FSSII"></a>Actualité  éditeurs / SSII</h3><h4><a
name="Revuedepresse-Ceylon%22Newton%22M1estdisponible"></a>Ceylon &laquo;&nbsp;Newton&nbsp;&raquo; M1 est disponible</h4><p>Ceylon est un langage de programmation fortement et statiquement typé destiné à la JVM, interopérable avec java, concurrent direct de Scala et de Clojure et soutenu par JBoss. <a
href="http://relation.to/Bloggers/Gavin" rel="nofollow">Gavin King</a> (créateur d&#8217;Hibernate et de Seam) et son équipe <a
href="http://ceylon-lang.org/blog/2011/12/20/ceylon-m1-newton/" rel="nofollow">ont annoncé</a> la mise à dispostion de la <a
href="http://ceylon-lang.org/documentation/roadmap/#milestone_1" rel="nofollow">première release officielle de Ceylon</a>. Cette première version executable du langage est dotée de nombreuses fonctionalités :</p><ul><li>Utilisation de classes pour les types primitifs de la JVM</li><li>Inférence des types et du typage des arguments</li><li>Paramètres optionnels avec valeur par défaut</li><li>Argument nommés</li><li>Types intersection, union et type vide</li><li>Typage statique de la valeur <code>null</code> et des séquences vides</li><li>Fonctions imbriquées</li><li>Immutabilité par défault</li><li>&#8230;</li></ul><p>Même s&#8217;il manque encore quelques fonctionnalités présentes dans Java (enums, user-defined annotations et la réflexivité), le langage propose déjà des améliorations dans plusieurs domaines. Ajoutons que ce n&#8217;est que la première version (Milestone 1) et que la liste de fonctionnalités à venir est encore longue. Vous pouvez télécharger <a
href="http://ceylon-lang.org/download/" rel="nofollow">le langage</a> et son <a
href="https://github.com/ceylon" rel="nofollow">code source</a>, ou encore consulter <a
href="http://ceylon-lang.org/documentation/roadmap/" rel="nofollow">la roadmap</a> pour voir toutes les fonctionnalités à venir.</p><p>Sur <a
href="http://groups.google.com/group/ceylon-dev/browse_thread/thread/b8458aa5e4edf33f?pli=1" rel="nofollow">le google group ceylon-dev</a>, Gavin King indique sa volonté de sortir une nouvelle version &laquo;&nbsp;Milestone&nbsp;&raquo; tous les deux mois, jusqu&#8217;à atteindre la M5, qui sera la version 1.0 de Ceylon.</p><p>En même temps que cette première version du langage, <a
href="http://ceylon-lang.org/documentation/ide/" rel="nofollow">un plugin eclipse 3.7</a> en béta a été mis à disposition des curieux.</p><h4><a
name="Revuedepresse-WebStorm3.0estdisponible%5C%21"></a>WebStorm 3.0 est disponible !</h4><p>C&#8217;est au tour de <a
href="http://www.jetbrains.com/" rel="nofollow">JetBrains</a> d&#8217;offrir un joli cadeau de Noël aux amateurs de JavaScript !</p><p><a
href="http://www.jetbrains.com/webstorm/index.html" rel="nofollow">WebStorm</a>, un IDE JavaScript basé sur IDEA IntelliJ, est désormais disponible en v3.0 avec de nombreuses améliorations :</p><ul><li>Validation et mode debug des fichiers javascript pour <a
href="http://nodejs.org/" rel="nofollow">Node.js</a></li><li>Vérification de la qualité du code intégrée grace à <a
href="http://www.jslint.com/" rel="nofollow">JSLint</a></li><li>Support des tests unitaires via <a
href="http://code.google.com/p/js-test-driver/" rel="nofollow">JsTestDriver</a></li><li>Détection des duplications de code Javascript, CSS et HTML</li><li>Support du langage <a
href="http://coffeescript.org/" rel="nofollow">CoffeeScript</a></li><li>Améliorations du debugger Javascript</li><li>&#8230;</li></ul><p>Contrairement à IntelliJ, il n&#8217;existe pas de version gratuite pour WebStorm. Une version d&#8217;évaluation de 30 jours est néanmoins disponible. Notons que des tarifs réduits sont pratiqués pour la sortie de cette nouvelle mouture.</p><p>JetBrains a également annoncé que la sortie de WebStorm 3.5 se fera au premier trimestre 2012.</p><p>Le langage JavaScript est décidément de plus en plus populaire et incontournable. Nul doute que cette popularité ne s&#8217;estompera pas en 2012, tant le web est un sujet en ébullition.</p><h4><a
name="Revuedepresse-Googleseralemoteurderecherchepard%C3%A9fautdeFirefoxpour3ans"></a>Google sera le moteur de recherche par défaut de Firefox pour 3 ans</h4><p>Le 20 décembre, Mozilla a annoncé que Google sera <a
href="http://blog.mozilla.com/blog/2011/12/20/mozilla-and-google-sign-new-agreement-for-default-search-in-firefox/" rel="nofollow">le moteur de recherche par défaut de Firefox pour 3 ans</a>. Cela fait suite à un accord dont les détails, financiers entre autre, restent bien sur confidentiels. C&#8217;est un événement important, indépendamment du navigateur que vous utilisez. En effet, Mozilla est une fondation à but non lucratif, ce qui n&#8217;est pas le cas des acteurs principaux du marché des navigateurs ou de la recherche : Microsoft, Google, Apple.</p><h4><a
name="Revuedepresse-SpringestsurGitHub"></a>Spring est sur GitHub</h4><p>Cela faisait longtemps que certains projects du framework Spring étaient sur GitHub. Voici <a
href="http://blog.springsource.org/2011/12/21/spring-framework-moves-to-github/" rel="nofollow">l&#8217;annonce officielle</a> dans laquelle SpringSource explique ce mouvement afin d&#8217;être plus proche des contributeurs grâce aux fonctionnalités offertes par GitHub. Cela ne vous empêchera cependant pas de devoir <a
href="https://simerfoxy.appspot.com/support.springsource.com/spring_committer_signup" rel="nofollow">signer un accord</a> pour toutes les contributions &#8216;non triviales&#8217;.</p><h4><a
name="Revuedepresse-SortiedeSpringDataMongo1.0"></a>Sortie de Spring Data Mongo 1.0</h4><p>Utiliser Mongo DB depuis le framework Spring est devenu encore plus facile avec <a
href="http://www.springsource.org/node/3346" rel="nofollow">la sortie de Spring Data Mongo 1.0</a>. Ce cadeau de Noël contient :</p><ul><li>un template, <a
href="http://static.springsource.org/spring-data/data-mongo/docs/current/api/org/springframework/data/mongodb/core/MongoTemplate.html" rel="nofollow">MongoTemplate</a>, pour faciliter les opérations classiques, avec <a
href="http://static.springsource.org/spring-data/data-document/docs/current/reference/html/#mongodb-template-query" rel="nofollow">une API fluide</a> pour vos cas plus complexes;</li><li>un namespace, <a
href="http://static.springsource.org/spring-data/data-document/docs/current/reference/html/#d0e1113" rel="nofollow">mongo</a>, permettant une configuration succinte des instances, de la réplication et du monitoring mais également d&#8217;<a
href="http://static.springsource.org/spring-data/data-document/docs/current/reference/html/#d0e2718" rel="nofollow">enregistrer vos propres converteurs</a> si la <a
href="http://static.springsource.org/spring-data/data-document/docs/current/reference/html/#mapping-chapter" rel="nofollow">configuration du mapping par metadata</a> ne convient pas à votre contexte;</li><li>un support avancé des repositories grace à Spring Data: on notera par exemple le fait qu&#8217;il suffit de <a
href="http://static.springsource.org/spring-data/data-document/docs/current/reference/html/#mongodb.repositories.queries" rel="nofollow">déclarer dans une interface votre requête suivant une convention définie</a> et que le framework se chargera de l&#8217;implementation, qui est &#8216;juste&#8217; une transformation du nom de la méthode;</li><li>le <a
href="http://static.springsource.org/spring-data/data-document/docs/current/reference/html/#d0e3327" rel="nofollow">support de QueryDSL</a> pour ceux qui préféreraient une approche plus <em>type safe</em>;</li><li>un appender vers mongo pour log4j : <a
href="http://static.springsource.org/spring-data/data-document/docs/current/reference/html/#mongodb:logging-configuration" rel="nofollow">MongoLog4jAppender</a>;</li><li>un support pour de la <a
href="http://static.springsource.org/spring-data/data-document/docs/current/reference/html/#mongo.cross.store" rel="nofollow">persistance cross-store</a> JPA + Mongo DB, permettant ainsi de prendre le meilleur du monde relationnel et NoSQL pour vos requêtes.</li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/12/27/revue-de-presse-xebia-2011-53/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Programmation fonctionnelle &#8211; Solution des exercices du XKE de novembre</title><link>http://blog.xebia.fr/2011/12/26/programmation-fonctionnelle-solution-des-exercices-du-xke-de-novembre/</link> <comments>http://blog.xebia.fr/2011/12/26/programmation-fonctionnelle-solution-des-exercices-du-xke-de-novembre/#comments</comments> <pubDate>Mon, 26 Dec 2011 06:20:00 +0000</pubDate> <dc:creator>François Sarradin</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Programmation fonctionnelle]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10038</guid> <description><![CDATA[Lors du XKE du mois de novembre, j&#8217;ai présenté une introduction à la programmation fonctionnelle. Cette présentation fût suivie d&#8217;une partie Hands On où les participants ont pu s&#8217;essayer (parfois dans la douleur, mais toujours dans la bonne humeur) à ce paradigme avec le langage Java. Je vous propose dans cet article un ensemble de [...]]]></description> <content:encoded><![CDATA[<p>Lors du XKE du mois de novembre, j&#8217;ai présenté une introduction à la programmation fonctionnelle. Cette présentation fût suivie d&#8217;une partie <em>Hands On</em> où les participants ont pu s&#8217;essayer (parfois dans la douleur, mais toujours dans la bonne humeur) à ce paradigme avec le langage Java. Je vous propose dans cet article un ensemble de solutions sur les exercices présentés. De quoi occuper vos longues soirées d&#8217;hiver.</p><h3><a
name="2012-12-23-Programmationfonctionnelle-SolutiondesexercicesduXKEdenovembre-HandsOn1%3AFonctionr%C3%A9cursive"></a>Hands On 1 : Fonction récursive</h3><div
style="border: 1px dotted #909090; background: #F0F0F0; margin-left: 20px; margin-right: 20px; padding: 5px; padding-left: 20px; padding-right: 20px;"><p>Programmer une version de la fonction factorielle.</p><pre class="brush: java; gutter: true; title: ; notranslate">
// test unitaire
fact(0) = 1
fact(1) = 1
fact(5) = 120
fact(10) = 3628800
</pre><p>Réaliser cet exercice en Java seulement puis en utilisant l&#8217;interface Function de Guava, dans sa forme récursive simple puis dans sa forme récursive terminale.</p></div><p>Voici l&#8217;implémentation en Java qui suit assez bien la définition mathématique récursive de la fonction factorielle.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public static int factorial(int n) {
    if (n == 0) return 1;
    else return n * factorial(n - 1);
}
</pre><p>Voici l&#8217;équivalent avec Guava qui ressemble beaucoup à l&#8217;implémentation précédente.</p><pre class="brush: java; gutter: true; title: ; notranslate">
Function&lt;Integer, Integer&gt; factorial = new Function&lt;Integer, Integer&gt;() {
    @Override public Integer apply(Integer n) {
        if (n == 0) return 1;
        else return n * apply(n - 1);
    }
};
</pre><p>Pour utiliser la fonction Guava, il suffit de taper :</p><pre class="brush: java; gutter: true; title: ; notranslate">
Integer result = factorial.apply(5);
</pre><p>Passons à la version récursive terminale en Java.</p><pre class="brush: java; gutter: true; title: ; notranslate">
private static int fact(int n, int k) {
    if (n == 0) return k;
    else return fact(n - 1, n * k);
}
public static int factorial(int n) {
    return fact(n, 1);
}
</pre><p>Et l&#8217;équivalent Guava.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public class FactorialFunction implements Function&lt;Integer, Function&lt;Integer, Integer&gt;&gt; {
    @Override
    Function&lt;Integer, Integer&gt; apply(final Integer n) {
        return new Function&lt;Integer, Integer&gt;() {
            @Override
            public Integer apply(Integer k) {
                if (n == 0) return k;
                else return FactorialFunction.this.apply(n - 1).apply(k * n);
            }
        };
    }
}
FactorialFunction fact = new FactorialFunction();
Integer result = fact.apply(5).apply(1); // factorial of 5
</pre><p>La version Guava est étonnement plus complexe au regard de la version Java. Ceci s&#8217;explique par deux difficultés :</p><ol><li>la fonction factorielle récursive terminale prend deux paramètres,</li><li>la fonction factorielle récursive terminale est&#8230; récursive.</li></ol><p>Pour le premier point, il faut savoir que Guava ne définit que des fonctions ne prenant qu&#8217;un seul paramètre en entrée. Pour avoir une fonction prenant en entrée deux paramètres, nous avons alors deux possibilités :</p><ul><li>une fonction qui prend deux paramètres équivaut à une fonction qui prend en paramètre un élément, sachant que cet élément est un couple de valeurs ce qui nous obligerais à créer un type <em>Pair&lt;T1, T2&gt;</em> ou <em>Tuple2&lt;T1, T2&gt;</em>,</li><li>une fonction qui prend deux paramètres équivaut à une fonction qui prend un premier paramètre et retourne une fonction qui prend le paramètre suivant et retourne le résultat final.</li></ul><p>Cette seconde solution s&#8217;appelle la <b><a
href="http://en.wikipedia.org/wiki/Currying" rel="nofollow">curryfication</a></b>. Elle correspond à transformer une fonction de <em>n</em> paramètres en un chaînage de <em>n</em> fonctions prenant chacune un des paramètres et se renvoyant les unes des autres. Ce qui est très utile par exemple pour évaluer partiellement une fonction.</p><p>C&#8217;est la solution choisie ici. Ce qui explique la signature un peu particulière : <code>Function&lt;Integer, Function&lt;Integer, Integer&gt;&gt;</code>. Autrement dit, notre fonction factorielle est une fonction qui prend un entier et retourne une fonction qui prend un autre entier et retourne un nouvel entier en résultat. Pour rappel, l&#8217;interface <em>Function</em> prend deux types en paramètre : le premier correspond au type du paramètre en entrée et le second au type retourné par la fonction.</p><p>Concernant maintenant le fait que la fonction soit récursive en plus du fait que j&#8217;ai choisi d&#8217;utiliser la curryfication, cela nous oblige à nommer explicitement notre fonction, ou plus exactement à définir une classe nommée. Ceci permet d&#8217;utiliser la notation : <code>FactorialFunction.this.apply(...)</code>. Grâce à cette notation, on demande à Java de ne pas faire un appel à la méthode <em>apply()</em> dans laquelle se trouve directement notre instruction, mais plutôt à la méthode <em>apply()</em> de la classe <em>FactorialFunction</em>.</p><h3><a
name="2012-12-23-Programmationfonctionnelle-SolutiondesexercicesduXKEdenovembre-HandsOn2%3AFilter"></a>Hands On 2 : Filter</h3><div
style="border: 1px dotted #909090; background: #F0F0F0; margin-left: 20px; margin-right: 20px; padding: 5px; padding-left: 20px; padding-right: 20px;"><p>On fournit une liste de salaires. Ecrire la méthode HandsOn.lessThan() qui ne conserve que les salaires inférieurs strictement à 3000 en utilisant Iterables.filter().</p><pre class="brush: java; gutter: true; title: ; notranslate">
// test unitaire
Iterable&lt;Double&gt; salaries = Arrays.asList(1000.0, 2000.0, 2500.0, 3000.0, 4000.0);
Iterable&lt;Double&gt; newSalaries = HandsOn.lessThan(3000.0, salaries);
assertThat(newSalaries).containsOnly(1000.0, 2000.0, 2500.0);
</pre></div><p>Cet exercice se résout simplement. À noter, qu&#8217;au vu de la verbosité de Java (et en attendant Java 8), il vaut mieux utiliser une variable intermédiaire avec un nom significatif pour la fonction que de créer la fonction dans l&#8217;appel à la méthode <em>filter()</em>. Ainsi, la lisibilité du code s&#8217;en trouve améliorée.</p><pre class="brush: java; gutter: true; title: ; notranslate">
private Predicate&lt;Double&gt; isLessThan(final double threshold) {
    return new Predicate&lt;Double&gt;() {
        @Override
        public boolean apply(Double salary) {
            return salary &lt; threshold;
        }
    };
}
public static Iterable&lt;Double&gt; lessThan(double threshold, Iterable&lt;Double&gt; salaries) {
    return Iterables.filter(salaries, isLessThan(threshold));
}
</pre><h3><a
name="2012-12-23-Programmationfonctionnelle-SolutiondesexercicesduXKEdenovembre-HandsOn3%3AMap%2FTransform"></a>Hands On 3 : Map / Transform</h3><div
style="border: 1px dotted #909090; background: #F0F0F0; margin-left: 20px; margin-right: 20px; padding: 5px; padding-left: 20px; padding-right: 20px;"><p>On fournit une liste de salaires. Ecrire la méthode HandsOn.increaseSalaries() qui applique une augmentation identique à une liste de salaires en utilisant Iterables.transform() (équivalent de map en Guava).</p><pre class="brush: java; gutter: true; title: ; notranslate">
// test unitaire
Iterable&lt;Double&gt; salaries = Arrays.asList(1000.0, 2000.0, 2500.0, 3000.0, 4000.0);
Iterable&lt;Double&gt; newSalaries = HandsOn.increaseSalaries(salaries, 0.02);
assertThat(newSalaries).containsOnly(1020.0, 2040.0, 2550.0, 3060.0, 4080.0);
</pre></div><p>De même, cet exercice se résout simplement.</p><pre class="brush: java; gutter: true; title: ; notranslate">
private Function&lt;Double, Double&gt; increaseSalary(final double rate) {
    return new Function&lt;Double, Double&gt;() {
        @Override
        public Double apply(Double salary) {
            return salary * (1.0 + rate);
        }
    };
}
public static Iterable&lt;Double&gt; increaseSalaries(Iterable&lt;Double&gt; salaries, double rate) {
    return Iterables.transform(salaries, increaseSalary(rate));
}
</pre><h3><a
name="2012-12-23-Programmationfonctionnelle-SolutiondesexercicesduXKEdenovembre-HandsOn4%3AFold%2FReduce"></a>Hands On 4 : Fold / Reduce</h3><div
style="border: 1px dotted #909090; background: #F0F0F0; margin-left: 20px; margin-right: 20px; padding: 5px; padding-left: 20px; padding-right: 20px;"><p>La fonction fold(list, init, function) n&#8217;existe pas en Guava. Ecrire la fonction fold() et utiliser cette fonction pour calculer une somme de nombres.</p><pre class="brush: java; gutter: true; title: ; notranslate">
// signature
// &lt;T, R&gt; R fold(Iterable&lt;T&gt; values, R init, Function&lt;R, Function&lt;T, R&gt;&gt; function)
// test unitaire
List&lt;Integer&gt; values = Arrays.asList(1, 2, 3);
Integer result = HandsOn.fold(values, 0, sum);
assertThat(result).isEqualTo(6);
</pre></div><p>La fonction <em>fold</em> est en réalité assez simple.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public static &lt;T, R&gt; R fold(Iterable&lt;T&gt; values, R init, Function&lt;R, Function&lt;T, R&gt;&gt; function) {
    return fold(values.iterator(), init, function);
}
public static &lt;T, R&gt; R fold(Iterator&lt;T&gt; values, R init, Function&lt;R, Function&lt;T, R&gt;&gt; function) {
    R result = init;
    while (iterator.hasNext()) {
        result = function.apply(result).apply(iterator.next());
    }
    return result;
}
</pre><p>On aurait pu résoudre l&#8217;exercice avec une structure for-each sur l&#8217;Iterable <em>values</em> passé en paramètre. J&#8217;ai fait le choix d&#8217;avoir une fonction disponible à la fois pour les Iterable et les Iterator.</p><p>Pour le test unitaire, nous avons besoin de la fonction <em>sum</em>. Voici comment la définir :</p><pre class="brush: java; gutter: true; title: ; notranslate">
Function&lt;Integer, Function&lt;Integer, Integer&gt;&gt; sum = new Function&lt;Integer, Function&lt;Integer, Integer&gt;&gt;() {
    @Override
    public Function&lt;Integer, Integer&gt; apply(final Integer a) {
        return new Function&lt;Integer, Integer&gt;() {
            @Override
            public Integer apply(Integer b) {
                return a + b;
            }
        };
    }
};
</pre><h3><a
name="2012-12-23-Programmationfonctionnelle-SolutiondesexercicesduXKEdenovembre-HandsOn5%3AZip"></a>Hands On 5 : Zip</h3><div
style="border: 1px dotted #909090; background: #F0F0F0; margin-left: 20px; margin-right: 20px; padding: 5px; padding-left: 20px; padding-right: 20px;"><p>Écrire la fonction HandsOn.zipWith(function, list1, list2) qui fusionne deux listes en se basant sur une fonction.</p><pre class="brush: java; gutter: true; title: ; notranslate">
// signature
// &lt;T1, T2, R&gt; Iterable&lt;R&gt; zipWith(Function&lt;T1, Function&lt;T2, R&gt;&gt; function, Iterable&lt;T1&gt; list1, Iterable&lt;T2&gt; list2)
// test unitaire
Iterable&lt;Integer&gt; result = zipWith(sum, Arrays.asList(1, 2), Arrays.asList(3, 4, 6));
assertThat(result).containsExactly(4, 6);
</pre></div><p>Voici l&#8217;implémentation de la fonction <em>zipWith</em> à la fois pour les Iterable et les Iterator.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public static &lt;T1, T2, R&gt; Iterable&lt;R&gt; zipWith(Function&lt;T1, Function&lt;T2, R&gt;&gt; function, Iterable&lt;T1&gt; list1, Iterable&lt;T2&gt; list2) {
    return new Iterable&lt;R&gt;() {
        @Override
        public Iterator&lt;R&gt; iterator() {
            return zipWith(function, list1.iterator(), list2.iterator());
        }
    };
}
public static &lt;T1, T2, R&gt; Iterator&lt;R&gt; zipWith(Function&lt;T1, Function&lt;T2, R&gt;&gt; function, Iterator&lt;T1&gt; iterator1, Iterator&lt;T2&gt; iterator2) {
    return new AbstractIterator&lt;R&gt;() {
        @Override
        protected R computeNext() {
            if (!(iterator1.hasNext() &amp;&amp; iterator2.hasNext())) {
                return endOfData();
            }
            return function.apply(iterator1.next()).apply(iterator2.next());
        }
    }
}
</pre><p>On voit ici l&#8217;utilisation de la classe <em>AbstractIterator</em> qui simplifie l&#8217;écriture d&#8217;instances d&#8217;Iterator. On voit aussi comment utiliser la méthode <em>endOfData()</em> pour marquer la fin du flux. La fonction <em>sum</em> qui apparaît dans le test unitaire est exactement la même que la fonction <em>sum</em> de l&#8217;exercice précédent.</p><h3><a
name="2012-12-23-Programmationfonctionnelle-SolutiondesexercicesduXKEdenovembre-HandsOn6%3AListed%27entiersinfinisavecGuava"></a>Hands On 6 : Liste d&#8217;entiers infinis avec Guava</h3><div
style="border: 1px dotted #909090; background: #F0F0F0; margin-left: 20px; margin-right: 20px; padding: 5px; padding-left: 20px; padding-right: 20px;"><p>Écrire la méthode HandsOn.enumPositiveInts() qui retourne un Iterable&lt;Integer&gt; contenant tous les entiers à partir de 0 jusqu&#8217;à l&#8217;infini. Vous écrirez cette méthode est utilisant la classe AbstractIterator mise à disposition par Guava.</p><pre class="brush: java; gutter: true; title: ; notranslate">
// test unitaire
Iterable&lt;Integer&gt; fiveInts = Iterables.limit(HandsOn.enumPositiveInts(), 5);
assertThat(fiveInts).containsExactly(0, 1, 2, 3, 4);
Iterable&lt;Integer&gt; fiveNextInts = Iterables.limit(Iterables.skip(HandsOn.enumPositiveInts(), 5), 5);
assertThat(fiveInts).containsExactly(5, 6, 7, 8, 9);
</pre></div><p>On peut caractériser la notion de suite infinie avec un Iterator.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public static Iterable&lt;Integer&gt; enumPositiveInts() {
    return new Iterable&lt;Integer&gt;() {
        @Override
        public Iterator&lt;Integer&gt; iterator() {
            return new AbstractIterator&lt;Integer&gt;() {
                private int nextValue = 0;
                @Override
                protected Integer computeNext() {
                    int current = nextValue;
                    nextValue++;
                    return current;
                }
            };
        }
    };
}
</pre><p>On peut voir que &laquo;&nbsp;l&#8217;infini&nbsp;&raquo; est représenté par le fait que nous ne faisons pas appel à la méthode <em>endOfData()</em>.</p><h3><a
name="2012-12-23-Programmationfonctionnelle-SolutiondesexercicesduXKEdenovembre-HandsOn7%3AFibonnaccisousformedelisteinfinie"></a>Hands On 7 : Fibonnacci sous forme de liste infinie</h3><div
style="border: 1px dotted #909090; background: #F0F0F0; margin-left: 20px; margin-right: 20px; padding: 5px; padding-left: 20px; padding-right: 20px;"><p>Écrire la fonction HandsOn.fibs() qui retourne une liste infinie contenant la suite de Fibonnacci.</p><pre class="brush: java; gutter: true; title: ; notranslate">
// test unitaire
assertThat(Iterable.limit(HandsOn.fibs(), 8)).containsExactly(0, 1, 1, 2, 3, 5, 8, 13);
</pre></div><p>Cette exercice ressemble au précédent, sauf qu&#8217;il faut pouvoir conserver les deux étapes précédentes.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public static Iterable&lt;Integer&gt; fibs() {
    return new Iterable&lt;Integer&gt;() {
        @Override
        public Iterator&lt;Integer&gt; iterator() {
            return fibIterator();
        }
    }
}
public static Iterator&lt;Integer&gt; fibIterator() {
    return new AbstractIterator&lt;Integer&gt;() {
        private int a = 0;
        private int b = 1;
        @Override
        protected Integer computeNext() {
            int result = a;
            a = a + b;
            b = result;
            return result;
        }
    }
}
</pre><p>Il faut savoir que cette façon d&#8217;écrire la <a
href="http://fr.wikipedia.org/wiki/Suite_de_Fibonacci" rel="nofollow">suite Fibonnacci</a> est très efficace par rapport à la version connue utilisant une double récursivité (fib(n) = fib(n-1) + fib(n-2)). La version ci-dessus est complètement linéaire et la récupération de l&#8217;élément suivant ne nécessite pas d&#8217;explorer une arborescence.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/12/26/programmation-fonctionnelle-solution-des-exercices-du-xke-de-novembre/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Legacy code &#8211; gestion des exceptions avec Java Instrumentation</title><link>http://blog.xebia.fr/2011/12/23/legacy-code-gestion-des-exceptions-avec-java-instrumentation/</link> <comments>http://blog.xebia.fr/2011/12/23/legacy-code-gestion-des-exceptions-avec-java-instrumentation/#comments</comments> <pubDate>Fri, 23 Dec 2011 12:30:00 +0000</pubDate> <dc:creator>Nabil Gasri</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[exception]]></category> <category><![CDATA[Instrumentation]]></category> <category><![CDATA[Legacy code]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10134</guid> <description><![CDATA[Dans un récent billet, je vous ai présenté JPDA afin de résoudre le problème d’envoi de mail à l’interception des exceptions levées dans une application legacy. Dans cette deuxième partie de la série, je vous propose de résoudre le même problème avec l’API Java Instrumentation. Java Instrumentation L’API instrumentation a vu le jour avec Java [...]]]></description> <content:encoded><![CDATA[<p>Dans un récent <a
href="http://blog.xebia.fr/2011/12/12/legacy-code-gestion-des-exceptions-avec-jpda/" rel="nofollow">billet</a>, je vous ai présenté JPDA afin de résoudre le problème d’envoi de mail à l’interception des exceptions levées dans une application legacy. Dans cette deuxième partie de la série, je vous propose de résoudre le même problème avec l’API Java Instrumentation.</p><h2><a
name="DRAFT-Legacycode-gestiondesexceptionsavecJavaInstrumentation-JavaInstrumentation"></a>Java Instrumentation</h2><p>L’API instrumentation a vu le jour avec Java 5. Elle décrit le mécanisme de manipulation du byte-code utilisé par les outils d’analyse, afin de collecter des données relatives à l’exécution des programmes. Avant la version 5 de Java, les programmes utilisaient d’autres techniques pour analyser les programmes pendant leur exécution, notamment JPDA (présentée dans le précédent article). L’instrumentation est réalisée avec les &laquo;&nbsp;agents&nbsp;&raquo; Java. Un agent est un programme Java qui se déploie sous forme d’un jar. Il est lancé au démarrage de la JVM en ajoutant l’option &laquo;&nbsp;-javaagent:cheminAgent=options&nbsp;&raquo; à la ligne de commande (on remarquera au passage la similarité avec le lancement de JPDA). &laquo;&nbsp;cheminAgent&nbsp;&raquo; est le chemin pointant vers le jar de l’agent et &laquo;&nbsp;options&nbsp;&raquo; la liste des arguments sous forme d’une seule chaine de caractères.<br
/> Pour qu&#8217;il soit valide, l’agent doit contenir:</p><ul><li> Une classe qui implémente la méthode <em>premain</em> dont la signature doit être:<pre class="brush: java; gutter: true; title: ; notranslate">
public static void premain(String agentArgs, Instrumentation inst);
</pre><p>ou</p><pre class="brush: java; gutter: true; title: ; notranslate">
public static void premain(String agentArgs);
</pre><p>Cette méthode ressemble à la méthode main d’un programme Java. Elle sera appelée par la JVM au lancement de l’agent en lui fournissant une chaîne de caractères, à analyser par le programme, représentant les options de l’agent et un objet instrumentation. Typiquement, la méthode premain décompose les options et ajoute un ou plusieurs <em>ClassFileTransformer</em> à l&#8217;objet instrumentation.</li><li> Une classe qui implémente <em>ClassFileTransformer</em> : La méthode <em>transform()</em> de la classe sera appelée pour chaque chargement de classe. S’il y a plusieurs transformateurs, ils seront invoqués dans l’ordre dans lequel ils ont été ajoutés. La méthode reçoit parmi ses arguments le byte-code original de la classe, et elle retourne le byte-code après modification s’il y en a eu.</li><li> Un fichier META-INF/MANIFEST.MF : ce fichier doit contenir un attribut <em>Premain-Class</em> désignant le nom complet de la classe qui implémente la méthode premain, et optionnellement un attribut <em>Boot-Class-Path</em> qui référencera les librairies externes. Pour les autres options, le lecteur pourra se référer à la <a
href="http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html" rel="nofollow">spécification</a>.</p></li></ul><h2><a
name="DRAFT-Legacycode-gestiondesexceptionsavecJavaInstrumentation-ExceptionHandlerAgent"></a>ExceptionHandlerAgent</h2><p>Pour résoudre le problème des exceptions Java levées par l’application, nous allons créer notre propre agent <em>ExceptionHandlerAgent</em>. Celui-ci modifiera le byte-code des classes afin de rajouter le traitement des exceptions. Il implémente donc l&#8217;interface <em>ClassFileTransformer.</em> La manipulation du byte-code Java n’est pas chose facile. Elle nécessite une connaissance approfondie du format du byte-code. Heureusement, il existe beaucoup de frameworks (ASM, BCEL, Javassist…) qui rendent cette tâche plus facile. Dans notre exemple, nous allons utiliser la librairie Javassist. Elle nous offre un ensemble de méthodes haut-niveau pour la manipulation du byte-code ainsi qu’un micro-compilateur intégré pour la compilation des petits bouts de code Java. Nous présenterons cette librairie en détail dans un prochain article.</p><p>La méthode premain se contente d’ajouter une nouvelle instance d’<em>ExceptionHandlerAgent</em></p><pre class="brush: java; gutter: true; title: ; notranslate">
public class ExceptionHandlerAgent implements ClassFileTransformer {
    public static void premain(String agentArgument, Instrumentation instrumentation) {
        instrumentation.addTransformer(new ExceptionHandlerAgent());
    }
...
}
</pre><p>La manipulation du byte-code est effectuée dans la méthode <em>transform()</em>, qui est appelée à chaque chargement de classe. Instrumenter les classes de la JVM ne nous intéresse pas et peut même être dangereux. Il en est de même pour les classes des librairies utilisées par l’application. Nous nous intéressons donc uniquement au classes du package <em>fr.xebia</em>.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public byte[] transform(ClassLoader loader, String className, Class&lt;?&gt; classBeingRedefined,
            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        if (className.startsWith(&quot;fr/xebia&quot;)) {
            ClassPool pool = ClassPool.getDefault();
            CtClass cl = null;
            try {
                cl = pool.makeClass(new java.io.ByteArrayInputStream(classfileBuffer));
                if (!cl.isInterface()) {
                    CtBehavior[] methods = cl.getDeclaredBehaviors();
                    for (int i = 0; i &lt; methods.length; i++) {
                        if (!methods[i].isEmpty()) {
                            enrichMethod(cl, methods[i]);
                        }
                    }
                    classfileBuffer = cl.toBytecode();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (cl != null) {
                    cl.detach();
                }
            }
        }
        return classfileBuffer;
    }
</pre><p>Notre but est de traiter les exceptions &laquo;&nbsp;catchées&nbsp;&raquo; et non &laquo;&nbsp;catchées&nbsp;&raquo;. Pour les exceptions non catchées, nous pouvons utiliser <em>Thread.setDefaultUncaughtExceptionHandler(eh)</em>, qu’il suffit d’insérer au début de la méthode <em>main</em>. Javaassist ne permet pas de compiler les classes internes et anonymes, nous allons faire en sorte que la classe contenant la méthode main implémente l&#8217;interface <em>UncaughtExceptionHandler</em>. Il suffit alors de passer une instance de cette classe à la méthode statique <em>setDefaultUncaughtExceptionHandler().</em> Pour les autres exceptions, nous pouvons modifier les clauses <em>catch</em> afin d’insérer le traitement d’exception au début de la clause. C&#8217;est ce qui est fait par la méthode enrichMethod.</p><pre class="brush: java; gutter: true; title: ; notranslate">
private void enrichMethod(CtClass cl, CtBehavior ctBehavior) throws CannotCompileException, NotFoundException {
        if (ctBehavior.getName().equals(&quot;main&quot;)) {
            CtClass eh = ClassPool.getDefault().makeClass(&quot;java.lang.Thread$UncaughtExceptionHandler&quot;);
            cl.addInterface(eh);
            CtMethod m = CtNewMethod.make(&quot;public void uncaughtException(Thread t, Throwable e){System.out.println(\&quot;An Uncaughed exception is thrown\&quot;);e.printStackTrace();}&quot;,cl);
            cl.addMethod(m);
            ctBehavior.insertBefore(&quot;Thread.setDefaultUncaughtExceptionHandler( new &quot; + cl.getName() + &quot;());&quot;);
        }
        ctBehavior.instrument(new ExprEditor() {
            @Override
            public void edit(Handler h) throws CannotCompileException {
                h.insertBefore(&quot;System.out.println(\&quot;Caugh an Exception\&quot;);&quot;);
            }
        });
    }
</pre><h2><a
name="DRAFT-Legacycode-gestiondesexceptionsavecJavaInstrumentation-Conclusion"></a>Conclusion</h2><p>Contrairement à la solution avec JPDA, cette solution n&#8217;ajoute pas d&#8217;overhead à l&#8217;exécution de l&#8217;application. Cependant, le pré-requis de bien comprendre un minimum le format byte-code avant de pouvoir en profiter reste un handicap pour la démocratisation de cette API, qui reste réservée aux développeurs de frameworks. La simplicité de l&#8217;API et la complexité des librairies de manipulation de code font de cette solution une arme à double tranchant.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/12/23/legacy-code-gestion-des-exceptions-avec-java-instrumentation/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Peut-on faire du TDD sur du code existant ?</title><link>http://blog.xebia.fr/2011/12/23/peut-on-faire-du-tdd-sur-du-code-existant/</link> <comments>http://blog.xebia.fr/2011/12/23/peut-on-faire-du-tdd-sur-du-code-existant/#comments</comments> <pubDate>Fri, 23 Dec 2011 06:30:13 +0000</pubDate> <dc:creator>Julien Smadja</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[refactoring]]></category> <category><![CDATA[TDD]]></category> <category><![CDATA[Test-Driven-Development]]></category> <category><![CDATA[Tests unitaires]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10053</guid> <description><![CDATA[Notre quotidien de développeur consiste très souvent à modifier du code existant. Certes, nous avons parfois la chance de développer de nouveaux modules tout frais, tout neufs et le Test Driven Development est à son avantage. Mais comment peut-on mettre en pratique le TDD sur du code déjà écrit, parfois mal pensé et non testé. [...]]]></description> <content:encoded><![CDATA[<p>Notre quotidien de développeur consiste très souvent à modifier du code existant. Certes, nous avons parfois la chance de développer de nouveaux modules tout frais, tout neufs et le Test Driven Development est à son avantage.</p><p>Mais comment peut-on mettre en pratique le TDD sur du code déjà écrit, parfois mal pensé et non testé. Cet article va partir d&#8217;un exemple concret, une classe comme on pourrait en trouver sur tous les projets. Le but est de commencer une démarche TDD et de pousser au maximum son efficacité (mise en évidence d&#8217;un bug potentiel, ajout d&#8217;une nouvelle fonctionnalité, refactoring du code et refactoring des tests). Au final, la classe sera beaucoup plus apte à subir le changement et surtout, elle sera testée et couvrira tous les cas d&#8217;utilisation.</p><h1><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-Aucommencement%C3%A9taitlecodeexistant"></a>Au commencement était le code existant</h1><p>L&#8217;exemple est tiré du site <a
href="http://thedailywtf.com/" rel="nofollow">The Daily WTF</a>. C&#8217;est en regardant la photo ci-dessous que je me suis dit que le code serait un bon candidat au refactoring. Il n&#8217;y a pas de frameworks, de règles de gestion complexes et c&#8217;est pourtant ce genre de code &laquo;&nbsp;simple&nbsp;&raquo; qui peut nous ralentir au quotidien.</p><div
align="center"><img
src="http://blog.xebia.fr/wp-content/uploads/2011/12/wtf.jpg" style="border: 1px solid black" /></div><p>Vous l&#8217;aurez compris, il s&#8217;agit d&#8217;associer des mots que nous appellerons <em>flag</em> à des valeurs booléennes : par exemple <b>ON</b> correspond à <b>true</b>, <b>OFF</b> à <b>false</b>. De plus, les flags peuvent être orthographiés différemment : <b>ON</b>, <b>On</b>, <b>on</b> doivent tous correspondre à <b>true</b>.</p><p>Voici l&#8217;adaptation Java du code legacy ci-dessus. J&#8217;ai introduit la méthode publique <em>asBoolean</em>(), utilisée par le code appelant, renvoyant la valeur booléenne d&#8217;un <em>flag.</em> Si aucun <em>flag</em> ne correspond, la méthode renvoie <b>null</b>.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public class StringSettingBool {
    private Map&lt;String, Boolean&gt; boolFlag = new HashMap&lt;String, Boolean&gt;() {
        {
            put(&quot;NO&quot;, false);
            put(&quot;No&quot;, false);
            put(&quot;no&quot;, false);
            put(&quot;YES&quot;, true);
            put(&quot;Yes&quot;, true);
            put(&quot;yes&quot;, true);
            put(&quot;OFF&quot;, false);
            put(&quot;Off&quot;, false);
            put(&quot;off&quot;, false);
            put(&quot;ON&quot;, true);
            put(&quot;On&quot;, true);
            put(&quot;on&quot;, true);
        }
    };
    public Boolean asBoolean(String flag) {
        if (boolFlag.containsKey(flag)) {
            return boolFlag.get(flag);
        }
        return null;
    }
}
</pre><h1><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-LeCycleTDD"></a>Le Cycle TDD</h1><p>Pour rappel, le TDD consiste en 3 étapes :</p><ol><li>Écrire un test qui échoue</li><li>Écrire le code suffisant pour passer le test</li><li>Refactorer le code</li></ol><div
align="center"><img
src="http://blog.xebia.fr/wp-content/uploads/2011/12/tdd-cycle.png" style="border: 0px solid black" /></div><h2><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-Couverturedulegacy"></a>Couverture du legacy</h2><p>Dans notre cas, nous devons d&#8217;abord écrire une suite de tests couvrant le code déjà écrit avant de pouvoir le modifier (correction d&#8217;anomalie, refactoring, ajout d&#8217;une évolution).</p><p>Voici les tests que j&#8217;ai écrit :</p><pre class="brush: java; gutter: true; title: ; notranslate">
public class StringSettingBoolTest {
    StringSettingBool stringSettingBool = new StringSettingBool();
    @Test
    public void should_be_false_for_no_flag() {
        for (String noFlag : { &quot;NO&quot;, &quot;No&quot;, &quot;no&quot; })
            assertFalse(stringSettingBool.asBoolean(noFlag));
    }
    @Test
    public void should_be_false_for_off_flag() {
        for (String offFlag : { &quot;OFF&quot;, &quot;Off&quot;, &quot;off&quot; })
            assertFalse(stringSettingBool.asBoolean(offFlag));
    }
    @Test
    public void should_be_true_for_yes_flag() {
        for (String yesFlag : { &quot;YES&quot;, &quot;Yes&quot;, &quot;yes&quot; })
            assertTrue(stringSettingBool.asBoolean(yesFlag));
    }
    @Test
    public void should_be_true_for_on_flag() {
        for (String onFlag : { &quot;ON&quot;, &quot;On&quot;, &quot;on&quot; })
            assertTrue(stringSettingBool.asBoolean(onFlag));
    }
    @Test
    public void should_return_null_when_flag_is_null() {
        assertNull(stringSettingBool.asBoolean(null));
    }
    @Test
    public void should_return_null_when_flag_is_unknown() {
        assertNull(stringSettingBool.asBoolean(&quot;garbage&quot;));
    }
    @Test
    public void should_return_null_when_flag_is_empty() {
        assertNull(stringSettingBool.asBoolean(&quot;&quot;));
    }
}
</pre><p>Comme vous pouvez le remarquer, je vérifie simplement les deux règles précédemment citées :</p><ol><li>Les <em>flags</em> doivent correspondre aux valeurs booléennes attendues (yes -&gt; true, no -&gt; false, &#8230;)</li><li>La valeur <b>null</b> doit être retournée en cas d&#8217;utilisation d&#8217;un <em>flag</em> invalide (valeur nulle ou inconnue ou chaîne vide).</li></ol><h2><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-D%C3%A9marrageducycle"></a>Démarrage du cycle</h2><p>Pour les besoins de l&#8217;article, nous imaginerons qu&#8217;un bug a été détecté par l&#8217;équipe QA. L&#8217;application n&#8217;a pas le comportement attendu si la valeur nO est passé en paramètre d&#8217;un formulaire.</p><h3><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-TDD%C3%A9tape1%C3%89crireletestqui%C3%A9choue"></a>TDD étape 1 &#8211; Écrire le test qui échoue</h3><p>Si le <em>flag</em> <b>NO</b> est orthographié <b>nO</b>, la méthode <em>asBoolean()</em> ne renverra pas <b>false</b> mais <b>null</b>. Comme première correction nous pouvons rendre la méthode <em>asBoolean()</em> insensible à la casse.</p><p>Nous faisons du TDD, nous écrirons donc un test qui doit mettre en évidence le bug.</p><pre class="brush: java; gutter: true; title: ; notranslate">
@Test
public void should_be_false_for_no_flag_ignore_case() {
    assertFalse(stringSettingBool.asBoolean(&quot;nO&quot;));
}
</pre><p>Le test échoue, c&#8217;est l&#8217;occasion de toucher au code !</p><h3><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-TDD%C3%A9tape2Fairepasserletest"></a>TDD étape 2 &#8211; Faire passer le test</h3><p>Rien de bien compliqué, nous allons convertir en minuscule le <em>flag</em> reçu en paramètre.</p><pre class="brush: java; gutter: true; title: ; notranslate">
public Boolean asBoolean(String flag) {
        if (flag == null) {
            return null;
        }
        flag = flag.toLowerCase();
        if (boolFlag.containsKey(flag)) {
            return boolFlag.get(flag);
        }
        return null;
    }
</pre><p>Le test est vert, profitons-en pour réduire la quantité de code !</p><h3><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-TDD%C3%A9tape3Refactorer"></a>TDD étape 3 &#8211; Refactorer</h3><p>Depuis que nous utilisons les <em>flags</em> en minuscule, nous pouvons supprimer toutes les insertions superflues. Le code lié à l&#8217;initialisation de la Map est désormais plus concis.</p><pre class="brush: java; gutter: true; title: ; notranslate">
private Map&lt;String, Boolean&gt; boolFlag = new HashMap&lt;String, Boolean&gt;() {
    {
        put(&quot;no&quot;, false);
        put(&quot;yes&quot;, true);
        put(&quot;off&quot;, false);
        put(&quot;on&quot;, true);
    }
};
</pre><h2><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-Nouvellefonctionnalit%C3%A9"></a>Nouvelle fonctionnalité</h2><p>Il devient dorénavant plus simple d&#8217;ajouter un <em>flag</em> comme par exemple <b>start</b>.</p><h3><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-TDD%C3%A9tape1%C3%89crireletestqui%C3%A9choue"></a>TDD étape 1 &#8211; Écrire le test qui échoue</h3><p>On commence par écrire les tests qui couvrent le flag <b>start</b></p><pre class="brush: java; gutter: true; title: ; notranslate">
@Test
public void should_be_true_for_start_flag() {
    String[] startFlags = { &quot;START&quot;, &quot;start&quot;, &quot;Start&quot;, &quot;STart&quot;, &quot;STArt&quot; };
    for (String startFlag : startFlags) {
        assertTrue(stringSettingBool.asBoolean(startFlag));
    }
}
</pre><h3><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-TDD%C3%A9tape2Fairepasserletest"></a>TDD étape 2 &#8211; Faire passer le test</h3><p>Une seule ligne est nécessaire (contre trois dans la version originale) :</p><pre class="brush: java; gutter: true; title: ; notranslate">
put(&quot;start&quot;, true);
</pre><h3><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-TDD%C3%A9tape3Refactorer%2Clestestscettefoisci%5C%21"></a>TDD étape 3 &#8211; Refactorer, les tests cette fois-ci !</h3><p>La batterie de tests ne comporte pas toutes les possibilités d&#8217;écriture des <em>flags</em> (ex: STARt, StArT, STARt, &#8230;). Nous pourrions profiter d&#8217;une fonctionnalité de JUnit permettant de paramétrer l’exécution des tests avec un jeu de données préalablement généré. Ce que nous voulons, c&#8217;est qu&#8217;un test prenne en paramètre un <em>flag</em> et la valeur booléenne attendue en résultat de l&#8217;appel à la méthode <em>asBoolean()</em>. Le jeu de données serait constitué de toutes les combinaisons de casses possibles d&#8217;un <em>flag</em>.</p><pre class="brush: java; gutter: true; title: ; notranslate">
@RunWith(Parameterized.class)
public class StringSettingBoolTest {
    StringSettingBoold stringSettingBool = new StringSettingBool();
    private String flag;
    private boolean expectedBooleanValue;
    public StringSettingBoolTest(String flag, boolean expectedBooleanValue) {
        this.flag = flag;
        this.expectedBooleanValue = expectedBooleanValue;
    }
    @Test
    public void should_return_boolean_value_for_valid_flag() {
        assertEquals(flag + &quot; should be &quot; + expectedBooleanValue, expectedBooleanValue,
                stringSettingBool.asBoolean(flag));
    }
    @Parameters
    public static Collection&lt;Object[]&gt; createDataSet() {
        Collection&lt;Object[]&gt; data = new ArrayList&lt;Object[]&gt;();
        addItem(data, false, &quot;no&quot;, &quot;off&quot;);
        addItem(data, true, &quot;yes&quot;, &quot;on&quot;, &quot;start&quot;);
        return data;
    }
    private final static StringUtil stringUtil = new StringUtil();
    private static void addItem(Collection&lt;Object[]&gt; data, boolean flagBooleanValue, String... flags) {
        for (String flag : flags) {
            Set&lt;String&gt; findAllCases = stringUtil.findAllCases(flag);
            for (String flagName : findAllCases) {
                Object[] item = new Object[2];
                item[0] = flagName;
                item[1] = flagBooleanValue;
                data.add(item);
            }
        }
    }
}
</pre><blockquote><p>Note: J&#8217;ai écrit la classe <b>StringUtil</b> et la méthode <em>findAllCases()</em> pour l&#8217;occasion, en TDD bien entendu. A partir du mot passé en paramètre, la méthode renvoie un Set de tous les combinaisons de casses possibles : start -&gt; start, Start, STart, STArt, staRT, &#8230;</p></blockquote><h1><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-Lesbienfaitsdesrefactoringsuccessifs"></a>Les bienfaits des refactoring successifs</h1><p>Le résultat est obtenu est désormais entièrement testé. De plus, la méthode <em>asBoolean()</em> accepte un paramètre dont la casse n&#8217;est plus importante.<br
/> Il suffit de trois étapes pour ajouter un nouveau <em>flag</em>, les étapes du cycle TDD :</p><p>1. Modifier l&#8217;un des deux appels dans la méthode <em>createDataSet()</em> de la classe de tests paramétrée. Ajoutons par exemple le <em>flag</em> <b>stop</b> en paramètre de la méthode <em>addItem</em>.</p><pre class="brush: java; gutter: true; title: ; notranslate">
addItem(data, false, &quot;no&quot;, &quot;off&quot;, &quot;stop&quot;);
</pre><p>Vérifier que les tests nouvellement générés échouent.</p><p>2. Ajouter le <em>flag</em> <b>stop</b> à la Map dans la classe <b>StringSettingBool</b></p><pre class="brush: java; gutter: true; title: ; notranslate">
private Map&lt;String, Boolean&gt; boolFlag = new HashMap&lt;String, Boolean&gt;() {
    {
        put(&quot;no&quot;, false);
        put(&quot;yes&quot;, true);
        put(&quot;off&quot;, false);
        put(&quot;on&quot;, true);
        put(&quot;start&quot;, true);
        put(&quot;stop&quot;, false);
    }
};
</pre><p>Vérifier que les tests nouvellement générés passent tous.</p><p>3. Refactorer si nécessaire</p><p>Que remarque-t-on ? Ajouter un nouveau <em>flag</em> prend désormais moins d&#8217;une minute ! Les risques d&#8217;erreur sont faibles (plus besoin de penser à ajouter une ligne par combinaison de casse). Le code est pleinement testé !</p><h1><a
name="DRAFT-Peut-onfaireduTDDsurducodeexistant%3F-Conclusion"></a>Conclusion</h1><p>Ce premier billet consacré au TDD sur du code existant s&#8217;achève. Comme vous avez pu le constater, il est possible de se lancer dans l&#8217;apprentissage du TDD en prenant une partie de code peu complexe. Ayez toujours comme objectif d&#8217;avoir un code plus simple, plus court et mieux testé. Une nouvelle fonctionnalité devrait dorénavant être testable et implémentable  plus facilement et plus rapidement.</p><p>Le prochain article sera consacré à l&#8217;extraction de dépendances et à l&#8217;utilisation de bouchons.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/12/23/peut-on-faire-du-tdd-sur-du-code-existant/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc &#8211; Épisode 2</title><link>http://blog.xebia.fr/2011/12/22/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-2/</link> <comments>http://blog.xebia.fr/2011/12/22/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-2/#comments</comments> <pubDate>Thu, 22 Dec 2011 13:30:11 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Cloud / NoSQL]]></category> <category><![CDATA[Tech Events]]></category> <category><![CDATA[cloud]]></category> <category><![CDATA[CloudBees]]></category> <category><![CDATA[Sacha Labourey]]></category> <category><![CDATA[vidéo]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10116</guid> <description><![CDATA[Voici le second épisode de la série de questions / réponses échangées lors de la soirée Cloud organisée par Cyrille Le Clerc avec Sacha Labourey. Tous les podcasts Xebia France : Les vidéos de la soirées : Vidéo de la présentation de Sacha Labourey sur le Cloud Questions-Réponses sur le Cloud avec Sacha Labourey et [...]]]></description> <content:encoded><![CDATA[<p>Voici le second épisode de la série de questions / réponses échangées lors de <a
href="http://blog.xebia.fr/2011/11/10/soiree-cloud-avec-sacha-labourey-ceo-and-founder-cloudbees" rel="nofollow">la soirée Cloud</a> organisée par <a
href="http://blog.xebia.fr/author/cleclerc" rel="nofollow">Cyrille Le Clerc</a> avec Sacha Labourey.</p><div
align="center"> <iframe
src="http://player.vimeo.com/video/33893126?title=0&amp;byline=0&amp;portrait=0&amp;color=800079" width="600" height="338" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></div><hr/> <strong>Tous les podcasts Xebia France :</strong></p><ul><li><a
href="itpc://blog.xebia.fr/feed/podcast/" title="Subscribe to the Podcast Feed with iTunes"><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/itunes.png" class="podpress_feed_buttons" alt="Subscribe with iTunes"></a></li><li><a
href="http://blog.xebia.fr/feed/podcast/" title="Les podcasts de Xebia France vous permettent de suivre l'actualité autour de Java, de l'agilité, des technologies Web et bien d'autres. Xebia France est une entreprise spécialisée dans les technologies Java et JEE en environnement agile."><img
src="http://blog.xebia.fr/wp-content/plugins/podpress/images/feed_button-rss-podcast.png" class="podpress_feed_buttons" alt="Xebia France Podcast Feed"></a></li></ul><p><strong>Les vidéos de la soirées :</strong></p><ul><li><a
href="http://blog.xebia.fr/2011/12/08/video-de-la-presentation-de-sacha-labourey-sur-le-cloud/">Vidéo de la présentation de Sacha Labourey sur le Cloud</li><li><a
href="http://blog.xebia.fr/2011/12/16/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-1/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 1</li><li><a
href="http://blog.xebia.fr/2011/12/22/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-2/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 2</li><li><a
href="http://blog.xebia.fr/2012/01/05/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-3/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 3</li><li><a
href="http://blog.xebia.fr/2012/01/23/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-le-clerc-episode-4/">Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 4</li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/12/22/questions-reponses-sur-le-cloud-avec-sacha-labourey-et-cyrille-leclerc-episode-2/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <enclosure
url="http://xebia-video.s3-website-eu-west-1.amazonaws.com/2011-12-qr-cloud-labourey-le-clerc-ep2.mp4" length="168945574" type="audio/mpeg" /> <itunes:duration>0:31:36</itunes:duration> <itunes:subtitle>Voici le second épisode de la série de questions / réponses échangées lors de la soirée Cloud organisée par Cyrille Le Clerc avec Sacha Labourey.
Tous les podcasts Xebia France :
Les vidéos de la soirées :
Vidéo de la présentation de Sacha [...]</itunes:subtitle> <itunes:summary>Voici le second épisode de la série de questions / réponses échangées lors de la soirée Cloud organisée par Cyrille Le Clerc avec Sacha Labourey.
Tous les podcasts Xebia France :
Les vidéos de la soirées :
Vidéo de la présentation de Sacha Labourey sur le Cloud
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 1
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 2
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 3
Questions-Réponses sur le Cloud avec Sacha Labourey et Cyrille Le Clerc – Épisode 4 </itunes:summary> <itunes:author>Xebia France</itunes:author> <itunes:explicit>no</itunes:explicit> <itunes:block>no</itunes:block> </item> <item><title>Atelier Grails &#8211; Dojo Découverte &#8211; (Ré-édition)</title><link>http://blog.xebia.fr/2011/12/22/atelier-grails-dojo-decouverte-re-edition/</link> <comments>http://blog.xebia.fr/2011/12/22/atelier-grails-dojo-decouverte-re-edition/#comments</comments> <pubDate>Thu, 22 Dec 2011 08:30:00 +0000</pubDate> <dc:creator>Alexis Kinsella</dc:creator> <category><![CDATA[Tech Events]]></category> <category><![CDATA[Atelier]]></category> <category><![CDATA[Grails]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=10010</guid> <description><![CDATA[Alors que la version 2.0 de Grails vient tout juste d&#8217;être publiée, si vous n&#8217;avez pas eu la possibilité de participer à la première édition de l&#8217;atelier, une seconde chance vous est offerte de découvrir ce framework web &#171;&#160;haute productivité&#160;&#187; à travers une réédition de son atelier d&#8217;initiation en mode participatif. Pendant cet atelier nous [...]]]></description> <content:encoded><![CDATA[<p><span
style="float: right"><img
src="http://blog.xebia.fr/wp-content/uploads/2011/12/cXmUZIAv28XIiNgkRiz4RRl21TsGZ5HoGpZw1UITNyV.png" hspace="20" vspace="20" style="border: 0px solid black" /></span><br
/> Alors que la version 2.0 de Grails vient tout juste d&#8217;être publiée, si vous n&#8217;avez pas eu la possibilité de participer à la première édition de l&#8217;atelier, une seconde chance vous est offerte de découvrir ce framework web &laquo;&nbsp;haute productivité&nbsp;&raquo; à travers une réédition de son atelier d&#8217;initiation en mode participatif.</p><p>Pendant cet atelier nous aborderons ensemble :</p><ul><li>le démarrage d&#8217;un projet from scratch avec quelques classes de domaine liées entre elles,</li><li>la mise en place de la sécurité, avec gestion des utilisateurs et des rôles fonctionnels,</li><li>l&#8217;utilisation de JSON et de JQuery pour créer un champ autocomplété en AJAX,</li><li>la mise en place d&#8217;un moteur de recherche full-text sur nos classes de domaine,</li><li>la mise en place d&#8217;un éditeur WYSIWYG (<a
href="http://ckeditor.com/" rel="nofollow">CKEditor</a>),</li><li>plus si affinités (ou plutôt si le timing est bon <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ) : création de taglibs, de plugins, bref : les prolongations dont vous êtes les héros.</li></ul><p>Après une rapide présentation formelle pour cadrer le débat et exposer les concepts de base du framework, c&#8217;est toi, public adoré, qui prendra le clavier. Dans un environnement préparé et sous la houlette d&#8217;un animateur, chaque participant pourra mettre la main à la pâte pour faire avancer le projet.</p><ul><li>Une connaissance du langage Groovy vous assurera une meilleur compréhension mais n&#8217;est pas nécessaire.</li><li>Grails 2.0 servira de support à l&#8217;atelier.</li></ul><p>Cet atelier aura lieu le <b>10 janvier 2012</b> dans les locaux de Xebia au boulevard Haussmann. Vous pouvez dès maintenant vous inscrire sur <a
href="http://xfr-grails-dojo-2.eventbrite.com/" rel="nofollow">Eventbrite</a>.</p><p>Venez nombreux (malheureusement dans la limite des places disponibles)</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/12/22/atelier-grails-dojo-decouverte-re-edition/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> </channel> </rss>
