<?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 &#187; Hibernate</title> <atom:link href="http://blog.xebia.fr/tag/hibernate/feed/" rel="self" type="application/rss+xml" /><link>http://blog.xebia.fr</link> <description>J2EE, Agilité et SOA</description> <lastBuildDate>Wed, 08 Feb 2012 09:23:16 +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, voire 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éger 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>5</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2011/12/06/revue-de-presse-xebia-240/</link> <comments>http://blog.xebia.fr/2011/12/06/revue-de-presse-xebia-240/#comments</comments> <pubDate>Tue, 06 Dec 2011 12:58:35 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[ASF]]></category> <category><![CDATA[Gitblit]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Puppet]]></category> <category><![CDATA[PuppetLabs]]></category> <category><![CDATA[scala]]></category> <category><![CDATA[Subversion]]></category> <category><![CDATA[tools]]></category> <category><![CDATA[Typesafe]]></category> <category><![CDATA[Yammer]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=9707</guid> <description><![CDATA[La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia. Actualité éditeurs / SSII Scala : la saga continue VMWare, Cisco et Google jouent aux marionnettes Le coin de la technique Hibernate et ses performances anti-patterns Gitblit : le nouveau gestionnaire de repositories Git Evénements de notre communauté en France et à l&#8217;étranger L&#8217;Apache [...]]]></description> <content:encoded><![CDATA[<p><img
style="margin: 1em 1em 1em 1em; float: right;" src="http://blog.xebia.fr/wp-content/uploads/2007/06/revuedepresse.png" alt="Revue de Presse Xebia" /><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="#DRAFT-Revuedepresse-Scala%3Alasagacontinue">Scala : la saga continue</a></li><li><a
href="#DRAFT-Revuedepresse-VMWare%2CCiscoetGooglejouentauxmarionnettes">VMWare, Cisco et Google jouent aux marionnettes</a></li></ul><p><strong>Le coin de la technique</strong></p><ul><li><a
href="#DRAFT-Revuedepresse-Hibernateetsesperformancesantipatterns">Hibernate et ses performances anti-patterns</a></li><li><a
href="#DRAFT-Revuedepresse-Gitblit%3AlenouveaugestionnairederepositoriesGit">Gitblit : le nouveau gestionnaire de repositories Git</a></li></ul><p><strong>Evénements de notre communauté en France et à l&#8217;étranger</strong></p><ul><li><a
href="#DRAFT-Revuedepresse-L%27ApacheSoftwareFoundationetSubversion">L&#8217;Apache Software Foundation et Subversion</a></li><li><a
href="#DRAFT-Revuedepresse-Envrac">En vrac</a></li></ul><h3><a
name="DRAFT-Revuedepresse-Actualitééditeurs/SSII"></a>Actualité éditeurs / SSII</h3><h4><a
name="DRAFT-Revuedepresse-Scala:lasagacontinue"></a>Scala : la saga continue</h4><p>Lors de notre précédente revue de presse <a
href="http://blog.xebia.fr/2011/11/29/revue-de-presse-xebia-239#ScalaetlesEJB" rel="nofollow">nous vous avions parlé</a> de l&#8217;article publié par Stephen Colbourne qui expliquait pourquoi il compare Scala aux EJB2. En réponse aux critiques qui l&#8217;accusaient de n&#8217;avoir pas assez utilisé Scala dans la vie réelle, il a <a
href="http://blog.joda.org/2011/11/real-life-scala-feedback-from-yammer.html" rel="nofollow">publié un mail</a> envoyé par <a
href="http://codahale.com/" rel="nofollow">Coda Hale</a> (ingénieur infrastructure chez Yammer) à Donald Fischer (CEO de <a
href="http://typesafe.com/" rel="nofollow">Typesafe</a>) et Martin Odersky (créateur de Scala). Ce mail contient une série de critiques précises contre le langage (complexe, courbe d&#8217;apprentissage importante, forme idiomatique, outils de build immatures, incompatibilité des binaires entre versions majeures et des problèmes de performances de certaines formes fonctionnelles) qui ont amené Yammer à reconsidérer son utilisation.<br
/> Il s&#8217;avère ensuite que le mail est un échange privé dans lequel Coda Hale répondait à une demande de Typesafe sur les points d&#8217;amélioration possibles du langage, il avait été placé dans un gist de github pour relecture et s&#8217;est retrouvé partagé et repris par mégarde. Son contenu finit par être repris de façon générale.<br
/> Finalement, Yammer publie sa <a
href="http://eng.yammer.com/blog/2011/11/30/scala-at-yammer.html" rel="nofollow">position officielle</a> toujours par la plume de Coda Hale. Dans ce communiqué, il indique</p><ul><li>qu&#8217;ils suivent une philosophie très pragmatique, et qu&#8217;ils essayent de nombreux outils pour résoudre leurs problèmes.</li><li>que tous les langages ont des défauts face aux types de problématiques rencontrées chez Yammer</li><li>qu&#8217;ils ont construit plusieurs systèmes impressionnants avec Scala (gestion de centaines de milliers d&#8217;utilisateurs, de millions de recherches, etc avec des performance très élevées).</li><li>que Scala est un langage encore jeune (il le compare à java 1.3) et qu&#8217;il est normal qu&#8217;il ait encore quelques bords à arrondir, que c&#8217;était justement le sens de la démarche de Typesafe.</li></ul><p>En retrait de l&#8217;agitation, Martin Odersky adresse indirectement une partie des problèmes remontés lors de cette controverse dans <a
href="http://blog.typesafe.com/getting-down-to-work" rel="nofollow">un article publié sur le blog de Typesafe</a>. Quelques points intéressants</p><ul><li>Support au développement avec l&#8217;annonce de la sortie en release candidate de <a
href="http://download.scala-ide.org/" rel="nofollow">scala IDE</a></li><li>Courbe d&#8217;apprentissage réduite d&#8217;une part par l&#8217;IDE, par des sources gratuites dont un site de <a
href="http://docs.scala-lang.org/" rel="nofollow">documentation collaboratif </a>et pour le reste par des formations.</li><li>Accélération du compilateur et soutient au travail accompli dans le compilateur incrémental de SBT.</li><li>Community avec surtout le <a
href="https://github.com/scala/scala" rel="nofollow">passage de Scala sous github</a></li></ul><p>Il évoque également la performance, les frameworks (avec akka, et play2), les plans pour répondre aux problèmes de compatibilité binaire.</p><p>La bataille fait rage pour décider du langage qui remplacera Java sur la JVM, bataille qui ne manquera pas de s&#8217;amplifier avec les fonctionnalités annoncées pour Java 8 (Jigsaw, Lambda expressions, le reste du projet Coin, &#8230;) et l&#8217;arrivée de nouveaux challengers annoncés ces derniers temps (<a
href="http://blog.jetbrains.com/kotlin/" rel="nofollow">Kotlin</a> et <a
href="http://ceylon-lang.org/" rel="nofollow">Ceylon</a>)</p><h4><a
name="DRAFT-Revuedepresse-VMWare,CiscoetGooglejouentauxmarionnettes"></a>VMWare, Cisco et Google jouent aux marionnettes</h4><p><a
href="http://puppetlabs.com/" rel="nofollow">PuppetLabs</a>, l&#8217;entreprise commerciale derrière l&#8217;outil Open source Puppet vient d&#8217;annoncer <a
href="http://puppetlabs.com/blog/company/vmware-google-and-cisco-invest-in-puppet-labs/" rel="nofollow">sur son blog</a> que VMWare, Cisco et Google venaient de prendre des parts lors du dernier tour de table effectué par la société. En dehors du blabla marketing d&#8217;une telle annonce, il faut bien reconnaître que, comme elle le dit, ces partenaires utilisent déjà Puppet &laquo;&nbsp;en production et à grande échelle&nbsp;&raquo;. Et il est certain que cette association en jette !<br
/> En tout cas, il est certain que cette annonce se présente dans une dynamique très porteuse pour les outils de management de configuration. Avec le Cloud, la tendance à prendre en compte le Devops <a
href="http://blog.loof.fr/2011/10/puppet-vs-chef-fight.html" rel="nofollow">se confirme</a> et c&#8217;est toute l&#8217;industrie qui va en bénéficier.<br
/> Rappelons que PuppetLabs édite aussi la solution commerciale <a
href="http://puppetlabs.com/puppet/puppet-enterprise/" rel="nofollow">Puppet Enterprise</a> sortie il y a peu en version 2.0. Et pour ceux que ça intéresse, notons que <a
href="http://java.dzone.com/articles/puppet-editing-pro" rel="nofollow">ce récent article</a> donne des pistes pour optimiser ses éditeurs texte et parle même de Geppetto, un IDE basé sur Eclipse pour Puppet.</p><h3><a
name="DRAFT-Revuedepresse-Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="DRAFT-Revuedepresse-Hibernateetsesperformancesantipatterns"></a>Hibernate et ses performances anti-patterns</h4><p>Pour ceux qui n&#8217;ont pas encore vu cette présentation de Patrycja Wegrzynowic à Devoxx, Mathilde Lemée <a
href="http://www.java-freelance.fr/java/hibernate-anti-patterns" rel="nofollow">en reparle ici</a>. Cet article détaillé revient avec des exemples précis sur des cas d&#8217;utilisation réel de l&#8217;outil. On y retrouve les exemples de N+1 SELECT, de problème de synchronisation en écriture et bien d&#8217;autres.<br
/> L&#8217;accroche de la présentation à Devoxx est simple &laquo;&nbsp;I do think Hibernate is a great tool&nbsp;&raquo;. De plus en plus de débats se lèvent sur l&#8217;utilisation de ce framework. Il est évertué par les uns pour son gain de productivité et son utilisation simple mais décrié par les autres pour les contraintes de modélisation qu&#8217;il entraîne et son côté opaque.<br
/> Lors de notre dernier XKE (Xebia Knowledge Exchange), nous avons eu la chance d&#8217;assister à une présentation de <a
href="http://www.retour1024.fr/" rel="nofollow">David Gageot</a> sur la notion d&#8217;outil et de framework. Lors de cette session, il a codé sous nos yeux une application Web simple, sans utiliser de grand framework. L&#8217;idée était de nous amener à nous poser les bonnes questions face aux outils que nous utilisons tous les jours:</p><ul><li>En ai-je vraiment besoin ?</li><li>A quoi sert-il vraiment ?</li><li>Son utilisation m&#8217;amène-t-elle plus de valeurs ajoutées que de contraintes ?</li></ul><p>L&#8217;idée directrice de David était de nous montrer que nous ne sommes pas obligés d&#8217;utiliser des outils très imposants pour des tâches très simples.<br
/> Un outil, à la différence d&#8217;un framework, n&#8217;imposera que peu de contraintes à son utilisateur. Il restreint son périmètre d&#8217;utilisation pour être &laquo;&nbsp;expert&nbsp;&raquo; dans une tâche bien précise. L&#8217;avantage cependant d&#8217;un framework est d&#8217;offrir des guides d&#8217;utilisation, afin d&#8217;assurer une homogénéité au sein de plusieurs projets.<br
/> Il faut savoir adapter l&#8217;outil à la tâche qui lui correspond. Mieux vaut utiliser des outils simples, non intrusifs pour faire correctement ce qui est demandé en se laissant la possibilité de changer plus tard.<br
/> De la même manière, Hibernate est un outil puissant, encore faut-il savoir l&#8217;utiliser correctement. Tous les cas d&#8217;utilisation n&#8217;en on pas l&#8217;utilité. Mais rappelons nous que si nous voulons l&#8217;introduire dans notre projet, apprenons d&#8217;abord à bien l&#8217;utiliser.Tout est une question d&#8217;adaptation. C&#8217;est le coeur de notre métier, comprendre le contexte pour lui apporter la meilleure réponse possible. La réponse universelle n&#8217;existe pas et c&#8217;est cela qui rend notre profession intéressante.</p><h4><a
name="DRAFT-Revuedepresse-"></a></h4><h4><a
name="DRAFT-Revuedepresse-Gitblit:lenouveaugestionnairederepositoriesGit"></a>Gitblit : le nouveau gestionnaire de repositories Git</h4><p><a
href="http://gitblit.com/" rel="nofollow">GitBlit</a> est une application Web Open-Source (licence Apache Software Foundation version 2.0), reposant sur une stack pure Java, et qui a pour objectif de gérer, consulter et héberger des repositories Git. Il utilise pour cela JGit, une implémentation Java du gestionnaire de sources distribué.</p><p>L&#8217;application se présente sous deux modes :</p><ol><li><strong>Gitblit GO</strong> : une solution clé en main basée sur Jetty. Il n&#8217;est pas nécessaire d&#8217;installer un quelconque serveur Web ou même Git lui-même, c&#8217;est l&#8217;option à privilégier si l&#8217;on veut démarrer le plus simplement et rapidement possible. L&#8217;objectif de ce mode est d&#8217;obtenir un serveur fonctionnel avec un minimum de configuration. En effet, un unique fichier texte permet de configurer le serveur et Gitblit. Aussi, un certificat pour communiquer via HTTPS est automatiquement généré pour localhost et un script permet d&#8217;en générer un pour n&#8217;importe quel hostname.</li><li><strong>Gitblit WAR</strong> : si vous utilisez déjà un conteneur de servlets où vous déployer vos différents outils, le mode WAR est à privilégier. Les versions 6, 7 et 8 de Jetty ainsi que les versions 6 et 7 de Tomcat sont supportées. De manière générale, n&#8217;importe quelle implémentation de Servlet 2.5 ou 3.0 devrait fonctionner.</li></ol><p>Gitblit peut être utiliser de différentes manières :</p><ul><li>Comme une simple IHM Web (inspirée de Gitweb) pour consulter les repositories Git sans accès administrateur ou ou gestion de comptes utilisateurs.</li><li>Comme une stack Git complète pour cloner, &laquo;&nbsp;pusher&nbsp;&raquo; et contrôler l&#8217;accès aux repositories.</li><li>Gitblit peut être utiliser sans aucun outil relatif à Git (dont Git lui-même) ou il peut collaborer avec vos outils existants.</li></ul><p>Les administrateurs peuvent gérer les repos et comptes utilisateurs soit via l&#8217;IHM Web, soit via une interface JSON RPC accessible depuis le <a
href="http://code.google.com/p/gitblit/downloads/detail?name=manager-0.7.0.zip" rel="nofollow">Gitblit Manager</a> (une IHM Swing pour gérer les repos Git et administrer un serveur Gitblit de manière distante) ou depuis un outil custom.</p><p>L&#8217;application requière au minimum un JRE/JDK 6.</p><h3><a
name="DRAFT-Revuedepresse-EvénementsdenotrecommunautéenFranceetàl'étranger"></a>Evénements de notre communauté en France et à l&#8217;étranger</h3><h4><a
name="DRAFT-Revuedepresse-L'ApacheSoftwareFoundationetSubversion"></a>L&#8217;Apache Software Foundation et Subversion</h4><p>Ben Collins-Sussman, fondateur du projet Subversion et membre actuelle de l&#8217;Apache Software Foundation, vient donner son point de vue sur un débat qui fait rage : <a
href="http://blog.red-bean.com/sussman/?p=597" rel="nofollow">Pourquoi l&#8217;ASF choisit encore Subversion comme gestionnaire de source</a> ?<br
/> La première réponse apportée par Jim Jagielski, un des leaders de l&#8217;ASF, est de garantir l&#8217;intégrité des projets sur le long terme et ne pas céder aux dernières modes. Ben Collins-Sussman pense lui que l&#8217;ASF est aussi présente pour fournir des protections légales face à l&#8217;utilisation des outils et d&#8217;assurer une cohérence aux long-termes et non seulement sur le software mais aussi sur les membres de la communauté.<br
/> Pour lui ce dernier point est assuré au sein de la fondation avec ces quelques mots &laquo;&nbsp;community over code&nbsp;&raquo;. Les réponses apportées aux différents problèmes des projets se font par consensus et système de vote au sein des projets.<br
/> Cet esprit de communauté et de protection légale est la raison pour laquelle Ben Collins-Sussman défend l&#8217;idée que les projets Apache doivent joindre le Grand Repository Subersion d&#8217;Apache. Mais l&#8217;utilisation de ce dépôt de source ne doit en aucun cas être unique. Certains projets pourraient selon lui utiliser Git et déposer de façon automatisée les sources au sein du Subversion d&#8217;Apache une fois par jour.<br
/> Pour reprendre le titre de son article, entrer dans une communauté, ce n&#8217;est pas être forcé d&#8217;utiliser tous ses outils.</p><h4><a
name="DRAFT-Revuedepresse-Envrac"></a>En vrac</h4><p>Sortie de <a
href="http://search-lucene.com/m/ElBcpJHvZ&amp;subj=+ANNOUNCE+Apache+Lucene+3+5+0+released" rel="nofollow">Lucene 3.5.0 </a>réduisant entre autre de façon significative la consommation mémoire lors de l&#8217;ouverture d&#8217;un IndexReader.</p><p>Sortie de <a
href="http://www.elasticsearch.org/blog/2011/11/29/0.18.5-released.html" rel="nofollow">ElasticSearch 0.18.5</a> comprenant des corrections de bugs mais surtout reprenant Lucene 3.5.0.</p><p>Sortie de <a
href="http://lucene.apache.org/solr/#27+November+2011+-+Solr+3.5.0+Released" rel="nofollow">Solr 3.5.0</a> reprenant également Lucene 3.5.0.</p><p>Sortie de <a
href="http://forum.springsource.org/showthread.php?118523-STS-2-8-1-released" rel="nofollow">SpringSource Tool Suite 2.8.1</a> dont le but principal est de réduire les couts de migrations de m2eclipse à m2e. Il y a d&#8217;ailleurs <a
href="http://forum.springsource.org/showthread.php?116189-STS-2.8.0-and-m2e-FAQ-%28updated-for-STS-2.8.1%29" rel="nofollow">une FAQ intéressante</a> sur m2e fournie par SpringSource (elle est bien sûr applicable aux utilisateurs d&#8217;Eclipse version &laquo;&nbsp;normale&nbsp;&raquo;).</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2011/12/06/revue-de-presse-xebia-240/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2010/12/21/revue-de-presse-xebia-190/</link> <comments>http://blog.xebia.fr/2010/12/21/revue-de-presse-xebia-190/#comments</comments> <pubDate>Tue, 21 Dec 2010 08:30:05 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Hibernate Search]]></category> <category><![CDATA[InnoDB]]></category> <category><![CDATA[JPA]]></category> <category><![CDATA[Lucene]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[Refcard]]></category> <category><![CDATA[Sonar]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=6295</guid> <description><![CDATA[La revue de presse de l’actualité Java/J2EE hebdomadaire proposée par Xebia. Actualité éditeurs / SSII MySQL 5.5 Sonar 2.4 Hibernate Search 3.3 Le coin de la technique Une Refcard sur JPA2 Actualité éditeurs / SSII MySQL 5.5 Après le rachat de MySQL en avril 2009 il y avait des craintes qu’Oracle continue à développer cette [...]]]></description> <content:encoded><![CDATA[<p><img
style="margin: 1em 1em 1em 1em; float: right;" src="http://blog.xebia.fr/wp-content/uploads/2007/06/revuedepresse.png" alt="Revue de Presse Xebia" /></p><p><em>La revue de presse de l’actualité Java/J2EE hebdomadaire proposée par Xebia.</em></p><p><strong>Actualité  éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2010/12/21/revue-de-presse-xebia-190/#MySQL">MySQL 5.5</a></li><li><a
href="http://blog.xebia.fr/2010/12/21/revue-de-presse-xebia-190/#Sonar">Sonar 2.4</a></li><li><a
href="http://blog.xebia.fr/2010/12/21/revue-de-presse-xebia-190/#HibernateSearch">Hibernate Search 3.3</a></li></ul><p><strong>Le coin de la  technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2010/12/21/revue-de-presse-xebia-190/#UneRefcardsurJPA">Une Refcard sur JPA2</a></li></ul><h3><a
name="ActualitditeursSSII"></a>Actualité  éditeurs / SSII</h3><h4><a
name="MySQL"></a>MySQL 5.5</h4><p>Après le rachat de MySQL en avril 2009 il y avait des craintes qu’Oracle continue à développer cette application. Cette nouvelle <a
title="version 5.5" href="http://dev.mysql.com/downloads/mysql/5.5.html">version 5.5</a> devrait rassurer (un peu) les inquiets car elle vient avec un bon nombre d’améliorations (à lire par ailleurs <a
title="cette interview" href="http://www.infoworld.com/d/data-management/oracle-angles-mysql-web-apps-494">cette interview</a> de Monica Kumar, d’Oracle, sur la complémentarité des deux produits). Parmi les points intéressants à noter:</p><ul><li>InnoDB devient le choix par défaut pour le moteur de stockage à la place de MyISAM. Ce dernier n’était pas transactionnel, entre autres <a
title="dfauts" href="http://blogs.sitepoint.com/2010/11/19/mysql-mistakes-php-developers/">défauts</a>, et la plupart des utilisateurs changeaient leur configuration pour InnoDB.</li><li><a
title="meilleur gestion" href="http://dev.mysql.com/doc/refman/5.5/en/smp-improvements.html">meilleur gestion</a> dans l’utilisation des processeurs multi-coeurs dans le cas d’InnoDB</li><li>amélioration des mécanismes de réplication avec à présent un heartbeat entre le maître et les esclaves ainsi qu’un envoi d&#8217;une confirmation lorsque le premier esclave a fini sa réplication (<a
title="rplication semisynchrone" href="http://dev.mysql.com/doc/refman/5.5/en/replication-semisync.html">réplication semi-synchrone</a>).</li><li>un nouveau <em>statement</em> <code>LOAD XML</code> pour charger des données dans un fichier xml.</li><li>il est possible à présent de <em>plugger</em> son système d’authentification, par exemple le LDAP de son entreprise.</li></ul><p>Une liste plus complète des nouvelles fonctionnalités se trouve <a
title="ici" href="http://dev.mysql.com/doc/refman/5.5/en/mysql-nutshell.html">ici</a>. Oracle estime une amélioration de 360% des performances de MySQL comparée à l’ancienne version, à prendre bien sûr avec des pincettes en fonction des différents cas d’utilisation. Sur Windows les chiffres grimpent même jusqu’à 1500% (!) de gain, cette version proposant une meilleure intégration à ce système d’exploitation. Bref cette nouvelle version semble très recommandable.</p><h4><a
name="Sonar"></a>Sonar 2.4</h4><p>La sortie de Sonar 2.4 le <a
title="mois" href="http://www.sonarsource.org/sonar-2-4-in-screenshots/">mois</a> dernier nous avait échappé, profitons d’un rappel d’<a
title="InfoQ" href="http://www.sonarsource.org/sonar-2-4-in-screenshots/">InfoQ</a> cette semaine pour faire un tour des nouveautés:</p><ul><li>Régles d’architecture: une régle consiste à définir des exclusions de référence à un package. Par exemple on peut exclure les packages <code><strong>.web.</strong></code> (couche de présentation) dans les packages <code><strong>.dao.</strong></code> (couche basse  d’accès aux données). On peut aussi exclure des classes de java jugés obsolètes comme <code>Vector</code> ou <code>Hashtable</code>. Parler d’architecture à ce niveau semble un peu exagérer tant les règles sont relativement simple mais ça peut aider à améliorer du code <em>legacy</em>.</li><li>Personnalisation des <em>dashboards</em>: une vue synthétique peuvent être proposés à des chefs de projet ou des <em>managers</em> tandis qu’un développeur utilisera une vue détaillée qui contiendra plus de <em>widgets</em> par exemple. Sonar prévoit par ailleurs d’ajouter de nouvelles <em>widget</em>.</li><li>Un centre de mise à jour des <em>plugins</em>: une page permet à présent de lister les <em>plugins</em> installés, de les mettre à jours, d’en installer d’autres et de vérifier s’il existe une nouvelle version de Sonar.</li><li>Support pour Maven 3.0: cette mise à jour est appréciable. Il est à noter qu’il existe malgrès tout une incompatibilité avec <a
title="Clover" href="http://jira.codehaus.org/browse/SONAR-1985">Clover</a>.</li></ul><p>Dans ce même article, Olivier Gaudin, de l’équipe Sonar, nous informe des prochaines évolutions. Les règles d’architectures devraient se complexifier grâce à l’ajout d’un DSL permettant d’exprimer une règle comme “La couche A ne peut être utiliser que par la couche B et C”. Il identifie également 3 axes pour diminuer sa dette technique: meilleure visibilité de la dynamique d’un projet (ajout ou suppression de violations de certaines règles), une zone de partage d’information pour les revues de code et intégration d’une version légère dans Eclipse pour anticiper avant les <em>commits</em> les éventuelles violations.</p><h4><a
name="HibernateSearch"></a>Hibernate Search 3.3</h4><p>La nouvelle version d’Hibernate Search 3.3 est <a
title="disponible" href="http://in.relation.to/Bloggers/SantaBringsHibernateSearch33">disponible</a>. Elle contient en particulier un nouveau système de requêtes DSL qui permet de faciliter l’écriture des requêtes, Martin Fowler parlera plutôt de <a
title="Fluent Interface" href="http://martinfowler.com/bliki/FluentInterface.html">Fluent Interface</a>. Voici un exemple :</p><pre class="brush: java; title: ; notranslate">
Query luceneQuery = mythQB.keyword()
.onField(&quot;history&quot;)
.andField(&quot;name&quot;)
.boostedTo(5)
.andField(&quot;description&quot;)
.matching(&quot;storm&quot;)
.createQuery();
</pre><p>Ceci allège l’écriture et devrait donc faciliter l’élaboration de requêtes plus complexes.</p><p>Sous le capot, des modifications ont été apportées sur le mécanisme d’envoi de message pour mettre à jour les indexes, améliorant ainsi les performances. De plus ces indexes peuvent également être stockés sur une grille Infinispan (qui appartient à JBoss tout comme Hibernate Search). Pour ne rien gâcher, des nouveaux indicateurs sur les statistiques sont remontés via JMX pour mieux configurer l’outil.</p><p>Enfin Hibernate Search 3.3 est compatible avec Lucene 3.0. Bien que cette dernière version de Lucene contienne des problèmes de rétro-compatibilité, Hibernate Search les masquera. Par ailleurs il supporte le nouveau type <code>@NumericField</code> encore expérimental dans Lucene mais qui améliore beaucoup les performances.</p><h3><a
name="Lecoindelatechnique"></a>Le coin de la  technique</h3><h4><a
name="UneRefcardsurJPA"></a>Une Refcard sur JPA2</h4><p>Mike Keith, <a
title="un expert" href="http://jdc2010.egjug.org/node/2#Mike_Keith">un expert</a> en persistance Java nous avait offert la Refcard &laquo;&nbsp;<a
title="Getting started with JPA" href="http://refcardz.dzone.com/refcardz/getting-started-with-jpa">Getting started with JPA</a>&nbsp;&raquo; en septembre 2008. Il vient de récidiver pour notre plus grand plaisir avec &laquo;&nbsp;<a
title="Whats New in JPA 20" href="http://refcardz.dzone.com/refcardz/whats-new-jpa-20">What&#8217;s New in JPA 2.0</a>&nbsp;&raquo;<br
/> Une Refcard sur JPA est une très bonne idée, car qui n&#8217;a jamais pesté de ne pas savoir immédiatement quelles étaient les bonnes façons d&#8217;annoter ses entités. Entre les annotations <em>provider-specific</em> et &laquo;&nbsp;normalisées JPA&nbsp;&raquo;, il y a en effet souvent de quoi se perdre. En effet, on trouve parfois des pièges comme <code>@Mapkey</code> par exemple qui <a
title="se comporte diffremment" href="http://stackoverflow.com/questions/2327971/how-do-you-map-a-map-in-hibernate-using-annotations#2331068">se comporte différemment</a> selon le fournisseur.</p><p>La première Refcard était, tout comme JPA 1, assez basique et nous rappelait des notions comme les <em>entity managers</em> et les <em>transactions</em> (<em>container-managed</em> ou non) ainsi qu&#8217;une petite référence JPQL pour écrire ses requêtes&#8230;<br
/> Dans la nouvelle mouture, nous retrouvons les apports de JPA2 à la persistance comme par exemple:<br
/> - la suppression des orphelins avec l&#8217;attribut <code>orphanRemoval</code> de <code>@OneToMany</code><br
/> - les nouvelles fonctionnalités de JPQL (tiens, on peut utiliser un &#8216;CASE&#8217;, bon à savoir ! <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> )<br
/> - les requêtes typées pour ceux qui veulent éviter de caster les valeurs de retour</p><p>Et pour ceux désirant renforcer au maximum le typage de leur requêtes à la compilation, les requêtes Criteria <a
title="fortement types" href="http://www.ibm.com/developerworks/java/library/j-typesafejpa/">fortement typées</a> sont évoquées:</p><pre class="brush: java; title: ; notranslate">
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery c = cb.createQuery(Account.class);
Root acct = c.from(Account.class);
c.select(acct).where(cb.equal(acct.get(Account_.name), “Jim Morrison”));
List result = em.createQuery(c).getResultList();
</pre><p>Certes, la façon de générer la classe du metamodèle canonique (le <code>Account_</code> avec l&#8217;underscore bizarre) n&#8217;est pas évoquée et il vous faudra trouver par vous même comment la générer <a
title="avec Hibernate" href="http://docs.jboss.org/hibernate/jpamodelgen/1.0/reference/en-US/html_single/">avec Hibernate</a> ou <a
title="avec EclipseLink" href="http://wiki.eclipse.org/UserGuide/JPA/Using_the_Canonical_Model_Generator_%28ELUG%29">avec EclipseLink</a>. Mais le principe d&#8217;une RefCard est justement de ne pas être exhaustif, mais de donner les clefs pour un survol rapide des possibilités. Se rafraîchir ainsi la mémoire fait généralement beaucoup de bien et cette nouvelle Refcard mérite donc de rejoindre sa grande sœur et de rester en permanence à porté de main.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/12/21/revue-de-presse-xebia-190/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Devoxx &#8211; Les nouveautés d&#8217;Hibernate, une perspective JPA 2</title><link>http://blog.xebia.fr/2010/11/17/devoxx-les-nouveautes-dhibernate-une-perspective-jpa-2/</link> <comments>http://blog.xebia.fr/2010/11/17/devoxx-les-nouveautes-dhibernate-une-perspective-jpa-2/#comments</comments> <pubDate>Wed, 17 Nov 2010 08:40:35 +0000</pubDate> <dc:creator>Romain Maton</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Devoxx]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Hibernate Envers]]></category> <category><![CDATA[Hibernate Search]]></category> <category><![CDATA[Hibernate Spatial]]></category> <category><![CDATA[Hibernate Validator]]></category> <category><![CDATA[JPA 2]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=5898</guid> <description><![CDATA[Nouvelle journée d&#8217;université et, comme dans toute conférence qui se respecte, nous avons droit à une session de mise au point sur les différentes nouveautés de l&#8217;écosystème d&#8217;Hibernate d&#8217;un point de vue JPA 2. La couverture est large : Hibernate Core, Search, Envers, Validator et Spatial. De nombreuses démos nous ont permis de nous familiariser [...]]]></description> <content:encoded><![CDATA[<p>Nouvelle journée d&#8217;université et, comme dans toute conférence qui se respecte, nous avons droit à une session de mise au point sur les différentes <a
href="http://www.devoxx.com/display/Devoxx2K10/What's+new+in+Hibernate++a+JPA+2+perspective" title="nouveauts de lcosystme dHibernate dun point de vue JPA 2" >nouveautés de l&#8217;écosystème d&#8217;Hibernate d&#8217;un point de vue JPA 2</a>.</p><p>La couverture est large : Hibernate Core, Search, Envers, Validator et Spatial. De nombreuses démos nous ont permis de nous familiariser avec ces nouveautés liées à JPA 2.<br
/> La session était animée, comme il se doit, par Emmanuel Bernard. Le code de la session est disponible sur <a
href="https://github.com/emmanuelbernard/hibernateuniversity-devoxx" title="GitHub" >GitHub</a> et ce pour encore une petite semaine.</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/11/devoxx_emmanuel_bernard_live_coding.png" border="0" alt="" /></div><h3><a
name="HibernateCoreORM"></a>Hibernate Core &#8211; ORM</h3><p>Après quelques nouveautés, dont le support de l&#8217;annotation <code>@MapsId</code> de JPA 2, le partial generator <em>(pour générer une clé selon un algorithme spécifique)</em> et le runtime fetch profile <em>(qui définit plusieurs stratégies de fetch)</em>, Emmanuel commence sa première démo et nous présente la nouvelle API Criteria :</p><ul><li>query building API orientée objet,</li><li>type-safe,</li><li>fortement typé,</li><li>avec la possibilité d&#8217;utiliser le méta-modèle statique <em>(par annotation processor)</em>.</li></ul><p>Et c&#8217;est sur ce dernier point qu&#8217;il insistera pendant toutes ses démos. En effet l&#8217;API est construite de telle manière que nous récupérerons des erreurs <em>compile-time</em> si un mauvais méta-modèle ou un mauvais attribut de méta-modèle est défini.</p><p>Concrètement, le méta-modèle est généré par annotation processor. Une fois celui-ci activé dans votre IDE, chaque compilation de fichier lancera le processus de génération des méta-modèles. Par exemple, une classe <code>User</code> aura un méta-modèle associé <code>User_</code> qui contiendra plusieurs attributs statiques reflétant les attributs de la classe. Ainsi, si un attribut change de nom, toutes les requêtes utilisant l&#8217;ancien nom seront en <em>compilation error</em>. Voici un exemple à partir d&#8217;une capture d&#8217;un bout de code lors de cette démo :</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/11/devoxx_hibernate_core.png" border="0" alt="" /></div><p>On remarque ainsi dans les contraintes l&#8217;utilisation de <code>User_.credits</code>, <code>credits</code> étant un attribut de la classe <code>User</code>. On voit dès lors l&#8217;intérêt d&#8217;un tel mécanisme qui justifie ainsi son appellation type-safe et fortement typé. En effet, sur le 3ème exemple, imaginons que  l&#8217;on donne un argument autre que <code>User_.gender</code> mais du même type que <code>gender</code> ; l&#8217;API nous donnera tout de même une erreur de compilation car ce qui est attendu est un <code>Path&lt;Gender&gt;</code> qui ne peut être obtenu qu&#8217;en ayant pris en paramètre un <code>gender</code>. Une fonctionnalité plutôt intéressante donc mais qu&#8217;il convient mieux de voir de ses propres yeux dans un IDE pour bien comprendre la puissance de la chose.</p><p>Cette nouvelle API criteria prend en compte toutes sortes de <code>Joins</code> et <code>Where</code>, les <code>Subquery</code> et les <code>Map</code> et <code>Like</code>. Cette API supporte ainsi tout le JP-QL : collections, maps, aggregation, order by, group by, having count, subselect, &#8230;</p><p>Le lock  mode, qui prévient entre autres des <em>dirty reads</em>,   supporte l&#8217;optimistic et le pessimistic read/write. Le cache de second niveau a été amélioré et Hibernate supporte aussi Infinispan. Enfin, CGLIB se retrouve déprécié et se voit remplacé par Javassist.</p><p>Côté packaging, Hibernate passe de plusieurs modules à un seul core module qui contient Hibernate Annotations, Entitymanager, Envers et l&#8217;ancien Core. De même, tous les modules auront le même numéro de version simplifiant ainsi la gestion des dépendances entre modules <em>(si un module est en 3.6.0, les autres devront l&#8217;être aussi)</em>.</p><h3><a
name="HibernateSearch"></a>Hibernate Search</h3><p>Le point important est une fois de plus l&#8217;API programmatique permettant de faire ses requêtes full text directement telles que :</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/11/devoxx_hibernate_search.png" border="0" alt="" /></div><p>Dans les petits plus : un error handling pour reporter dans un log ou dans une pile, des statistiques avancées, une indexation des valeurs <code>null</code>, des query timeout et bien d&#8217;autres.</p><h3><a
name="HibernateSpatial"></a>Hibernate Spatial</h3><p>Hibernate Spatial est une extension d&#8217;Hibernate permettant de gérer des données géographiques. Il s&#8217;appuie sur le package Java Topology Suite ou <a
href="http://www.vividsolutions.com/jts/jtshome.htm" title="JTS" >JTS</a> pour représenter les données géographiques dans le monde Java.</p><p>Voici ce que rajoute le projet à Hibernate :</p><ul><li>GeometryUserType.</li><li>SpatialRestrictions API.</li><li>HQL Spatial functions.</li><li>SpatialDialectProvider.</li></ul><p>Les bases de données supportées sont les suivantes :</p><ul><li>Oracle Spatial.</li><li>Postgresql/Postgis.</li><li>MySQL.</li><li>Microsoft SQL Server 2008.</li><li>H2 (GeoDB).</li><li>IBM Informatix IDS (en cours).</li><li>IBM DB2 (à planifier).</li></ul><p>Les spatial queries s&#8217;écrivent comme des requêtes criteria normales mais dans le monde spatial. Un exemple tiré du slide :</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/11/devoxx_hibernate_spatial.png" border="0" alt="" /></div><p>A noter que pour l&#8217;instant le projet est un module à part d&#8217;Hibernate 3 mais qu&#8217;il sera packagé dans Hibernate Core en version 4.</p><h3><a
name="HibernateEnvers"></a>Hibernate Envers</h3><p>Comme pour les autres modules, l&#8217;API programmatique est tout de suite mise en avant avec des requêtes Criteria par révision sur les objets :</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2010/11/devoxx_hibernate_envers.png" border="0" alt="" /></div><h3><a
name="HibernateValidator"></a>Hibernate Validator</h3><p>Là encore, l&#8217;API a aussi été remaniée et l&#8217;on peut ainsi appeler directement des méthodes du type <code>.constraint(SizeDef.class).min(1)</code> dans notre requête Criteria <em>(équivalent de l&#8217;annotation @Min)</em>.</p><h3><a
name="Conclusion"></a>Conclusion</h3><p>Un bon tour d&#8217;horizon des produits Hibernate mais surtout beaucoup de démos <em>les mains dedans</em> où l&#8217;on voit le tout fonctionner en @Inject et <a
href="http://seamframework.org/Weld" title="Weld" >Weld</a> sous IntelliJ IDEA. Une bonne session !</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/11/17/devoxx-les-nouveautes-dhibernate-une-perspective-jpa-2/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2010/08/24/revue-de-presse-xebia-173/</link> <comments>http://blog.xebia.fr/2010/08/24/revue-de-presse-xebia-173/#comments</comments> <pubDate>Tue, 24 Aug 2010 05:29:57 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[ActiveMQ]]></category> <category><![CDATA[CGLIB]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[WebSocket]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=5244</guid> <description><![CDATA[La revue de presse de l’actualité Java/J2EE hebdomadaire proposée par Xebia. Actualité éditeurs / SSII James Gosling sur l&#8217;affaire Oracle vs Google ActiveMQ 5.4.0 Le coin de la technique Hibernate ne supporte plus CGLIB Actualité éditeurs / SSII James Gosling sur l&#8217;affaire Oracle vs Google James Gosling revient sur l&#8217;épisode Oracle vs Google avec un [...]]]></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 de l’actualité Java/J2EE hebdomadaire proposée par Xebia.</em></p><p><strong>Actualité  éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2010/08/24/revue-de-presse-xebia-173/#JamesGoslingsurlaffaireOraclev">James Gosling sur l&#8217;affaire Oracle vs Google</a></li><li><a
href="http://blog.xebia.fr/2010/08/24/revue-de-presse-xebia-173/#ActiveMQ">ActiveMQ 5.4.0</a></li></ul><p><strong>Le coin de la  technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2010/08/24/revue-de-presse-xebia-173/#HibernatenesupporteplusCGLIB">Hibernate ne supporte plus CGLIB</a></li></ul><h3><a
name="ActualitditeursSSII"></a>Actualité  éditeurs / SSII</h3><h4><a
name="JamesGoslingsurlaffaireOraclev"></a>James Gosling sur l&#8217;affaire Oracle vs Google</h4><p>James Gosling revient sur l&#8217;épisode <a
href="http://blog.xebia.fr/2010/08/17/revue-de-presse-xebia-172/" title="Oracle vs Google" >Oracle vs Google</a> avec un <a
href="http://nighthacks.org/roller/jag/entry/quite_the_firestorm" title="article" >article</a> dans lequel il nous donne quelques éléments pour mieux comprendre la politique de Sun vis à vis de Java et des brevets :</p><ul><li>Sun a principalement déposé des brevets afin de se protéger d&#8217;éventuelles attaques venant de ses concurrents. Un épisode malheureux dans lequel Sun fut attaqué par IBM concernant un brevet sur les processeurs RISC leur fit prendre conscience qu&#8217;il était nécessaire de posséder un arsenal de brevets. Le procès se termina en effet en leur défaveur et ils durent payer d&#8217;importantes indemnités à IBM, les mettant au bord du dépôt de bilan.</li><li>Les brevets sur la technologie Java et le choix de la license CDDL avaient pour but de garantir l&#8217;interopérabilité des applications java sur les différentes plateformes. Cette protection a donné lieu à un procès entre Sun et Microsoft car ce dernier avait fournit une implémentation d&#8217;un machine virtuelle Java sur laquelle le code ne s&#8217;exécutait pas de la même manière que sur les autres JVM (dont celle de Sun) qui respectaient les spécifications. La machine virtuelle java de Google présentant elle aussi des problèmes d&#8217;interopérabilité, Oracle se sert de cette jurisprudence pour les poursuivre.</li><li>Sun aurait souhaité obtenir une partie des bénéfices générés par la plateforme Android mais sans succès. Il semble donc qu&#8217;Oracle souhaite continuer dans cette voie mais en choisissant de sortir l&#8217;artillerie lourde pour parvenir à ses fins.</li></ul><p>Cette affaire a un effet néfaste sur l&#8217;image de Java et James Gosling, loin de cautionner l&#8217;action d&#8217;Oracle, regrette l&#8217;absence de moralité des grandes compagnies informatiques actuelles.</p><h4><a
name="ActiveMQ"></a>ActiveMQ 5.4.0</h4><p>Un peu moins d&#8217;un an après la <a
href="http://blog.xebia.fr/2009/10/19/revue-de-presse-xebia-130/#UnnouveaumoteurdestockagepourA" title="dernière release" >dernière release</a>, Apache sort une nouvelle version de son <em>broker</em> de message. Au-delà des <a
href="https://issues.apache.org/activemq/secure/IssueNavigator.jspa?reset=true&#038;pid=10520&#038;fixfor=12110&#038;sorter/field=priority&#038;sorter/order=DESC" title="283" >283</a> bugs résolus, on notera quelques nouvelles fonctionnalités intéressantes:</p><ul><li>Priorité des messages: Jusqu&#8217;à maintenant pour jouer sur la priorité de certains messages sur d&#8217;autres il fallait contourner le problème en utilisant plusieurs queues de messages qui pouvaient être, elles, <em>priorisées</em>. Le point de blocage jusqu&#8217;à maintenant était lié à l&#8217;ordonnancement des messages, trop gourmand en temps. Ce problème semble être en partie réglé et le paramètre priorité du message JMS (inclus dans l&#8217;API) sera pris en compte.</li><li><a
href="http://activemq.apache.org/delay-and-schedule-message-delivery.html" title="Planifier ses messages" >Planifier ses messages</a>: ActiveMQ possède à présent un planificateur persistant de message. En d&#8217;autres termes, il est possible à l&#8217;envoi du message de préciser la date réelle de l&#8217;envoi et la durée entre la répétition d&#8217;un envoi. L&#8217;interface permet même de préciser tout cela sous la forme d&#8217;une entrée CRON. Ceci peut être assez intéressant pour par exemple faire du <em>heartbeat</em> (envoi d&#8217;un message à intervalle régulier pour s&#8217;assurer du fonctionnement de l&#8217;application ou faire des calculs de performance).</li><li><a
href="http://activemq.apache.org/websockets.html" title="WebSocket" >WebSocket</a>: Le sujet est à la mode, surtout avec l&#8217;émergence d&#8217;HTML 5, <a
href="http://blog.xebia.fr/2010/06/08/revue-de-presse-xebia-162/#HornetQ" title="HornetQ" >HornetQ</a> le propose également sur sa dernière version. Il s&#8217;agit d&#8217;utiliser le <em>broker</em> de messages depuis du code javascript. Tout comme HornetQ, ActiveMQ utilise son protocole de message simplifié STOMP. Deux librairies javascripts sont proposées sur leur site: <a
href="http://github.com/krukow/stomple" title="Stomple" >Stomple</a> et <a
href="http://github.com/jmesnil/stomp-websocket" title="stompwebsocket" >stomp-websocket</a>.</li></ul><p>Hormis ces nouveautés, des améliorations ont été apportées sur <a
href="http://activemq.apache.org/osgi-integration.html" title="OSGI" >OSGI</a> et le shell <a
href="http://activemq.apache.org/unix-shell-script.html" title="unix" >unix</a>.</p><h3><a
name="Lecoindelatechnique"></a>Le coin de la  technique</h3><h4><a
name="HibernatenesupporteplusCGLIB"></a>Hibernate ne supporte plus CGLIB</h4><p>Historiquement <a
href="http://cglib.sourceforge.net/" title="CGLIB" >CGLIB</a> a rendu de nombreux services à Hibernate et Spring pour permettre de manipuler le bytecode Java. Par exemple, vous avez sans doute déjà vu passer un proxy préfixé par CGLIB lorsque vous débuggez votre application. Mais récemment, Steve Ebersole, développeur chez Hibernate, <a
href="http://in.relation.to/Bloggers/DeprecatedCGLIBSupport" title="a annoncé" >a annoncé</a> qu&#8217;il n&#8217;y aurait plus de support pour cette librairie. Cette décision aurait été prise non pas pour des raisons purement techniques mais parce que cette librairie n&#8217;aurait plus de support et semble figée à la version 2.2 qui date de 2008. L&#8217;auteur donne pour exemple un <a
href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-2222" title="ancien bug" >ancien bug</a> sur une incompatibilité de version de la librairie ASM (qui manipule à un niveau plus bas le bytecode) avec celle de Spring et qui mit un an à être corrigé.</p><p>Hibernate à présent privilégiera <a
href="http://jboss.org/javassist" title="Javassist" >Javassist</a>, un projet JBoss (tout comme Hibernate, tiens, tiens&#8230;), aux fonctionnalités similaires mais encore <em>en vie</em>. Reste à savoir si Spring suivra la même démarche.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/08/24/revue-de-presse-xebia-173/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Bean Validation</title><link>http://blog.xebia.fr/2010/07/15/bean-validation/</link> <comments>http://blog.xebia.fr/2010/07/15/bean-validation/#comments</comments> <pubDate>Thu, 15 Jul 2010 05:36:12 +0000</pubDate> <dc:creator>Guillaume Arnaud</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Beans Validation]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Hibernate Validator]]></category> <category><![CDATA[Java EE 6]]></category> <category><![CDATA[JSR-303]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring MVC]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=5033</guid> <description><![CDATA[Comment valider un bean ? L&#8217;idée de départ, comme toutes les bonnes idées, est très simple. Avant, pour confirmer que des données étaient valides selon certains critères métiers, le développeur pouvait être amené à intervenir sur plusieurs couches. Il pouvait agir, par exemple, sur la couche présentation, en ajoutant du javascript pour contrôler un champ [...]]]></description> <content:encoded><![CDATA[<p>Comment valider un bean ? L&#8217;idée de départ, comme toutes les bonnes idées, est très simple. Avant, pour confirmer que des données étaient valides selon certains critères métiers, le développeur pouvait être amené à intervenir sur plusieurs couches. Il pouvait agir, par exemple, sur la couche présentation, en ajoutant du javascript pour contrôler un champ du formulaire, ou bien ajouter du code de vérification dans la couche DAO avant de persister en base. Cette spécification a eu pour objectif, d&#8217;une part d&#8217;enrichir les entités métiers sur les valeurs que pouvaient prendre ses propriétés, et d&#8217;autre part de fournir un service capable de valider ces entités avec en plus un certain niveau d&#8217;information sur les cas non valides.</p><p>La JSR-303, finalisée en novembre 2009, fournit une standardisation de ces concepts et fait partie de Java EE 6. Emmanuel Bernard étant le <em>spec lead</em> de cette JSR, assez naturellement l&#8217;implémentation <em>Hibernate Validator</em> est devenue celle de référence. C&#8217;est cette dernière qui sera exclusivement évoquée dans cet article.</p><h3><a
name="Conceptsdebase"></a>Concepts de base</h3><p>On étudiera dans cet article la configuration par annotations, mais il reste possible de faire l&#8217;équivalent en fichier xml.</p><h4><a
name="Contraintes"></a>Contraintes</h4><p>Une contrainte est une restriction sur un attribut d&#8217;un bean. Beaucoup sont déjà définies dans la JSR-303, Hibernate Validator en rajoute quelques-unes très utiles et l&#8217;utilisateur peut définir les siennes comme nous le verrons plus loin.</p><p>Voici un exemple pour valider qu&#8217;un attribut est non nul :</p><pre class="brush: java; title: ; notranslate">
public class Personne{
    @NotNull
    private String nom;
    ...
}
</pre><p>Les contraintes peuvent être posées directement sur le champ, sur la propriété par l&#8217;intermédiaire de l&#8217;accesseur ou au niveau de la classe, ce qui nécessite de définir sa propre contrainte. La visibilité du champ n&#8217;a pas d&#8217;importance car il sera introspecté par réflexion mais il ne doit pas être statique.</p><p>Un graphe d&#8217;objets peut être validé dans son ensemble, ou bien plus finement. Si une entité à valider possède une autre entité ayant des contraintes, l&#8217;annotation <code>@Valid</code> permet de contraindre aussi la validation de cette entité. Cerise sur le gâteau, la validation sur une collection fonctionne aussi, tous les éléments de cette collection devant être valides.</p><p>Voici les contraintes standards:</p><table
cellspacing="0" cellpadding="5" style="border: 1px solid black"><tr><td
bgcolor="#663366" style="color: #ffffff; border: 1px solid black"><strong>contrainte</strong></td><td
bgcolor="#663366" style="color: #ffffff; border: 1px solid black"><strong>signification</strong></td><td
bgcolor="#663366" style="color: #ffffff; border: 1px solid black"><strong>types acceptés</strong></td></tr><tr><td
style="border: 1px solid black"><code>@Null</code></td><td
style="border: 1px solid black">L&#8217;élément doit être nul</td><td
style="border: 1px solid black"><code>Object</code></td></tr><tr><td
style="border: 1px solid black"><code>@NotNull</code></td><td
style="border: 1px solid black">L&#8217;élément doit être non nul</td><td
style="border: 1px solid black"><code>Object</code></td></tr><tr><td
style="border: 1px solid black"><code>@AssertTrue</code></td><td
style="border: 1px solid black">L&#8217;élément doit être <code>true</code></td><td
style="border: 1px solid black"><code>boolean</code>, <code>Boolean</code></td></tr><tr><td
style="border: 1px solid black"><code>@AssertFalse</code></td><td
style="border: 1px solid black">L&#8217;élément doit être <code>false</code></td><td
style="border: 1px solid black"><code>boolean</code>, <code>Boolean</code></td></tr><tr><td
style="border: 1px solid black"><code>@Min</code></td><td
style="border: 1px solid black">L&#8217;élément doit être supérieur à la valeur spécifiée dans l&#8217;annotation</td><td
style="border: 1px solid black"><code>BigDecimal</code>, <code>BigInteger</code>, <code>byte</code>, <code>short</code>, <code>int</code>, <code>long</code></td></tr><tr><td
style="border: 1px solid black"><code>@Max</code></td><td
style="border: 1px solid black">L&#8217;élément doit être inférieur à la valeur spécifiée dans l&#8217;annotation</td><td
style="border: 1px solid black"><code>BigDecimal</code>, <code>BigInteger</code>, <code>byte</code>, <code>short</code>, <code>int</code>, <code>long</code></td></tr><tr><td
style="border: 1px solid black"><code>@DecimalMin</code></td><td
style="border: 1px solid black">L&#8217;élément doit être supérieur à la valeur spécifiée dans l&#8217;annotation</td><td
style="border: 1px solid black"><code>BigDecimal</code>, <code>BigInteger</code>, <code>String</code>, <code>byte</code>, <code>short</code>, <code>int</code>, <code>long</code></td></tr><tr><td
style="border: 1px solid black"><code>@DecimalMax</code></td><td
style="border: 1px solid black">L&#8217;élément doit être inférieur à la valeur spécifiée dans l&#8217;annotation</td><td
style="border: 1px solid black"><code>BigDecimal</code>, <code>BigInteger</code>, <code>String</code>, <code>byte</code>, <code>short</code>, <code>int</code>, <code>long</code></td></tr><tr><td
style="border: 1px solid black"><code>@Size</code></td><td
style="border: 1px solid black">L&#8217;élément doit être entre deux tailles spécifiées</td><td
style="border: 1px solid black"><code>String</code>, <code>Collection</code>, <code>Map</code>, <code>Array</code></td></tr><tr><td
style="border: 1px solid black"><code>@Digits</code></td><td
style="border: 1px solid black">L&#8217;élément doit être un nombre compris dans une certaine fenêtre</td><td
style="border: 1px solid black"><code>BigDecimal</code>, <code>BigInteger</code>, <code>String</code>, <code>byte</code>, <code>short</code>, <code>int</code>, <code>long</code></td></tr><tr><td
style="border: 1px solid black"><code>@Past</code></td><td
style="border: 1px solid black">L&#8217;élément doit être une date dans le passé</td><td
style="border: 1px solid black"><code>Date</code>, <code>Calendar</code></td></tr><tr><td
style="border: 1px solid black"><code>@Future</code></td><td
style="border: 1px solid black">L&#8217;élément doit être une date dans le futur</td><td
style="border: 1px solid black"><code>Date</code>, <code>Calendar</code></td></tr><tr><td
style="border: 1px solid black"><code>@Pattern</code></td><td
style="border: 1px solid black">L&#8217;élément doit respecter une expression régulière</td><td
style="border: 1px solid black"><code>String</code></td></tr></table><p>Hibernate Validator ajoute des contraintes intéressantes : <code>@CreditCardNumber</code>, <code>@Email</code>, <code>@NotBlank</code>, <code>@NotEmpty</code>, <code>@Range</code>, <code>@ScriptAssert</code>, <code>@URL</code>. <code>@ScriptAssert</code> est sans doute la plus complexe à mettre en place, elle s&#8217;appuie sur la JSR-223 qui fournit une API pour introduire les langages de script, plus de détails <a
href="http://musingsofaprogrammingaddict.blogspot.com/2010/06/whats-new-in-hibernate-validator-41.html" title="ici" >ici</a>.</p><h4><a
name="Servicedevalidation"></a>Service de validation</h4><p>Pour valider ses entités il faut se munir tout naturellement d&#8217;un validateur, on passe pour cela par une <em>factory</em> fournie par l&#8217;API standard ( <code>javax.validator</code> ) :</p><pre class="brush: java; title: ; notranslate">
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
</pre><p>Pour récupérer l&#8217;implémentation du validateur, l&#8217;API utilise le <a
href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider" title="Service Provider" ><em>Service Provider</em></a> de Java. Son fonctionnement est assez simple. Dans le jar contenant l&#8217;implémentation il faut ajouter dans le répertoire <code>META-INF/services</code> un fichier nommé <code>javax.validation.spi.ValidationProvider</code> qui contient le nom de la classe implémentant l&#8217;interface <code>ValidationProvider</code>. Pour Hibernate Validator il s&#8217;agit de la classe <code>HibernateValidator</code>.</p><p>Donc pour résumer, il n&#8217;y a pas de configuration à faire pour spécifier que Hibernate Validator fournira le <code>Validator</code>, il suffit juste d&#8217;ajouter le jar, sauf s&#8217;il existe d&#8217;autres implémentations de l&#8217;API de validation. Dans ce dernier cas, et si on veut être sûr d&#8217;utiliser Hibernate Validator, il est possible de définir le provider explicitement :</p><pre class="brush: java; title: ; notranslate">
ValidatorFactory factory = Validation.byProvider(HibernateValidator.class).configure().buildValidatorFactory();
</pre><p>Ensuite on passe à la validation de nos entités :</p><pre class="brush: java; title: ; notranslate">
Set&lt;ConstraintViolation&lt;Voiture&gt;&gt; constraintViolations = validator.validate(voiture);
</pre><p>On introduit ici l&#8217;objet <code>ConstraintViolation</code>, très riche en informations sur les raisons de la non validation d&#8217;un élément. C&#8217;est cet objet qui va par exemple nous permettre de nous fournir le message associé à l&#8217;erreur. Les méthodes de cette classe :</p><table
cellspacing="0" cellpadding="5" style="border: 1px solid black"><tr><td
bgcolor="#663366" style="color: #ffffff; border: 1px solid black"><strong>méthode</strong></td><td
bgcolor="#663366" style="color: #ffffff; border: 1px solid black"><strong>description</strong></td></tr><tr><td
style="border: 1px solid black"><code>getMessage()</code></td><td
style="border: 1px solid black">Récupère le message interpolé</td></tr><tr><td
style="border: 1px solid black"><code>getMessageTemplate()</code></td><td
style="border: 1px solid black">Récupère le message non-interpolé</td></tr><tr><td
style="border: 1px solid black"><code>getRootBean()</code></td><td
style="border: 1px solid black">L&#8217;objet racine non valide</td></tr><tr><td
style="border: 1px solid black"><code>getLeafBean()</code></td><td
style="border: 1px solid black">Dans le cas où l&#8217;objet à valider contient un autre objet qui se trouve être non valide, ce dernier sera retourné</td></tr><tr><td
style="border: 1px solid black"><code>getRootBeanClass()</code></td><td
style="border: 1px solid black">La classe de l&#8217;objet non valide</td></tr><tr><td
style="border: 1px solid black"><code>getPropertyPath()</code></td><td
style="border: 1px solid black">La propriété de l&#8217;entité qui n&#8217;est pas valide</td></tr><tr><td
style="border: 1px solid black"><code>getInvalidValue()</code></td><td
style="border: 1px solid black">La valeur erronée</td></tr><tr><td
style="border: 1px solid black"><code>getConstraintDescriptor()</code></td><td
style="border: 1px solid black">Un objet contenant des informations sur la contrainte elle-même</td></tr></table><p>C&#8217;est l&#8217;occasion de remarquer que l&#8217;API de validation propose une gestion interne des ressources, on peut soit récupérer le message directement associé à une propriété ( <code>getMessage()</code> ) soit la clé ( <code>getMessageTemplate()</code> ). Dans le chapitre suivant on détaillera davantage la gestion des ressources.</p><p>On peut aussi avoir besoin de ne valider qu&#8217;une sous partie des contraintes d&#8217;une entité ou de rassembler plusieurs des contraintes de plusieurs entités. L&#8217;attribut <code>groups</code> des annotations de contraintes sert à ça. Elle contient une interface (ou une classe, ce qui est moins recommandé) qui sera commune aux contraintes:</p><pre class="brush: java; title: ; notranslate">
public class Facture {
    @Past
    private Date dateCommande;
    @NotNull(groups=PaiementCheck.class)
    private String nomBanque;
    @CreditCardNumber(groups=PaiementCheck.class)
    private String creditCardNumber;
}
public interface PaiementCheck {}
...
    validator.validate(facture, PaiementCheck.class);
...
</pre><h4><a
name="Gestiondesressources"></a>Gestion des ressources</h4><p>A chaque type de contrainte est associé une clé, elle même liée à une propriété. Toutes les contraintes de base ont des messages déjà définis et Hibernate Validator propose même les traductions françaises. Ce message peut être surchargé directement au niveau de la contrainte:</p><pre class="brush: java; title: ; notranslate">
@Min(message=&quot;ce champ doit être supérieur à {value}&quot;)
</pre><p>Grâce aux accolades, on peut accéder aux données de l&#8217;annotation (dans cet exemple à la valeur minimale). On peut <em>échapper</em> les accolades avec .</p><p>Les propriétés sont résolues par l&#8217;intermédiaire de l&#8217;interface <code>MessageInterpolator</code> qui, par défaut, va chercher un fichier <code>ValidationMessages.properties</code> à la racine du classpath. S&#8217;il n&#8217;en trouve pas à la racine il ira chercher celui dans le package <code>org.hibernate.validator</code>. On peut donc ainsi, facilement surcharger les propriétés de Hibernate Validator.</p><p>Il est possible d&#8217;utiliser ses propres <em>resource bundles</em> si on veut par exemple utiliser d&#8217;autres fichiers properties, ou les stocker ailleurs que dans le classpath. Pour cela il faut surcharger l&#8217;implémentation de <code>ResourceBundleLocator</code>. Ci-dessous, un exemple tiré de la <a
href="http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#example-resource-bundle-locator" title="documentation" >documentation</a>:</p><pre class="brush: java; title: ; notranslate">
HibernateValidatorConfiguration configure = Validation.byProvider(HibernateValidator.class).configure();
ResourceBundleLocator defaultResourceBundleLocator = configure.getDefaultResourceBundleLocator();
ResourceBundleLocator myResourceBundleLocator = new MyCustomResourceBundleLocator(defaultResourceBundleLocator);
configure.messageInterpolator(new ResourceBundleMessageInterpolator(myResourceBundleLocator));
</pre><p>A un plus haut niveau, on peut également ne pas passer par des <em>resource bundles</em> mais implémenter sa propre stratégie pour, par exemple, accéder à une base de données. Pour cela il faut fournir une implémentation de l&#8217;interface <code>MessageInterpolator</code>.</p><pre class="brush: java; title: ; notranslate">
Configuration&lt;?&gt; configuration = Validation.byDefaultProvider().configure();
ValidatorFactory factory = configuration
   .messageInterpolator(new MyMessageInterpolator(configuration.getDefaultMessageInterpolator()))
   .buildValidatorFactory();
Validator validator = factory.getValidator();
</pre><p><code>MyMessageInterpolator</code> implémente donc <code>MessageInterpolator</code> qui a deux méthodes:</p><pre class="brush: java; title: ; notranslate">
String interpolate(String messageTemplate, Context context);
String interpolate(String messageTemplate, Context context,  Locale locale);
</pre><p><code>messageTemplate</code> étant la clé de la contrainte et <code>context</code> contient des informations sur cette contrainte. Libre ensuite au développeur d&#8217;associer la ressource correspondante comme il veut.</p><h4><a
name="Dfinirsaproprecontrainte"></a>Définir sa propre contrainte</h4><p>Il est possible de créer sa propre contrainte, pour cela on passe par 3 étapes:</p><ul><li>créer l&#8217;annotation</li><li>implémenter le validateur</li><li>définir le message d&#8217;erreur</li></ul><p>Nous allons faire un validateur pour les plaques d&#8217;immatriculation et vérifier qu&#8217;elles appartiennent à un département donné (il s&#8217;agira des anciennes normes, par exemple 123-ABC-93, pas des nouvelles normes européennes). Commençons par l&#8217;annotation&nbsp;:</p><pre class="brush: java; title: ; notranslate">
@Target({METHOD,FIELD,ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy=ImmaticulationValidator.class)
@Documented
public @interface CheckImmatriculation {
   String message() default &quot;{fr.xebia.constraints.checkimmatriculation}&quot;;
   Class&lt;?&gt;[] groups() default {};
   Class&lt;? extends Payload&gt;[] payload() default {};
   String departement();
}
</pre><p>On voit apparaître la notion de <code>Payload</code>, elle peut être utilisée pour enrichir les informations sur cette contrainte. L&#8217;exemple proposé en général est le cas où on veut ajouter un niveau de sévérité à une contrainte. On peut récupérer la classe associée dans la description de la contrainte : <code>ConstraintViolation.getConstraintDescriptor().getPayload()</code>.</p><p>On écrit ensuite le validateur associé :</p><pre class="brush: java; title: ; notranslate">
public class ImmaticulationValidator implements
       ConstraintValidator&lt;CheckImmatriculation, String&gt; {
   private String departement;
   public void initialize(CheckImmatriculation constraintAnnotation) {
       departement = constraintAnnotation.departement();
   }
   public boolean isValid(String value, ConstraintValidatorContext context) {
       if (!Pattern.matches(&quot;
d{1,3}-[a-zA-Z]{2,3}-
d{2}&quot;, value)) {
           return false;
       }
       // On récupère le département donné
       String d = value.substring(value.length() - 2);
       return departement.equals(d);
   }
}
</pre><p>Enfin on doit ajouter le message qui sera retourné en cas d&#8217;erreur dans le fichier de <em>properties</em> <code>ValidationMessages.properties</code> comme vu précédemment. On peut par exemple afficher le département attendu:</p><pre class="brush: java; title: ; notranslate">
fr.xebia.constraints.checkimmatriculation=Le département doit être {departement}.
</pre><h3><a
name="SpringSpringMVC"></a>Spring/SpringMVC</h3><p>Depuis la version 3.0 de Spring MVC la JSR-303 est complètement supportée. Tout est donc grandement facilité et valider un formulaire devient quasiment immédiat. On peut résumer la procédure à l&#8217;ajout de l&#8217;annotation <code>@Valid</code> dans la requête POST de soumission du formulaire:</p><pre class="brush: java; title: ; notranslate">
public void submitVoiture(@Valid VoitureForm voiture, , Errors errors){
     logger.info(&quot;Nombre d'erreur&quot;+errors.getErrorCount());
     ...
}
</pre><p>Les contraintes non validées seront automatiquement injectées dans <code>errors</code> et donc accessibles dans la vue :</p><pre class="brush: java; title: ; notranslate">
&lt;form:form action=&quot;edit&quot; modelAndAttribute=&quot;voiture&quot;&gt;
    &lt;form:errors path=&quot;*&quot;/&gt;
    &lt;form:input path=&quot;immatriculation&quot;/&gt;
    ...
    &lt;input type=&quot;submit&quot;/&gt;
&lt;/form:form&gt;
</pre><p>Outre <em>Spring MVC</em>, de plus en plus de frameworks de présentation adoptent la JSR-303, remplaçant leurs anciens codes spécifiques par ce nouveau standard. Naturellement JSF 2.0 l&#8217;utilise mais on peut aussi citer <a
href="http://yeswicket.com/index.php?post/2010/02/24/Wicket-JSR-303-Validators" title="Wicket" >Wicket</a> ou <a
href="http://blog.tapestry5.de/index.php/2010/01/04/tapestry-and-jsr-303-bean-validation-api/" title="Tapestry" >Tapestry</a>.</p><h3><a
name="Hibernate"></a>Hibernate</h3><p>Nous avons vu qu&#8217;il était possible de valider programmatiquement une entité. Néanmoins, on peut vouloir être encore plus prudent et empêcher les opérations de persistance si une contrainte est violée. Hibernate propose <a
href="http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/additionalmodules.html#d0e3875" title="un mcanisme" >un mécanisme</a> de <em>listeners</em> sur les événements <code>insert</code>, <code>update</code> et <code>remove</code>. Voici un exemple de configuration possible:</p><pre class="brush: java; title: ; notranslate">
&lt;persistence ...&gt;
  &lt;persistence-unit ...&gt;
    ...
    &lt;properties&gt;
      &lt;property name=&quot;javax.persistence.validation.mode&quot;
                value=&quot;callback, ddl&quot;/&gt;
    &lt;/properties&gt;
  &lt;/persistence-unit&gt;
&lt;/persistence&gt;
</pre><p>Il existe plusieurs modes: <code>none</code>, <code>auto</code> (s&#8217;il n&#8217;y a aucun jar de validation, il n&#8217;y aura pas de validation), <code>callback</code> (s&#8217;il n&#8217;y a aucun jar une exception est lancée au démarrage), <code>ddl</code>. Cette dernière permet de générer le schéma de base avec les contraintes définies dans l&#8217;entité.</p><p>Il est possible de différencier les comportements selon le type d&#8217;opération:</p><pre class="brush: java; title: ; notranslate">
&lt;persistence ...&gt;
  &lt;persistence-unit ...&gt;
    ...
    &lt;properties&gt;
      &lt;property name=&quot;javax.persistence.validation.group.pre-update&quot;
                value=&quot;javax.validation.group.Default, com.acme.group.Strict&quot;/&gt;
      &lt;property name=&quot;javax.persistence.validation.group.pre-remove&quot;
                value=&quot;com.acme.group.OnDelete&quot;/&gt;
      &lt;property name=&quot;org.hibernate.validator.group.ddl&quot;
                value=&quot;com.acme.group.DDL&quot;/&gt;
    &lt;/properties&gt;
  &lt;/persistence-unit&gt;
&lt;/persistence&gt;
</pre><p>En cas de violation d&#8217;une contrainte une exception de type <code>ConstraintViolationException</code> est lancée, éventuellement englobée dans une exception <code>RollbackException</code> en mode transactionnel. Cette exception contient la liste des <code>ConstraintViolation</code> de l&#8217;API Bean Validation vue plus haut.</p><p>Une fonctionnalité de l&#8217;API encore non évoquée, mais qui rejoint les problématiques souvent rencontrées dans Hibernate, est la notion de <em>traversabilité</em>, formalisée par l&#8217;interface <code>TraversableResolver</code>. Celle-ci contient deux méthodes <em>isReachable</em> et <em>isCascadable</em> qui peuvent permettre dans certains cas de désactiver une validation d&#8217;un <em>sous-objet</em>. Cela peut permettre lorsqu&#8217;on manipule des objets en <em>lazy loading</em>, de préserver ce <em>non-chargement</em>.</p><h3><a
name="Conclusion"></a>Conclusion</h3><p><em>Bean Validation</em> impressionne par sa vision complète des problématiques de validation, peu de cas semblent avoir été ignorés ou oubliés, et dans le cas contraire l&#8217;API est suffisamment souple pour pouvoir être étendue proprement. Certains regretteront peut-être qu&#8217;il n&#8217;y ait pas plus de contraintes pré-définies, mais il est extrêmement difficile de définir des contraintes universelles et ajouter sa propre contrainte est vraiment facile.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/07/15/bean-validation/feed/</wfw:commentRss> <slash:comments>11</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2010/04/26/revue-de-presse-xebia-156/</link> <comments>http://blog.xebia.fr/2010/04/26/revue-de-presse-xebia-156/#comments</comments> <pubDate>Mon, 26 Apr 2010 17:30:01 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[Cassandra]]></category> <category><![CDATA[Cloud Computing]]></category> <category><![CDATA[Hadoop]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[JavaFX]]></category> <category><![CDATA[JPA]]></category> <category><![CDATA[scala]]></category> <category><![CDATA[whirr]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=4482</guid> <description><![CDATA[La revue de presse de l’actualité Java/J2EE hebdomadaire proposée par Xebia. Actualité éditeurs / SSII Apache Whirr, une proposition de librairie pour le Cloud RIA Où l&#8217;on reparle de JavaFX Le coin de la technique Des breaks dans Scala ! Une troisième implémentation de JPA 2 finalisée Actualité éditeurs / SSII Apache Whirr, une proposition [...]]]></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 de l’actualité Java/J2EE hebdomadaire proposée par Xebia.</em></p><p><strong>Actualité éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2010/04/26/revue-de-presse-xebia-156/#ApacheWhirrunepropositiondelib">Apache Whirr, une proposition de librairie pour le Cloud</a></li></ul><p><strong>RIA</strong></p><ul><li><a
href="http://blog.xebia.fr/2010/04/26/revue-de-presse-xebia-156/#OlonreparledeJavaFX">Où l&#8217;on reparle de JavaFX</a></li></ul><p><strong>Le coin de la technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2010/04/26/revue-de-presse-xebia-156/#DesbreaksdansScala">Des breaks dans Scala !</a></li><li><a
href="http://blog.xebia.fr/2010/04/26/revue-de-presse-xebia-156/#UnetroisimeimplmentationdeJPAf">Une troisième implémentation de JPA 2 finalisée</a></li></ul><h3><a
name="ActualitditeursSSII"></a>Actualité éditeurs / SSII</h3><h4><a
name="ApacheWhirrunepropositiondelib"></a>Apache Whirr, une proposition de librairie pour le Cloud</h4><p>Whirr est une <em>proposal</em> intéressante <a
href="http://wiki.apache.org/incubator/WhirrProposal" title="qui vient d'apparaître" >qui vient d&#8217;apparaître</a> au sein de la fondation Apache. Il s&#8217;agit de réunir au sein de ce projet tout un ensemble de scripts et de code source permettant d&#8217;intégrer facilement des services Apache avec les fournisseurs d&#8217;infrastructures de Cloud Computing. Parmi les première applications / services dont il est question, on compte sans grande surprise <a
href="http://hadoop.apache.org/" title="Hadoop" >Hadoop</a> (implémentation Java du modèle MapReduce de Google), <a
href="http://hadoop.apache.org/hbase/" title="HBase" >HBase</a> (implémentation de BigTable de Google au dessus d&#8217;Hadoop), <a
href="http://hadoop.apache.org/zookeeper/" title="ZooKeeper" >ZooKeeper</a> (service de configuration, nommage et synchronisation pour applications distribuées, implémentation Java de Chubby de Google), et <a
href="http://cassandra.apache.org/" title="Cassandra" >Cassandra</a> (base de données hybride BigTable et Dynamo, initialement développée par Facebook). Ces projets ont en effet acquis une grande popularité en quelques mois et font maintenant partie des applications typiques du Cloud Computing.</p><p>La raison d&#8217;être du projet est de mutualiser les efforts fournis par ces projets pour fournir des scripts et des mécanismes d&#8217;intégration de qualité sur les plate-formes de Cloud Computing. Au-delà de ces justifications techniques, on remarquera qu&#8217;il s&#8217;agit d&#8217;une véritable reconnaissance du Cloud Computing en tant qu&#8217;enjeu d&#8217;avenir. En effet cette proposition intervient dans un contexte où les projets liés à ce sujet se multiplient au sein de la fondation Apache, puis acquièrent leur indépendance : après la promotion de Cassandra hors de l&#8217;incubateur Apache, c&#8217;est au tour de HBase d&#8217;être promu <em>top-level project</em> sortant donc de l&#8217;affiliation au projet Hadoop. Enfin, on notera que les acteurs impliqués dans la proposition Whirr sont majeurs : Cloudera, Twitter ou encore HP Labs.</p><h3><a
name="RIA"></a>RIA</h3><h4><a
name="OlonreparledeJavaFX"></a>Où l&#8217;on reparle de JavaFX</h4><p>JavaFX a beaucoup fait parler d&#8217;elle après sa sortie fin 2008. Elle <a
href="http://blog.xebia.fr/2009/03/09/revue-de-presse-xebia-99/#LepositionnementdeJavaFXtoujou" title="navait gure convaincu" >n&#8217;avait guère convaincu</a> : on lui reprochait de ne pas être mature, de ne pas offrir de composants graphiques de haut niveau, de ne pas tenir ses promesses de déploiement sur plusieurs plates-formes puisqu&#8217;il n&#8217;était alors pas possible de l&#8217;utiliser sur TV et sur mobile comme cela devait être le cas.</p><p>En février 2009, <a
href="http://blog.xebia.fr/2009/02/16/revue-de-presse-xebia-96/#JavaFxsurmobile" title="la version 11" >la version 1.1</a> avait permis le déploiement des applications JavaFX sur mobile (tout du moins théoriquement). La version 1.2, sortie en juin dernier, avait été une autre étape majeure en introduisant enfin des composants graphiques évolués.</p><p>Lors de la conférence Devoxx de novembre dernier, il avait été amusant de constater que les sessions et <em>keynotes</em> dédiés à JavaFX, si présents lors de la précédente édition, avaient été remplacés par leurs équivalents Flex avec l&#8217;annonce en grande pompe d&#8217;Adobe Catalyst. JavaFX disparaissait peu à peu de l&#8217;actualité.</p><p>Oracle vient d&#8217;annoncer l&#8217;arrivée de <a
href="http://javafx.com/docs/articles/javafx1-3.jsp" title="la version 13" >la version 1.3</a>. Les nouveautés sont incontestablement conséquentes :</p><ul><li>Support étendu de CSS pour le design des <em>widgets</em> : JavaFX supportait déjà CSS, il va maintenant plus loin dans l&#8217;intégration de ce langage de style.</li></ul><ul><li>Nouveaux <em>widgets</em> : une liste déroulante (<a
href="http://java.sun.com/javafx/1.3/docs/api/javafx.scene.control/javafx.scene.control.ChoiceBox.html" title="ChoiceBox" >ChoiceBox</a>), un champ de saisie de mots de passe (<a
href="http://java.sun.com/javafx/1.3/docs/api/javafx.scene.control/javafx.scene.control.PasswordBox.html" title="PasswordBox" >PasswordBox</a>), une vue <em>scrollable</em> (<a
href="http://java.sun.com/javafx/1.3/docs/api/javafx.scene.control/javafx.scene.control.ScrollView.html" title="ScrollView" >ScrollView</a>), un séparateur (<a
href="http://java.sun.com/javafx/1.3/docs/api/javafx.scene.control/javafx.scene.control.Separator.html" title="Separator" >Separator</a>) et une bulle d&#8217;information (<a
href="http://java.sun.com/javafx/1.3/docs/api/javafx.scene.control/javafx.scene.control.Tooltip.html" title="ToopTip" >ToopTip</a>).</li></ul><ul><li>Amélioration de <em>widgets</em> existants : divers améliorations des composants <a
href="http://java.sun.com/javafx/1.3/docs/api/javafx.scene.control/javafx.scene.control.ListView.html" title="ListView" >ListView</a>, <a
href="http://java.sun.com/javafx/1.3/docs/api/javafx.scene.control/javafx.scene.control.TextBox.html" title="TextBox" >TextBox</a> et <a
href="http://java.sun.com/javafx/1.3/docs/api/javafx.scene.control/javafx.scene.control.Slider.html" title="Slider" >Slider</a></li></ul><ul><li>Le support des TV fait enfin son apparition : les TV faisaient historiquement partie des plates-formes de déploiement possibles pour JavaFX mais n&#8217;étaient pas accessibles jusqu&#8217;alors. Un émulateur de TV vient compléter ce support.</li></ul><p>Pour <a
href="http://blog.xebia.fr/2009/11/23/devoxx-jour-2-java-fx-the-developer-guide/" title="rappel" >rappel</a>, l&#8217;équipe de développement de JavaFX expliquait que leur vision était qu&#8217;après une certaine période de développement, les différentes plate-formes RIA convergeront vers un niveau de fonctionnalités similaire et que JavaFX pourrait alors briller du fait de son intégration native à Java. Cette version 1.3 semble bien une étape pour rattraper le (grand) retard face à l&#8217;environnement RIA d&#8217;Adobe en terme de fonctionnalités, il sera alors intéressant de voir si JavaFX pourra maintenant rattraper son retard en terme d&#8217;adoption.</p><h3><a
name="Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="DesbreaksdansScala"></a>Des breaks dans Scala !</h4><p>Avec la sortie de la <a
href="http://www.scala-lang.org/node/5982" title="RC1 de Scala 280" >RC1 de Scala 2.8.0</a>, la communauté est en ébullition et les articles sur les nouveautés de cette <em>release</em> majeure affluent sur la toile.</p><p>Ainsi, Scala ayant une syntaxe très <em>allégée</em> par rapport à Java, certains mots clés avaient tout simplement disparu du langage pour le malheur de certains java-istes. C&#8217;est le cas de <code>break</code>, souvent utilisé pour, par exemple, sortir d&#8217;une boucle, qui n&#8217;était jusqu&#8217;à présent pas disponible dans Scala. Le mot clé fait ainsi <a
href="http://daily-scala.blogspot.com/2010/04/breaks.html" title="son apparition dans cette version 280" >son apparition dans cette version 2.8.0</a>, non pas en tant que mot clé mais en tant que trait/object.</p><p>La syntaxe sera donc un petit peu différente par rapport à ce que nous avions l&#8217;habitude d&#8217;utiliser en Java. Il faudra ainsi englober le code pouvant être arrêté dans un <code>breakable</code>, l&#8217;appel à break restant le même :</p><pre class="brush: java; title: ; notranslate">
// Java
for(int i=0; i&lt;10; i++)
   if(i==5) break;
   i++;
}
//Scala
breakable {
   for(int i=0; i&lt;10; i++)
      if(i==5) break;
      i++;
   }
}
</pre><p>Rendez-vous sur cette <a
href="http://www.scala-lang.org/downloads#ReleaseCandidate" title="page" >page</a> pour télécharger cette RC1 de Scala 2.8.0 et essayer de toute urgence les breaks mais aussi les <code>Package objects</code>, la nouvelle API de collection, les paramètres nommés et par défaut, le tout nouveau REPL ainsi que beaucoup d&#8217;autres nouveautés !</p><h4><a
name="UnetroisimeimplmentationdeJPAf"></a>Une troisième implémentation de JPA 2 finalisée</h4><p>La communauté Java dispose maintenant d&#8217;une troisième implémentation de la <a
href="http://jcp.org/en/jsr/detail?id=317" title="JSR-317 (JPA 2.0)" >JSR-317 (JPA 2.0)</a> : <a
href="http://openjpa.apache.org/2010/04/22/openjpa-200-is-available.html" title="OpenJPA 20" >OpenJPA 2.0</a>. Ce projet de la fondation Apache est utilisé dans WebSphere AS et constitue de ce fait un choix d&#8217;implémentation pertinent.</p><p>OpenJPA succède donc à <a
href="http://www.eclipse.org/eclipselink/" title="EclipseLink" >EclipseLink</a> (qui étant l&#8217;implémentation de référence avait logiquement été finalisée en premier) et <a
href="http://www.hibernate.org" title="Hibernate" >Hibernate</a> (qui a finalisé sa version 3.5 conforme à JPA 2.0 <a
href="http://in.relation.to/15040.lace" title="le mois dernier" >le mois dernier</a>).</p><p>Les nouveautés d&#8217;OpenJPA 2.0 se limitent avant tout au support de JPA 2.0 ce qui inclut :</p><ul><li>La nouvelle API de construction de requêtes, basée sur l&#8217;interface <a
href="http://www.eclipse.org/eclipselink/api/1.2/javax/persistence/criteria/QueryBuilder.html" title="QueryBuilder" >QueryBuilder</a>, qui standardise et étend l&#8217;API Criteria d&#8217;Hibernate.</li><li>L&#8217;intégration à la <a
href="http://jcp.org/en/jsr/detail?id=303" title="JSR-303 (Bean Validation)" >JSR-303 (Bean Validation)</a> qui apporte une logique de validation uniforme pour toutes les couches d&#8217;une application JEE.</li><li>Une API de méta-modèle permettant de naviguer par programmation dans le modèle de données d&#8217;une unité de persistance.</li><li>Diverses améliorations des APIs JPA</li></ul><p>JPA avait connu une très large adoption par la communauté Java, mais on lui reprochait parfois quelques manquements qui nécessitaient de recourir aux APIs propriétaires de son implémentation. Ces ajouts permettent de contourner ces limites et donc de supprimer dans la plupart des cas le recours au fameux <code>entityManager.getDelegate()</code>.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/04/26/revue-de-presse-xebia-156/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Performance, les Xebians jouent les démineurs 3</title><link>http://blog.xebia.fr/2010/04/16/performance-les-xebians-jouent-les-demineurs-3/</link> <comments>http://blog.xebia.fr/2010/04/16/performance-les-xebians-jouent-les-demineurs-3/#comments</comments> <pubDate>Fri, 16 Apr 2010 09:00:30 +0000</pubDate> <dc:creator>Pablo Lopez</dc:creator> <category><![CDATA[Exploitation]]></category> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[datasource]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[jmeter]]></category> <category><![CDATA[JMX]]></category> <category><![CDATA[Performances]]></category> <category><![CDATA[threaddump]]></category> <category><![CDATA[VisualVM]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=4398</guid> <description><![CDATA[3ème épisode de notre série. Il est temps pour notre magnifique application de dépasser la barre symbolique de l&#8217;utilisateur unique. Mais comme nous nous sentons confiants et forts, nous allons pousser le vice de passer à, tenez vous bien, 5 utilisateurs concurrents. Et comme certains diraient, &#171;&#160;Et là, c&#8217;est le drame&#160;&#187;. Les temps se dégradent [...]]]></description> <content:encoded><![CDATA[<p>3ème épisode de notre série. Il est temps pour notre magnifique application de dépasser la barre symbolique de l&#8217;utilisateur unique. Mais comme nous nous sentons confiants et forts, nous allons pousser le vice de passer à, tenez vous bien, 5 utilisateurs concurrents. Et comme certains diraient, &laquo;&nbsp;Et là, c&#8217;est le drame&nbsp;&raquo;. Les temps se dégradent à vitesse grand V.</p><p>Pour rappel, nous avions laissé notre utilisateur unique avec un temps mirobolant de 1,7 secondes par requête en moyenne.</p><p>Le tableau ci dessous montre que la concurrence est nuisible à nos temps de réponse.</p><div
align="center"> <a
href="http://blog.xebia.fr/wp-content/uploads/2010/04/tempsInitial.png"><img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/tempsInitial670.png" alt="tempsInitial" title="tempsInitial" class="alignnone size-medium wp-image-4402" /></a></div><h3><a
name="Labaseuneressourcecritique"></a>La base une ressource critique.</h3><p>Première amélioration, quasiment gratuite. En allant chercher dans les problèmes que nous avions mis de coté (il y a quelques semaines sur le blog, mais quelques minutes auparavant lors du Xke <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> , nous pouvons exhumer le traçage de la totalité des requêtes SQL dans les fichiers de log. Cette fonctionnalité est bien connue des utilisateurs d&#8217;Hibernate (très pratique pour débugger), mais elle se retrouve malheureusement bien trop souvent en production.</p><pre class="brush: xml; title: ; notranslate">
&lt;prop key=&quot;hibernate.show_sql&quot;&gt;false&lt;/prop&gt;
</pre><p>Il suffit alors d&#8217;une simple modification dans la configuration d&#8217;Hibernate, d&#8217;un redéploiement, et miracle, les temps s&#8217;améliorent déjà un peu.</p><ul><li>hibernate.show_sql à false</li><li>Temps moyen de 8,2 s à 7,6 s pour 5 utilisateurs</li><li>1 point pour l&#8217;équipe qui a trouvé</li></ul><p>Après cette correction facile, attaquons nous à plus complexe.</p><p>Si la montée en charge induit une augmentation du temps de réponse, c&#8217;est que les utilisateurs sont en concurrence sur un certain type de ressource, ou bien qu&#8217;ils mettent la machine à genoux. Un rapide coup d&#8217;oeil dans VisualVm nous montre que la CPU et la mémoire ne sont pas saturées, on a donc à faire à une contention applicative.</p><p>Celles ci peuvent être de deux types :</p><ul><li>une concurrence applicative, <i>mal</i> gérée avec les outils fournis par <code>java.concurrent.util</code></li><li>une contention sur des ressources externes, comme un pool de connexions JDBC dans une DataSource.</li></ul><p>Comme nous étions déjà sur Hibernate dans la correction précédente, continuons à creuser le sillon. Et profitons en pour dégainer un nouvel outil de notre couteau suisse de diagnostic : JMX.<br
/> Pour vérifier si nos connexions JDBC sont bloquantes, utilisons l&#8217;api de monitoring de Java. Une fois de plus, utilisons notre VisualVm, qui propose une interface graphique d&#8217;affichage des MBeans.<br
/> Nous sommes chanceux, nos GO ont utilisé la dataSource standard de Tomcat, elle est donc exposée <code>Catalina:type=DataSource,class=javax.sql.DataSource,name="jdbc/petclinicMySQL"</code></p><div
align="center"> <a
href="http://blog.xebia.fr/wp-content/uploads/2010/04/numActive.png"><img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/numActive-300x152.png" alt="numActive" title="numActive" width="300" height="152" class="alignnone size-medium wp-image-4400" /></a></div><p>En procédant par sondage rapide (à l&#8217;aide de la fonction &#8216;refresh&#8217; du MBean), on constate rapidement que les valeurs <em>maxActive</em> et <em>numActive</em> se rejoignent autour de la valeur 3. Pas la peine d&#8217;en dire beaucoup plus&#8230; Comme d&#8217;habitude, la documentation va nous confirmer ce que nous pouvions supposer à la lecture de ces valeurs. <em>maxActive</em> nous donne le nombre maximal de connexion JDBC, alors que <em>numActive</em> nous donne celles qui sont utilisées à l&#8217;instant t. Ce qui signifie que lorsque les 3 connexions sont prises, les process suivant se mettent en attente, pendant un temps fixé par <em>maxWait</em> soit 3 secondes. Le goulet d&#8217;étranglement est évident. Il suffit donc de le fluidifier.</p><p>Ce paramétrage se trouve dans la configuration du serveur tomcat, dans le fichier <em>server.xml</em>. Nous allons agir sur deux paramètres : le <em>maxActive</em>, que nous allons positionner à 30 connexions (ce qui est plus que raisonnable) et sur le <em>maxWait</em> afin de ne pas attendre en vain une connexion qui ne viendra jamais.</p><pre class="brush: xml; title: ; notranslate">
&lt;GlobalNamingResources&gt;
    &lt;Resource name=&quot;jdbc/petclinicMySQL&quot; auth=&quot;Container&quot; type=&quot;javax.sql.DataSource&quot; driverClassName=&quot;org.gjt.mm.mysql.Driver&quot; url=&quot;jdbc:mysql://localhost:3306/petclinic_light?autoReconnect=true&quot; username=&quot;petclinic&quot; password=&quot;petclinic&quot; maxActive=&quot;30&quot; maxIdle=&quot;10&quot; removeAbandoned=&quot;true&quot; removeAbandonedTimeout=&quot;60&quot; logAbandoned=&quot;true&quot; maxWait=&quot;60&quot;/&gt;
&lt;/GlobalNamingResources&gt;
</pre><p>Les résultats sont immédiats et nous passons à un temps moyens de 7,2 s :</p><ul><li>Paramétrage de la datasource</li><li>Temps moyen de 7,6 s à 7,2 s pour 5 utilisateurs</li><li>2 points pour l&#8217;équipe qui a trouvé</li></ul><h3><a
name="CacoincetoujoursOletempsestilc"></a>Ca coince toujours. Où le temps est il consommé ?</h3><p>Pas la peine d&#8217;envisager de passer à plus d&#8217;utilisateurs tant que le temps moyen de requête est aussi catastrophique. Si l&#8217;on s&#8217;intéresse plus en détail aux résultats de JMeter, on constate que la requête <em>Owner detail</em> est la plus consommatrice. Sûrement quelque chose à optimiser de ce côté là.<br
/> On ne va pas déroger aux bonnes habitudes prises, on retourne dans VisualVm. Et quand quelque chose coince au niveau applicatif, on réalise un ensemble de ThreadDump. Comme nous sommes avides de nouveauté, nous allons laisser les commandes Unix <em>vi</em> et <em>grep</em> aux dinosaures et utiliser les possibilités de VisualVm, <a
href="https://visualvm.dev.java.net/plugins.html" title=" savoir le plugin Tda" >à savoir le plugin Tda</a>.</p><p>Pour mettre en évidence notre problème, nous allons tout d&#8217;abord restreindre les scenarii JMeter à la seule et unique requête <em>Owner Details</em>. Ensuite, nous allons réaliser une série de ThreadDump très rapproché (de 5 à 10 en quelques secondes). Nous allons ensuite utiliser une des possibilités de TDA, à savoir la détection des Thread longue durée <i><em>Long Running Thread</em></i>. TDA va tenter d&#8217;identifier les threads &#8216;bloqués&#8217; dans la même méthode au travers de n ThreadDump.<br
/> Comme auparavant, nous ne nous occuperons que des <em>catalina-exec-xx RUNNABLE</em>. Et nous avons de la chance, puisque sur nos cinq utilisateurs, nous trouvons 2 threads bloqués au même point, dans la même méthode (vous l&#8217;aurez compris, la détection de thread longue durée est principalement basée sur un &#8216;coup de sonde&#8217; statistique).</p><div
align="center"> <a
href="http://blog.xebia.fr/wp-content/uploads/2010/04/longRuningThreads.png"><img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/longRuningThreads-300x172.png" alt="longRuningThreads" title="longRuningThreads" width="300" height="172" class="alignnone size-medium wp-image-4399" /></a></div><p>Un petit tour dans le code, dans la classe incriminée.</p><pre class="brush: java; title: ; notranslate">
/**
     &lt;strong&gt; Custom handler for rendering images.
     &lt;/strong&gt;
     &lt;strong&gt; @param petId
     &lt;/strong&gt;            the ID of the pet whose visits to display
     &lt;strong&gt; @param response to output the image bytes
     &lt;/strong&gt; @throws IOException
     */
    @RequestMapping(value = &quot;/owners/*/pets/{petId}/image&quot;, method = RequestMethod.GET)
    public void petImageHandler(@PathVariable int petId, HttpServletResponse response) throws IOException {
        int imgId = petId % 6;
        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(&quot;img/pet-&quot; + imgId + &quot;.jpg&quot;);
        response.setContentType(&quot;image/jpeg&quot;);
        OutputStream out = response.getOutputStream();
        IoUtils.copy(in, out);
        clean();
    }
</pre><p>A priori, rien de très suspect dans la façon de servir des images stockées côté serveur (le but de l&#8217;exercice n&#8217;étant pas d&#8217;éliminer le problème, en changeant le comportement de l&#8217;application et en déplaçant ces images côté apache).<br
/> Si on revient à nos ThreadDump, nous constatons que nous pouvons encore descendre dans le code, à l&#8217;intérieur de la classe IoUtils.</p><pre class="brush: java; title: ; notranslate">
    public static void copy(InputStream in, OutputStream out) throws IOException {
        OutputStream bufferedOutputStream = new BufferedOutputStream(out);
        byte[] buffer = new byte[512];
        int length;
        while ((length = in.read(buffer)) &gt;= 0) {
            bufferedOutputStream.write(buffer, 0, length);
        }
        bufferedOutputStream.close();
    }
</pre><p>A priori, si les copies d&#8217;InputStream / Outputstream étaient à ce point sous performantes, cela se saurait. Mais ne mésestimons pas la fourberie de nos poseurs de bombes.</p><p>En y regardant de plus près, on constate en effet que nous avons une belle implémentation maison de la méthode write, inspirée de celle du <code>ByteArrayOutputstream</code>.</p><pre class="brush: java; title: ; notranslate">
public synchronized void write(int b) {
            int newcount = count + 1;
            if (newcount &gt; buf.length) {
                buf = Arrays.copyOf(buf, (buf.length &lt;&lt; 1) / 2 + 3);
            }
            buf[count] = (byte) b;
            count = newcount;
        }
</pre><p>Et là où le <code>ByteArrayOutputstream</code> se redimensionne de manière intelligente pour accélérer la copie</p><pre class="brush: java; title: ; notranslate">
    public synchronized void write(int b) {
	int newcount = count + 1;
	if (newcount &gt; buf.length) {
            buf = Arrays.copyOf(buf, Math.max(buf.length &lt;&lt; 1, newcount));
	}
	buf[count] = (byte)b;
	count = newcount;
    }
</pre><p>, l&#8217;implémentation maison reste définitivement bloquée et recopie les octets 2 à 2&#8230;</p><p>Si nous remplaçons cette implémentation par <code>java.io.BufferedOutputstream</code>, nous devrions avoir de bien meilleurs résultats.</p><div
align="center"> <a
href="http://blog.xebia.fr/wp-content/uploads/2010/04/tempsFinal.png"><img
src="http://blog.xebia.fr/wp-content/uploads/2010/04/tempsFinal670.png" alt="tempsFinal" title="tempsFinal"  class="alignnone size-medium wp-image-4401" /></a></div><p>Et en effet cette fois, c&#8217;est spectaculaire. Pour nos cinq utilisateurs, nous passons à un temps moyen de 1,4 s avec une très remarquée dégringolade du temps moyen de <em>ownersDetail</em> qui passe de 32 s à 3,7 s.</p><ul><li>Suppression d&#8217;un java.io maison</li><li>Temps moyen de 7,2 s à 1,4 s pour 5 utilisateurs</li><li>3 points pour l&#8217;équipe qui a trouvé</li></ul><p>Il va bientôt être temps de passer à un nombre d&#8217;utilisateurs &laquo;&nbsp;raisonnable&nbsp;&raquo;.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2010/04/16/performance-les-xebians-jouent-les-demineurs-3/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2009/12/28/revue-de-presse-xebia-140/</link> <comments>http://blog.xebia.fr/2009/12/28/revue-de-presse-xebia-140/#comments</comments> <pubDate>Mon, 28 Dec 2009 19:02:30 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[Cloud Computing]]></category> <category><![CDATA[EC2]]></category> <category><![CDATA[GAE]]></category> <category><![CDATA[GlassFish]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[IBM]]></category> <category><![CDATA[J2EE]]></category> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[JBoss]]></category> <category><![CDATA[JEE]]></category> <category><![CDATA[JEE6]]></category> <category><![CDATA[JGroups]]></category> <category><![CDATA[JPA]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring Security]]></category> <category><![CDATA[Sun]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=3665</guid> <description><![CDATA[La revue de presse de l&#8217;actualité Java/J2EE hebdomadaire proposée par Xebia. Actualité éditeurs / SSII Le meilleur de The Server Side Le coin de la technique Spring Security seulement un alignement sur Spring 3.0 ? Tour d&#8217;horizon de JBoss Infinispan JGroups à l&#8217;heure du Cloud Computing Actualité éditeurs / SSII Le meilleur de The Server [...]]]></description> <content:encoded><![CDATA[<p><img
style="margin: 1em 1em 1em 1em; float: right;" src="http://blog.xebia.fr/wp-content/uploads/2007/06/revuedepresse.png" alt="Revue de Presse Xebia" /><br
/> <em>La revue de presse de l&#8217;actualité Java/J2EE hebdomadaire proposée par Xebia.</em></p><p><strong>Actualité éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2009/12/28/revue-de-presse-xebia-140/#LemeilleurdeTheServerSide">Le meilleur de The Server Side</a></li></ul><p><strong>Le coin de la technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2009/12/28/revue-de-presse-xebia-140/#SpringSecurityseulementunalign">Spring Security seulement un alignement sur Spring 3.0 ?</a></li><li><a
href="http://blog.xebia.fr/2009/12/28/revue-de-presse-xebia-140/#TourdhorizondeJBossInfinispan">Tour d&#8217;horizon de JBoss Infinispan</a></li><li><a
href="http://blog.xebia.fr/2009/12/28/revue-de-presse-xebia-140/#JGroupslheureduCloudComputing">JGroups à l&#8217;heure du Cloud Computing</a></li></ul><h3><a
name="ActualitditeursSSII"></a>Actualité éditeurs / SSII</h3><h4><a
name="LemeilleurdeTheServerSide"></a>Le meilleur de The Server Side</h4><p>Avec les fêtes vient le temps des rétrospectives. Et c&#8217;est TheServerSide qui ouvre le bal, avec son hit parade des neuf fils de discussion les plus vus en 2009. Sans surprise, on retrouve quelques stars de l&#8217;année, dont la popularité ne devrait pas faiblir en 2010 : <a
title="JavaEE 6" href="http://www.theserverside.com/news/thread.tss?thread_id=53459">JavaEE 6</a> et <a
title="Glassfish 3" href="http://www.theserverside.com/news/thread.tss?thread_id=58858">Glassfish 3</a>, la persistance (<a
title="JPA" href="http://www.theserverside.com/news/thread.tss?thread_id=53142">JPA</a>, <a
title="les caches d'Hibernate" href="http://www.theserverside.com/news/thread.tss?thread_id=53716">les caches d&#8217;Hibernate</a>, <a
title="la démarcation transactionnelle avec Spring" href="http://www.theserverside.com/news/thread.tss?thread_id=53529">la démarcation transactionnelle avec Spring</a>)&#8230; Mais aussi les buzz de l&#8217;année : <a
title="Google App Engine" href="http://www.theserverside.com/news/thread.tss?thread_id=54215">Google App Engine</a>, <a
title="les langages next-gen" href="http://www.theserverside.com/news/thread.tss?thread_id=55185">les langages next-gen</a>&#8230; On trouve ensuite un grand article communautaire, <a
title="sur ce que doit savoir un architecte applicatif" href="http://www.theserverside.com/news/thread.tss?thread_id=53819">sur ce que doit savoir un architecte applicatif</a>.<br
/> Enfin, et nous devons bien avouer qu&#8217;à la vue des évènements passés, cela prête à sourire, un très beau fil de prospective : <a
title="IBM parle de racheter Sun" href="http://www.theserverside.com/news/thread.tss?thread_id=54007">IBM parle de racheter Sun</a>.</p><p>Cette première rétrospective reflète pour nous bien les tendances de l&#8217;année passée : pas mal de grandes manœuvres chez les éditeurs, des <em>concurrents</em> à Java de plus en plus présent, un nouvelle spécification très attendue, et des frameworks incontournables qui continuent à mener la danse.</p><h3><a
name="Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="SpringSecurityseulementunalign"></a>Spring Security seulement un alignement sur Spring 3.0 ?</h4><p>Dans la foulée de la sortie de la version 3 de Spring Framework, c&#8217;est au tour de Spring Security de faire <a
title="son annonce" href="http://www.springsource.org/node/2271">son annonce</a>. Le point le plus marquant de cette version est l&#8217;utilisation du Spring Expression Language pour décrire les règles de contrôle d&#8217;accès qui simplifieront des vérifications simples comme <code>@PreAuthorize("#contact.name == principal.name)")</code> et surtout, couplé à des classes java transverses de sécurité, permettra d&#8217;effectuer élégamment des contrôles déclaratifs sophistiqués tels que :</p><pre class="brush: java; title: ; notranslate">
@PreAuthorize(&quot;isPhysician(#patientFile.patient)&quot;)
public void create(PatientFile patientFile);
</pre><p>Bien sûr, il faudra programmer la méthode <code>isPhysician()</code>, Spring Security ne se substituera pas au code métier de votre application, il sera juste une aide précieuse <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .<br
/> Nous noterons au passage que l&#8217;<em>Expression Language</em> apporte à l&#8217;<em>Aspect Oriented Programming</em> le haut niveau d&#8217;abstraction qui permet de programmer des fonctionnalités métiers transverses sans être un spécialiste de la plomberie <code>ProceedingJoinPoint</code> et autres joyeusetés. L&#8217;AOP devient alors beaucoup plus accessible pour les développeurs d&#8217;informatique de gestion.</p><p>Les autres nouveautés que nous garderons en tête : des contrôles pré et post traitement (<code>@PreAuthorize</code> et <code>@PostAuthorize</code>), la restructuration des jars similaire à celle que Spring 2.5 a connu, et une clarification des règles de redirection post authentification.</p><h4><a
name="TourdhorizondeJBossInfinispan"></a>Tour d&#8217;horizon de JBoss Infinispan</h4><p>Le projet <a
title="Infinispan" href="http://www.jboss.org/infinispan.html">Infinispan</a> a été <a
title="initié en milieu d'année 2009" href="http://blog.xebia.fr/2009/05/04/revue-de-presse-xebia-107/#JBossveutsonDataGrid">initié en milieu d&#8217;année 2009</a> chez JBoss. Il s&#8217;agit d&#8217;une évolution de <a
title="JBoss Cache" href="http://www.jboss.org/jbosscache/">JBoss Cache</a> d&#8217;un simple cache vers un DataGrid.</p><p>Dans le <a
title="dernier pisode en date de JBoss Asylum" href="http://asylum.libsyn.com/index.php?post_id=562565">dernier épisode en date de JBoss Asylum</a>, le podcast dédié à la communauté JBoss maintenu par Emmanuel Bernard et Max R Andersen, Mark Surtani, <em>leader</em> du projet Infinispan, était invité pour parler de son projet. Il a pu faire un tour d&#8217;horizon global en commençant par le lien entre JBoss Cache et Infinispan :</p><ul><li>Contrairement à JBoss Cache qui utilisait une organisation arborescente, Infinispan se base uniquement sur une structure clé-valeur à plat.</li><li>Tout comme le faisait JBoss Cache, Inifinispan utilise JGroups pour assurer la découverte de ses instances.</li><li>Une API d&#8217;adaptation permettra d&#8217;assurer la transition entre JBoss Cache et Infinispan, notamment en offrant une arborescence au dessus de la structure de base d&#8217;Infinispan. Des outils seront fournis afin de migrer les fichiers de configuration.</li></ul><p>Manik Surtani a également abordé les fonctionnalités à venir, après la finalisation de la première version, dévoilant ainsi les ambitions de positionnement de ce produit :</p><ul><li>Utilisation de Lucene pour offrir une API de requêtes puissante permettant des recherches dans le DataGrid. Plusieurs possibilités d&#8217;architecture ont été évoquées telles que la réplication d&#8217;un index complet sur l&#8217;ensemble des noeuds ou la distribution de <em>shards</em> de l&#8217;index complet sur les noeuds via l&#8217;utilisation d&#8217;un <code>InfinispanDirectory</code> pour Lucene, actuellement en cours de développement.</li><li>Intégration éventuelle avec Hibernate Search. Infinispan se substituerait à Hibernate Core et Hibernate Search lui apporterait alors la fonctionnalité de recherche.</li><li>Possibilité d&#8217;effectuer des <em>continuous requests</em> pour que les résultats d&#8217;une requête s&#8217;enrichissent au fur et a mesure de l&#8217;arrivée de données sur la grille.</li><li>API de MapReduce permettant de soumettre un <code>Callable</code> et un ensemble de clés d&#8217;objets sur lesquels doivent s&#8217;appliquer le traitement pour obtenir un <code>Future</code> représentant le résultat, à venir, après opération de réduction.</li></ul><p>La plupart des fonctionnalités évoquées sont présentes dans les produits commerciaux que sont <a
title="Oracle Coherence" href="http://www.oracle.com/technology/products/coherence/index.html">Oracle Coherence</a> ou <a
title="IBM eXtreme Scale" href="http://www.ibm.com/software/webservers/appserv/extremescale/">IBM eXtreme Scale</a>. Toutefois, de telles possibilités seraient inédites dans un produit Open Source ce qui devrait faire d&#8217;Inifinispan un produit très intéressant à suivre en 2010&#8230;</p><h4><a
name="JGroupslheureduCloudComputing"></a>JGroups à l&#8217;heure du Cloud Computing</h4><p>JGroups est un <em>framework</em> permettant la communication au sein d&#8217;un groupe de serveurs. Actuellement développé au sein de JBoss, il est à la base de nombreux <em>middlewares</em> et frameworks d&#8217;entreprise permettant un fonctionnement distribué tels que JBoss Cache ou plus récemment Infinispan.</p><p>Après un an sans mise à jour majeure, Bela Ban, <em>leader</em> du projet, <a
title="annonce la version 28" href="http://belaban.blogspot.com/2009/12/jgroups-280ga-released.html">annonce la version 2.8</a>. Outre de nombreuses évolutions améliorant la flexibilité de JGroups, un apport notable s&#8217;est glissé dans la liste : le support d&#8217;Amazon EC2. Il s&#8217;agit là d&#8217;une nouveauté emblématique de cette année 2009 qui va se conclure ; la majorité des <em>frameworks</em> cherche à afficher une compatibilité voire une synergie avec les environnements de Cloud Computing courant.<br
/> En pratique, cette intégration de JGroups à EC2 se fait par l&#8217;ajout d&#8217;un nouveau protocole de découverte de voisinage nommé S3_PING. Comme son nom l&#8217;indique, il utilise un stockage S3 commun dans lequel tous les membres d&#8217;un groupe écrivent leurs coordonnées. Ce mécanisme est particulièrement bien adapté à EC2 qui, de part la topologie réseau qu&#8217;il offre, ne permet pas le <em>multicasting</em> et n&#8217;est guère adapté aux autres protocoles de découvertes qui existaient jusqu&#8217;alors dans JGroups.</p><p>Notons tout de même que la principale nouveauté de cette version 2.8 est l&#8217;ajout du concept d&#8217;adresse logique que Bela Ban <a
title="presentait il y a quelques mois" href="http://belaban.blogspot.com/2009/02/whats-cool-about-logical-addresses.html">présentait il y a quelques mois</a>. Une adresse logique permet de découpler l&#8217;identité d&#8217;un nœud JGroups de son adresse réseau ; l&#8217;association entre adresse logique et physique est résolue lors de la découverte des nœuds. Outre le découplage offert par ce concept, ces adresses permettent également de simplifier la gestion des pertes de messages lors de la ré-incarnation d&#8217;un nœud suite a son indisponibilité temporaire.</p><p>10 ans après sa création, JGroups continue donc de se maintenir à jour et, dans la mesure où il remplit toujours parfaitement son rôle, il devrait rester présent encore des années dans plusieurs <em>middlewares</em> et <em>frameworks</em> majeurs.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/12/28/revue-de-presse-xebia-140/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Devoxx &#8211; Jour 2 &#8211; Hibernate Search</title><link>http://blog.xebia.fr/2009/11/23/devoxx-jour-2-hibernate-search/</link> <comments>http://blog.xebia.fr/2009/11/23/devoxx-jour-2-hibernate-search/#comments</comments> <pubDate>Mon, 23 Nov 2009 10:03:39 +0000</pubDate> <dc:creator>Romain Maton</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Devoxx]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Hibernate Search]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=3248</guid> <description><![CDATA[Pour le deuxième jour d&#8217;université, Emmanuel Bernard nous propose une présentation d&#8217;Hibernate Search avec une approche globale du produit : qu&#8217;est-ce qu&#8217;une recherche Full Text, le fonctionnement d&#8217;une recherche, les annotations sur nos objets métiers et les différentes recherches possible. L&#8217;application JBoss DVD Store utilisée tout au long de la session permettra de mettre en [...]]]></description> <content:encoded><![CDATA[<p>Pour le deuxième jour d&#8217;université, Emmanuel Bernard nous propose une <a
href="http://www.devoxx.com/display/DV09/Hibernate+Search+university" title="prsentation dHibernate Search" >présentation d&#8217;Hibernate Search</a> avec une approche globale du produit : qu&#8217;est-ce qu&#8217;une recherche <em>Full Text</em>, le fonctionnement d&#8217;une recherche, les annotations sur nos objets métiers et les différentes recherches possible. L&#8217;application <em>JBoss DVD Store</em> utilisée tout au long de la session permettra de mettre en avant la recherche <em>Full Text</em> et les différentes requêtes possibles (<em>batmen</em> au lieu de <em>batman</em>).</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2009/11/hs_speaker.jpg" border="0" alt="" /></div><p>Nous avons déjà publié plusieurs articles sur Hibernate Search : de l&#8217;<a
href="http://blog.xebia.fr/2008/03/06/introduction-a-hibernate-search-googling-your-persistent-domain-model/" title="introduction" >introduction</a> qui se focalisera sur l&#8217;architecture de l&#8217;outil au <a
href="http://blog.xebia.fr/2008/03/28/hands-on-hibernate-search-recherche-full-text/" title="Hands On" >Hands On</a> qui vous permettra de mettre les mains dedans. Les différentes recherches <em>Full Text</em> disponibles (appoximation, phonétique&#8230;) ont aussi été résumées dans le compte-rendu de la <a
href="http://blog.xebia.fr/2009/06/28/jazoon-jour-3-hibernate-search/" title="prsentation de loutil  Jazoon" >présentation de l&#8217;outil à Jazoon</a>.</p><p>Le speaker insistera surtout sur la <em>convention over configuration</em> une approche programmatique du produit. Après l&#8217;énumération des annotations possibles (<code>@Indexed</code>, <code>@Field</code>, <code>@FieldBridge</code>, <code>@IndexedEmbededd</code>, <code>@Boost</code> et <code>@Analyzer</code>), les premières questions sur la configuration par XML tombent et la réponse est assez direct : <em>Because we hate XML</em> <img
src='http://blog.xebia.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Il enchaîne ensuite avec quelques slides d&#8217;architecture. On retiendra ainsi que Hibernate Search est construit sur Hibernate Core, que le produit est <em>Event Based</em> et que l&#8217;indexation manuelle massive est optimisée. Un slide nous montrera les différentes étapes d&#8217;une recherche avec Hibernate Search, tout d&#8217;abord un appel à <a
href="http://lucene.apache.org/java/docs/" title="Lucne" >Lucène</a> pour récupérer nos documents et, si besoin, un appel au cache ou à la base de données pour récupérer les entités souhaitées.</p><p>Emmanuel terminera avec une Road Map plutôt chargée dont :</p><ul><li>Amélioration des performances de l&#8217;API programmatique.</li><li>Indexation massive multi-threadée.</li><li>Clustering (travail en collaboration avec Infinispan).</li><li>Meilleure intégration avec <a
href="http://lucene.apache.org/solr/" title="Solr" >Solr</a>.</li><li>Amélioration des <code>Query</code> (construction simplifiée&#8230;).</li><li>Statistiques.</li></ul><p>Pas de date de sortie prévue pour cette nouvelle version mais il est toujours possible de jouer avec <a
href="https://www.hibernate.org/410.html" title="Hibernate Search 311 GA" >Hibernate Search 3.1.1 GA</a> (version actuelle du produit qui date de 6 mois) et de mettre en œuvre quelques recherches <em>Full Text</em> !</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/11/23/devoxx-jour-2-hibernate-search/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/</link> <comments>http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/#comments</comments> <pubDate>Mon, 22 Jun 2009 16:19:03 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[Adobe]]></category> <category><![CDATA[GAE]]></category> <category><![CDATA[Gilead]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Hibernate Shards]]></category> <category><![CDATA[J2EE]]></category> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[jazoon]]></category> <category><![CDATA[Jigsaw]]></category> <category><![CDATA[OSGi]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[Vaadin]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=2304</guid> <description><![CDATA[La revue de presse de l’actualité Java/J2EE hebdomadaire proposée par Xebia. RIA Vaadin 6 Adaptateur Gilead pour GAE Une série d&#8217;annonces chez Adobe Le coin de la technique Scalabilité avec Hibernate et Shards Jigsaw vs OSGi Pourquoi utiliser un portail ? Embarquer le Web dans Java avec JWebPane Evènements de notre communauté en France et [...]]]></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 de l’actualité Java/J2EE hebdomadaire proposée par Xebia.</em></p><p><strong>RIA</strong></p><ul><li><a
href="http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/#Vaadin">Vaadin 6</a></li><li><a
href="http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/#AdaptateurGileadpourGAE">Adaptateur Gilead pour GAE</a></li><li><a
href="http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/#UnesriedannonceschezAdobe">Une série d&#8217;annonces chez Adobe</a></li></ul><p><strong>Le coin de la technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/#ScalabilitavecHibernateetShard">Scalabilité avec Hibernate et Shards</a></li><li><a
href="http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/#JigsawvsOSGi">Jigsaw vs OSGi</a></li><li><a
href="http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/#Pourquoiutiliserunportail">Pourquoi utiliser un portail ?</a></li><li><a
href="http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/#EmbarquerleWebdansJavaavecJWeb">Embarquer le Web dans Java avec JWebPane</a></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/2009/06/22/en-route-pour-jazoon-09/">Xebia @ Jazoon 09</a></li></ul><h3><a
name="RIA"></a>RIA</h3><h4><a
name="Vaadin"></a>Vaadin 6</h4><p>Au revoir <a
href="http://www.itmill.com/" title="IT Mill Toolkit" >IT Mill Toolkit</a> et bienvenue à <a
href="http://vaadin.com/home" title="Vaadin" >Vaadin</a> (vu sur leur <a
href="http://vaadin.com/blog/-/blogs/vaadin-6-server-driven-ria-framework-announced-the-next-generation-of-it-mill-toolkit" title="blog" >blog</a>) !</p><p>Pour ceux qui ne le connaissent pas encore, Vaadin (anciennement IT Mill Toolkit) est un framework de développement d&#8217;applications RIA qui s&#8217;appuie sur GWT. Sa particularité est d&#8217;être <em>runtime</em> donc aucune compilation spécifique n&#8217;est demandée avant de packager la webapp (à l&#8217;inverse de GWT).</p><p>Simple changement de nom ? En tout cas très peu de changement côté API selon les auteurs du framework. Il faut plutôt se tourner vers l&#8217;outillage pour voir quelques nouveautés : un <a
href="http://vaadin.com/eclipse" title="plugin eclipse" >plugin eclipse</a> (création de projets, de composants UI, de thèmes&#8230;) et, inclus dans le plugin, un <a
href="http://vaadin.com/image/image_gallery?uuid=93600d15-df24-4299-b3d1-77a91d17624c&#038;groupId=10904&#038;t=1241865010814" title="diteur WYSIWYG" >éditeur WYSIWYG</a>.</p><p>Côté liens utiles, l&#8217;habituel <a
href="http://demo.vaadin.com/sampler/" title="showcase" >showcase</a>, le <a
href="http://vaadin.com/book" title="livre" >livre</a> et la <a
href="http://vaadin.com/comparison" title="comparaison maison" >comparaison maison</a> avec les autres frameworks du marché (et la concurrence est rude dans le monde du RIA).</p><p>A noter que <a
href="http://vaadin.com/blog/-/blogs/vaadin-at-jazoon-09?_33_redirect=%2Fhome" title="Vaadin" >Vaadin</a> sera présent à <a
href="http://jazoon.com/" title="Jazoon" >Jazoon</a> pour une conférence sur <a
href="http://jazoon.com/en/conference/presentationdetails.html?type=sid&#038;detail=8360" title="RIA Security" >RIA Security</a> le mardi 23 juin à 15h (slides, projet et autres sur <a
href="http://vaadin.com/web/joonas/wiki/-/wiki/Main/RIA+Security" title="cette page" >cette page</a>).</p><h4><a
name="AdaptateurGileadpourGAE"></a>Adaptateur Gilead pour GAE</h4><p>Vous connaissez <a
href="http://blog.xebia.fr/2009/01/23/gwt-galaxy/" title="GWT" >GWT</a>, <a
href="http://blog.xebia.fr/2008/12/17/integrer-hibernate-avec-gwt-sans-douleur/" title="Gilead" >Gilead</a>, et <a
href="http://blog.xebia.fr/2009/04/14/revue-de-presse-xebia-104/#GoogleAppEnginepourJavaetGroov" title="Google App Engine" >Google App Engine</a> ? Et bien il ne reste plus qu&#8217;à mélanger tout ça et on obtient le <a
href="http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/69d5ccd01240a59c" title="Gilead GWT adapter for Google AppEngine" >Gilead GWT adapter for Google AppEngine</a> (vu sur le <a
href="http://googlewebtoolkit.blogspot.com/2009/06/gwt-community-updates.html" title="GWT Blog" >GWT Blog</a>).</p><p>Tout démarre d&#8217;un <a
href="http://groups.google.com/group/Google-Web-Toolkit-Contributors/browse_thread/thread/3c768d8d33bfb1dc" title="thread google groups" >thread google groups</a> avec comme point de départ la <em>serialization exception</em> lancée par les entités persistantes transférées vers GWT. Évidemment, la solution qui ressort <a
href="http://groups.google.com/group/Google-Web-Toolkit-Contributors/msg/c4e6d22860a7df3d" title="très rapidement" >très rapidement</a>, outre l&#8217;utilisation de DTOs, est de passer par <a
href="http://noon.gilead.free.fr/gilead/index.php?page=presentation" title="Gilead" >Gilead</a> pour transformer nos entités persistantes en POJOs. Il suffit d&#8217;ajouter le jar <code>adapter4appengine</code> et de remplacer la classe <code>PersistentRemoteService</code> par <code>EngineRemoteService</code> dans vos remotes services. Dès lors, il sera possible d&#8217;envoyer ses entités persistantes vers le client GWT sans exceptions de sérialisation sur <a
href="http://code.google.com/intl/fr/appengine/" title="GAE" >GAE</a>.</p><p>1.0 M2 téléchargeable à cette <a
href="http://sourceforge.net/project/downloading.php?group_id=239931&#038;filename=adapter4appengine-1.0M2.jar&#038;a=91098275" title="url" >url</a>, documentation <a
href="http://noon.gilead.free.fr/gilead/index.php?page=adapter4appengine" title="par ici" >par ici</a>. Attention toutefois, cette version n&#8217;est pas production ready.</p><h4><a
name="UnesriedannonceschezAdobe"></a>Une série d&#8217;annonces chez Adobe</h4><p>Après l&#8217;annonce de la sortie de la plateforme Flash il y a quelques semaines, voici une nouvelle série d&#8217;annonce de la part d&#8217;Adobe.</p><p>Pour commencer, deux news relayées par Andrew Twice dans <a
href="http://www.insideria.com/2009/06/its-an-active-news-day-from-ad.html" title="InsideRIA" >InsideRIA</a>.<br
/> La première concerne la sortie d&#8217;<a
href="http://labs.adobe.com/technologies/tables/" title="Adobe Table" >Adobe Table</a> en version bêta. Cet outil permet de créer des feuilles de calcul, des plannings ou encore des listes de tâches en ligne:</p><ul><li>Les utilisateurs peuvent ajouter des données en même temps: les données sont mises à jour en temps réel pour tout le monde.</li><li>Possibilité de savoir qui travaille sur Adobe Table.</li><li>Création d&#8217;écrans communs et privés : les utilisateurs peuvent travailler de manière coopérative, et/ou créer des espaces privés pour ne garder que les informations importantes.</li><li>Filtrage : les utilisateurs peuvent filtrer leurs données en temps réel.</li><li>Tri.</li></ul><p>Similaire à <a
href="http://www.google.com/google-d-s/intl/fr/tour1.html" title="Google Document" >Google Document</a>, cet outil a été développé sur la plateforme Flash et va continuer <a
href="http://blogs.adobe.com/acom/2009/06/shared_tables_for_shared_data_1.html" title="à évoluer" >à évoluer</a>. La <a
href="https://labs1.acrobat.com" title="démo" >démo</a> se passe <a
href="https://labs1.acrobat.com" title="ici" >ici</a>, la seule contrainte : avoir un compte Adobe.</p><p>La deuxième annonce concerne l&#8217;ouverture de la spécification de Real-Time Messaging Protocol (RTMP). Comme nous en avions parlé <a
href="http://blog.xebia.fr/2009/01/26/revue-de-presse-xebia-93/#Adobecontinuelouverturedeseste" title="ici" >ici</a>, la spécification a été publiée lundi dernier.</p><p>Enfin, Michael Chaize parle de la <a
href="http://codemoiunmouton.wordpress.com/2009/06/18/livecycle-data-services-3/" title="sortie de LiveCycle Data Services 3" >sortie de LiveCycle Data Services 3</a> en bêta. Disponible sur le <a
href="http://labs.adobe.com/technologies/livecycle_dataservices3/" title="labs d'Abobe" >labs d&#8217;Abobe</a>, cette nouvelle version propose une meilleure qualité de service pour des applications dont la fiabilité est primordiale telles que les applications bancaires par exemple. Venant compléter la plateforme Flash (avec Flex 4 et Flash Builder 4), Adobe incite la communauté à faire ses retours sur le <a
href="http://forums.adobe.com/community/labs" title="forum" >forum</a>.</p><h3><a
name="Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="ScalabilitavecHibernateetShard"></a>Scalabilité avec Hibernate et Shards</h4><p>Une <a
href="http://www.infoq.com/presentations/Scaling-Hibernate-Emmanuel-Bernard-Max-Ross" title="session de QCon 2008" >session de QCon 2008</a>, traitant de la scalabilité d&#8217;Hibernate, vient d&#8217;être mise en ligne. Présentée par Emmanuel Bernard, <em>project lead</em> d&#8217;Hibernate Search, et Max Ross, <em>project lead</em> d&#8217;Hibernate Shards, cette présentation offre une approche peu courante sur un problème pourtant récurrent.</p><p>Outre les classiques solutions permettant d&#8217;éviter certaines pertes de performance avec l&#8217;augmentation du volume traité, telles que la bonne gestion du cache, et les optimisations SQL, il a été question d&#8217;utiliser Hibernate Search et Hibernate Shards.</p><p><a
href="https://www.hibernate.org/410.html" title="Hibernate Search" >Hibernate Search</a> est connu pour sa capacité à simplifier les recherches dans un ensemble d&#8217;entités grâce à l&#8217;utilisation de <a
href="http://lucene.apache.org/" title="Lucene" >Lucene</a> conjointement à la base de données. Emmanuel Bernard proposait ici de déléguer à Search certaines recherches qui s&#8217;avèrent très coûteuses à effectuer en base. Lucene étant placé sur une machine séparée, et pouvant même fonctionner en maître / esclave, il est ainsi possible d&#8217;obtenir une intéressante répartition de la charge.</p><p><a
href="https://www.hibernate.org/414.html" title="Hibernate Shards" >Hibernate Shards</a>, bien que plus ancien, est moins répandu du fait qu&#8217;aucune version finale n&#8217;a encore été produite. Il s&#8217;agit d&#8217;un module additionnel pour Hibernate permettant à une application de manipuler des données partitionnées sur plusieurs BDD. Le but étant d&#8217;encapsuler la conscience du partitionnement des données au sein de la couche Hibernate afin que l&#8217;application n&#8217;ait pas à gérer cette problématique. Les possibilités du framework sont intéressantes :</p><ul><li>La gestion correcte des Criterias sur des données partitionnées grâce à <a
href="http://docs.jboss.org/hibernate/stable/shards/api/org/hibernate/shards/criteria/ShardedCriteria.html" title="ShardedCriteria" ><code>ShardedCriteria</code></a>.</li><li><a
href="http://docs.jboss.org/hibernate/stable/shards/reference/en/html_single/#shards-resharding-virtual" title="Virtual Shards" >Virtual Shards</a> permettant de faire la distinction entre <em>shard</em> logique et <em>shard</em> physique et ainsi d&#8217;augmenter le nombre d&#8217;instances de base de données au fur et à mesure de l&#8217;augmentation des besoins.</li><li><a
href="http://docs.jboss.org/hibernate/stable/shards/reference/en/html_single/#shards-strategy-idgen" title="Generation dIDs" >Generation d&#8217;IDs</a> compatibles avec l&#8217;utilisation sous-jacente de plusieurs BDDs grâce à l&#8217;utilisation d&#8217;UUIDs.</li><li>Gestion correcte de BDDs hétérogènes.</li></ul><p>Ce sont finalement les fonctionnalités manquantes qui permettent de comprendre pourquoi Shards est toujours en version bêta. Max Ross s&#8217;est expliqué il y a plusieurs mois sur les problématiques rencontrées, de manière succincte <a
href="http://groups.google.com/group/hibernate-shards-dev/browse_thread/thread/74c14afd6d341afa#" title="sur un forum" >sur un forum</a> et plus longuement <a
href="http://www.javaworld.com/podcasts/jtech/2008/072408jtech.html" title="dans une interview" >dans une interview</a>. De nombreux défis restent ainsi à relever concernant la gestion correcte des agrégations dans les <a
href="http://docs.jboss.org/hibernate/stable/shards/api/" title="ShardedQuery" ><code>ShardedQuery</code></a> et la fourniture d&#8217;outils d&#8217;aide au partitionnement et repartitionnement des données.<br
/> Max Ross est employé par Google et non par JBoss, tout comme les deux autres <em>committers</em> du projet (le code ayant été donné à JBoss par Google), et affirme ne disposer que de 20 % de son temps pour Shards. Ceci n&#8217;explique que partiellement <a
href="http://fisheye.jboss.com/browse/Hibernate/shards/" title="le peu de commits" >le peu de commits</a> sur le projet et ne nous rassure guère quant à sa finalisation prochaine.</p><h4><a
name="JigsawvsOSGi"></a>Jigsaw vs OSGi</h4><p>Sept mois après le démarrage du projet <a
href="http://openjdk.java.net/projects/jigsaw" title="Jigsaw" >Jigsaw</a>, sa légitimité n&#8217;est toujours pas reconnue face à OSGi qu&#8217;il est venu défier sur son propre terrain.</p><p>La semaine dernière <a
href="http://javaposse.com/index.php?post_id=492239" title="JavaPosse diffusait une interview" >JavaPosse diffusait une interview</a> de Mark Reinhold et Alex Buckley, où ils ont pu présenter plus en détail leur vision de Jigsaw :</p><ul><li>Il a été conçu pour modulariser le JDK et est intégré au langage.</li><li>Il ne repose pas sur une spécification car cela n&#8217;était pas possible compte tenu du calendrier de JDK 7. Il est donc à considérer comme un &laquo;&nbsp;détail d&#8217;implémentation&nbsp;&raquo; tout comme la gestion du classpath l&#8217;était dans les JVMs précédentes.</li><li>Il n&#8217;est pas supposé entrer en concurrence avec OSGi, des outils permettant l&#8217;intégration entre modules Jigsaw et <em>bundles</em> OSGi étant prévus, mais non prioritaires.</li></ul><p>Dans le même temps, Eric Newcomer (<em>Co-Chair</em>, <em>Enterprise Expert Group</em> de l&#8217;OSGi Alliance), postait <a
href="http://modualrit.blogspot.com/2009/06/osgi-standard-questions.html" title="une série" >une série</a> <a
href="http://modualrit.blogspot.com/2009/06/kill-project-jigsaw-now-please.html" title="de billets" >de billets</a> très virulents à l&#8217;égard du projet Jigsaw, reprochant principalement que Sun n&#8217;ait pas voulu se tourner vers OSGi, ne cherchant pas à combler les manques qu&#8217;il y trouvait, se tournant immédiatement vers une nouvelle technologie et ignorant donc les 10 années d&#8217;expérience acquises par OSGi.</p><p>En fait, il semble n&#8217;y avoir aucune justification technique permettant d&#8217;expliquer l&#8217;orientation de Sun vers Jigsaw plutôt que vers OSGi ou vers une évolution d&#8217;OSGi intégrée au langage. La véritable raison serait alors à chercher sur le plan politique : la modularisation est un concept important qui manque à Java actuellement et Sun ne pouvait probablement pas se permettre, pour l&#8217;ajout d&#8217;un tel concept, de s&#8217;appuyer sur une spécification émise en dehors du JCP sur lequel il a la gouvernance.</p><h4><a
name="Pourquoiutiliserunportail"></a>Pourquoi utiliser un portail ?</h4><p>Le <a
href="http://lescastcodeurs.com/2009/06/les-cast-codeurs-podcast-episode-6-portal-ma/" title="dernier podcast des Cast Codeurs" >dernier podcast des Cast Codeurs</a> était l&#8217;occasion d&#8217;une interview de Thomas Heute et Julien Viet sur les portails d&#8217;entreprise et sur le partenariat entre eXo et JBoss <a
href="http://blog.xebia.fr/2009/06/15/revue-de-presse-xebia-113/#JBosseteXofusionnentleurssolut" title="dont nous vous parlions" >dont nous vous parlions</a> la semaine dernière.</p><p>Les détails liés au partenariat ont déjà été largement couverts par la blogosphère, et c&#8217;est surtout le tour d&#8217;horizon du concept même de portail que l&#8217;on retiendra. Celui-ci reste en effet souvent un élément ambigu au sein de l&#8217;écosystème JEE.</p><p>Le rôle du portail est d&#8217;agréger plusieurs applications au sein d&#8217;une unique application Web. Ce besoin technique peut être atteint à plusieurs niveaux de l&#8217;architecture de l&#8217;application :</p><ul><li>Au niveau back-end, par agrégation de Web Service, se conformant ainsi à l&#8217;un des préceptes des SOAs.</li><li>Au niveau applicatif, par l&#8217;utilisation d&#8217;un portail, ou d&#8217;une solution spécifique.</li><li>Au niveau du navigateur Web, par l&#8217;utilisation de gadgets, en suivant le principe des <a
href="http://fr.wikipedia.org/wiki/Application_composite" title="Mashups" >Mashups</a>.</li></ul><p>En outre, il a également été question des problématiques d&#8217;intégration des frameworks Web aux portlets, de complexité éventuelle, et d&#8217;adaptation des technologies Web aux portlets. Déterminer si un portail doit être utilisé dans une architecture dépend alors du niveau de tolérance à ces problématiques.</p><h4><a
name="EmbarquerleWebdansJavaavecJWeb"></a>Embarquer le Web dans Java avec JWebPane</h4><p>Depuis plusieurs années, lorsque l&#8217;on veut afficher une page Web au sein d&#8217;une application Swing, il faut se tourner vers le composant <a
href="https://jdic.dev.java.net/documentation/Specification.html" title="Browser" >Browser</a> de la librairie <a
href="https://jdic.dev.java.net/" title="Jdic" >Jdic</a>. Ce composant utilise <a
href="http://www.mozilla.org/projects/embedding/" title="Embeddable Mozilla" >Embeddable Mozilla</a>, et se présente sous la forme de code natif décliné pour chaque OS et d&#8217;un <em>wrapper</em> Java. Outre la nécessité de fournir une version spécifique à chaque OS, ce composant présente également l&#8217;inconvénient de mal s&#8217;intégrer aux applications Swing du fait de sa nature <em>heavyweight</em>. Pour rappel, un composant est dit <em>heavyweight</em> lorsqu&#8217;il est dessiné par l&#8217;environnement graphique du système d&#8217;exploitation ; à l&#8217;opposé il devient <em>lightweight</em> s&#8217;il est dessiné par l&#8217;application,  ce qui est le cas de l&#8217;ensemble des composants Swing. Or, faire cohabiter les deux types de composants est délicat car n&#8217;étant pas dessinés au même moment, leur superposition est confuse et des chevauchements non contrôlables apparaissent.</p><p>Lors de JavaOne, Alexey Ushakov a fait la démonstration du composant JWebPane sur lequel il travaille actuellement et vient de poster <a
href="http://weblogs.java.net/blog/alex2d/archive/2009/06/jwebpane_bof_sc.html" title="des captures d'écrans" >des captures d&#8217;écrans</a>. Contrairement à Jdic Browser, JWebPane se base sur le moteur <a
href="http://webkit.org/" title="WebKit" >WebKit</a> pour effectuer le rendu HTML. Or celui-ci se caractérise par sa nature <em>lightweight</em> s&#8217;intégrant agréablement à Swing. La <a
href="http://weblogs.java.net/blog/alex2d/archive/JWebPaneJ1.pdf" title="prsentation dAlex Ushakov" >présentation d&#8217;Alex Ushakov</a> permet également de constater que son composant est particulièrement riche en possibilité d&#8217;interactions et apporte un support pour d&#8217;éventuels plugins tels que Flash.</p><p>On ne peut qu&#8217;apprécier le choix de Sun de créer un composant pour Swing, réutilisable dans JavaFX, plutôt que de privilégier uniquement JavaFX comme cela est souvent le cas depuis son arrivée. L&#8217;intégration de JWebPane au JDK 7 est maintenant indispensable pour rendre ce composant réellement exploitable : se basant sur WebKit, il repose donc sur des librairies natives qu&#8217;il sera nécessaire de livrer avec les applications Java et seul l&#8217;intégration au JDK permettrait de l&#8217;éviter. Or, malgré <a
href="http://www.jroller.com/dmdevito/entry/about_swing_future_and_jwebpane" title="les appels" >les appels</a> de la communauté, JWebPane reste pour le moment absent de la <a
href="http://openjdk.java.net/projects/jdk7/features/" title="liste des features" >liste des <em>features</em></a> du JDK 7 et il est uniquement question d&#8217;une <a
href="http://weblogs.java.net/blog/alex2d/archive/2008/12/jwebpane_projec.html" title="mise  disposition sur Javanet" >mise à disposition sur Java.net</a>.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/06/22/revue-de-presse-xebia-114/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2009/03/09/revue-de-presse-xebia-99/</link> <comments>http://blog.xebia.fr/2009/03/09/revue-de-presse-xebia-99/#comments</comments> <pubDate>Mon, 09 Mar 2009 18:00:10 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[Eclipse]]></category> <category><![CDATA[Flex]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[J2EE]]></category> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[JavaFX]]></category> <category><![CDATA[JSR-303]]></category> <category><![CDATA[RIA]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=1592</guid> <description><![CDATA[La revue de presse de l’actualité Java/J2EE hebdomadaire proposée par Xebia. Actualité éditeurs / SSII Riena, la nouvelle plate-forme de la fondation Eclipse RIA Flight Framework : le nouveau framework MVC pour les applications Flex et ActionScript Le coin de la technique Hibernate Validator poursuit l&#8217;alignement avec la JSR-303 Le positionnement de JavaFX toujours en [...]]]></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 de l’actualité Java/J2EE hebdomadaire proposée par Xebia.</em><br
/> <strong>Actualité éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2009/03/09/revue-de-presse-xebia-99/#Rienalanouvelleplateformedelaf">Riena, la nouvelle plate-forme de la fondation Eclipse</a></li></ul><p><strong>RIA</strong></p><ul><li><a
href="http://blog.xebia.fr/2009/03/09/revue-de-presse-xebia-99/#FlightFrameworklenouveauframew">Flight Framework : le nouveau framework MVC pour les applications Flex et ActionScript</a></li></ul><p><strong>Le coin de la technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2009/03/09/revue-de-presse-xebia-99/#HibernateValidatorpoursuitlali">Hibernate Validator poursuit l&#8217;alignement avec la JSR-303</a></li><li><a
href="http://blog.xebia.fr/2009/03/09/revue-de-presse-xebia-99/#LepositionnementdeJavaFXtoujou">Le positionnement de JavaFX toujours en question</a></li><li><a
href="http://blog.xebia.fr/2009/03/09/revue-de-presse-xebia-99/#Mettreenlignesesdveloppementsd">Mettre en ligne ses développements de BDD avec une application agile (tout au moins itérative).</a></li></ul><h3><a
name="ActualitditeursSSII"></a>Actualité éditeurs / SSII</h3><h4><a
name="Rienalanouvelleplateformedelaf"></a>Riena, la nouvelle plate-forme de la fondation Eclipse</h4><p>La fondation Eclipse a <a
href="http://www.eclipse.org/org/press-release/20090302riena10.php" title="annonc" >annoncé</a> la disponibilité de sa nouvelle plate-forme &laquo;&nbsp;Eclipse Riena&nbsp;&raquo; en version 1.0. Le but de ce projet est de fournir un environnement client et serveur pour développer des applications multi-tiers avec clients riches. En soit, rien de très original. En fait, la vraie nouveauté se situe dans les possibilités offertes et dans les technologies utilisées. En effet, cette plate-forme est basée sur Eclipse RCP et Equinox et offre la possibilité de développer des services OSGi sans pré-supposer de leur localisation sur le client ou le serveur.</p><p>Autour de ce modèle d&#8217;architecture, Riena propose un ensemble de fonctionnalités :</p><ul><li>Possibilité de faire évoluer des composants Eclipse existants vers la plate-forme Riena</li><li>Gestion des mises à jour des clients pilotée par le serveur. Possibilité de procéder de manière incrémentale.</li><li>Gestion des authentifications et des autorisations basée sur <a
href="http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html" title="JAAS" >JAAS</a>.</li><li>Monitoring de l&#8217;état des clients. L&#8217;ensemble des logs et erreurs des clients peut être accédé depuis le serveur.</li></ul><p>On notera également que la partie serveur est assurée par un module <a
href="http://www.mortbay.org/jetty/" title="Jetty" >Jetty</a> et que le protocole <a
href="http://hessian.caucho.com/" title="Hessian" >Hessian</a> est utilisé pour la communication avec les clients. En outre Riena apporte des composants graphiques supplémentaires permettant de construire plus facilement des interfaces orientées processus métier ; Elias Volanakis <a
href="http://eclipsenuggets.blogspot.com/2008/07/riena-milestone-3-ships-new-ui-for-rcp.html" title="en avait propos" >en avait proposé</a> un exemple il y a quelques mois.</p><p>Là où Eclipse RCP ne traitait que du développement de la partie cliente des applications d&#8217;entreprise, Riena apporte une réponse intéressante également sur la partie serveur. A l&#8217;heure où la majorité des développements se tournent vers le Web et ses récentes technologies RIA, pour des raisons de simplicité de déploiement et de maintenance, le nouveau projet de la fondation Eclipse propose une solution bien plus flexible, tout en se basant sur des technologies matures.</p><h3><a
name="RIA"></a>RIA</h3><h4><a
name="FlightFrameworklenouveauframew"></a>Flight Framework : le nouveau framework MVC pour les applications Flex et ActionScript</h4><p>Le framework Flight est un nouveau framework MVC pour le développement d&#8217;application Flex / ActionScript. Il vient rejoindre la liste déjà importante de frameworks MVC existants, comme Cairngorm, PureMVC, Mate &#8230; InfoQ s&#8217;intéresse <a
href="http://www.infoq.com/news/2009/03/flight-framework" title="dans cet article" >dans cet article</a> à ce nouveau venu.</p><p>Ce framework a été créé par Tyler Wright, Rob Taylor et Jacob Wright, pour faciliter le développement de leurs applications. Son principe est le suivant : modulariser en domaines logiques, rationaliser le développement en équipe. Minimaliste, il offre des solutions robustes, avec entre autres :</p><ul><li>un système de mémorisation de l&#8217;historique pour pouvoir mettre en place le <em>Annuler/Rétablir</em>.</li><li>la possibilité de configurer plus facilement le <a
href="http://www.xtyler.com/code/177" title="data binding" >data binding</a></li></ul><p>Pourquoi ce énième framework ? Tyler Wright répond à la question <a
href="http://www.xtyler.com/code/11" title="ici" >ici</a>. <a
href="http://cairngormdocs.org/" title="Cairngorm" >Cairngorm</a> étant très lourd à mettre en place, il lui fallait une solution plus efficace et répondant à son besoin. Pour le moment, le projet ne fournit que <a
href="http://www.flightxd.com/flightframework/2009/02/overview/" title="la liste des fonctionnalits" >la liste des fonctionnalités</a> et une version en beta release non documentée.</p><h3><a
name="Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="HibernateValidatorpoursuitlali"></a>Hibernate Validator poursuit l&#8217;alignement avec la JSR-303</h4><p>Le développement de la version 4.0 d&#8217;Hibernate Validator <a
href="http://in.relation.to/10777.lace" title="est en cours" >est en cours</a> et poursuit son alignement avec la <a
href="http://www.jcp.org/en/jsr/detail?id=303" title="JSR-303 (Bean validation)" >JSR-303 (Bean validation)</a>. Cette JSR, actuellement en <a
href="http://in.relation.to/service/File/10774" title="version beta" >version beta</a>, est dirigée par Emmanuel Bernard, également <em>project lead</em> d&#8217;Hibernate Validator, qui sera l&#8217;implémentation de référence. Par rapport à ce framework, outre une adaptation globale de l&#8217;API, la spécification diffère principalement sur deux points :</p><ul><li>l&#8217;apport de la notion de groupe, permettant de spécifier un ensemble de contraintes, à inclure ou non dans une validation</li><li>la possibilité de spécifier la &laquo;&nbsp;traversabilité&nbsp;&raquo; des propriétés d&#8217;un objet. Ainsi, si une propriété ne doit pas être validée à un instant donné (pour cause de lazy loading par exemple), il sera possible de l&#8217;indiquer au framework.</li></ul><p>Ces apports, bien que minimes en apparence, sont réellement utiles. En effet, les scénarios de validation dans les applications d&#8217;entreprises sont souvent constitués de nombreuses règles de gestion, qu&#8217;il est délicat d&#8217;appréhender sans un framework offrant une grande flexibilité.</p><h4><a
name="LepositionnementdeJavaFXtoujou"></a>Le positionnement de JavaFX toujours en question</h4><p>Manque de communication de Sun ? Le positionnement de JavaFX par rapport à Swing fait toujours débat, 4 mois après la sortie de sa première version finale.</p><p>Ces derniers jours, deux interventions ont particulièrement entretenu le débat.</p><p>D&#8217;un coté, John O&#8217;Conner <a
href="http://weblogs.java.net/blog/joconner/archive/2009/03/is_the_swing_ap_1.html" title="soutient" >soutient</a> que la relance de la <a
href="http://www.jcp.org/en/jsr/detail?id=296" title="JSR-296 (Swing Application Framework)" >JSR-296 (Swing Application Framework)</a> est vaine et ne constitue qu&#8217;un investissement à court terme. Poursuivant dans cette vision d&#8217;un Swing obsolète, il conseille aux développeurs arrivant dans le monde des interfaces riches en Java de ne pas chercher à apprendre Swing mais de directement se tourner vers JavaFX.</p><p>De l&#8217;autre coté, Jan Erik Paulsen, <a
href="http://labs.teppefall.com/2009/03/sun_is_pulling_a_netscape_rewr.html" title="rejette avec force" >rejette avec force</a> JavaFX, tant comme concurrent de Flex / Silverlight, critiquant le manque de productivité offert par la solution de Sun pour les <em>designers</em>, que comme remplaçant de Swing, ne pouvant admettre le rejet de cette technologie mature et maîtrisée.</p><p>Au trouble existant sur l&#8217;évolution de Swing dont <a
href="http://blog.xebia.fr/2009/03/02/revue-de-presse-xebia-98/#LinitiativeSwingcritique" title="nous parlions" >nous parlions</a> la semaine dernière, s&#8217;ajoute donc ce positionnement ambiguë de JavaFX. S&#8217;il veut empêcher la fuite des javaistes vers les solutions concurrentes, Sun devra clarifier son discours dans les mois à venir et tenter de mettre un point final à ce genre de querelles (en apportant, lors de la prochaine release en Juin, un véritable gain de productivité grâce à un environnement de développement, à des composants graphiques de haut niveau, &#8230;).</p><h4><a
name="Mettreenlignesesdveloppementsd"></a>Mettre en ligne ses développements de BDD avec une application agile (tout au moins itérative).</h4><p>Pramod Sadalage, co-auteur, avec Scott Ambler en 2007 de <a
href="http://www.informit.com/store/product.aspx?isbn=0321293533" title="Refactoring Databases: Evolutionary Database Development" >Refactoring Databases: Evolutionary Database Development</a> et auteur de <a
href="http://www.informit.com/store/product.aspx?isbn=032150206X" title="Recipes for Continuous Database Integration" >Recipes for Continuous Database Integration</a>, expose, <a
href="http://www.infoq.com/presentations/refactoring-databases" title="dans une vido capte au QCon et relaye par infoQ" >dans une vidéo captée au QCon et relayée par infoQ</a>, les grands principes d&#8217;un <em>design</em> de base de données évolutif (qu&#8217;on pourrait sous titrer <em>&#8216;Comment attirer les DBA dans le monde itératif J2EE&#8217;</em>).<br
/> Pour ceux qui n&#8217;auraient pas le temps d&#8217;ingurgiter les quelques 500 pages de ces 2 ouvrages, cette vidéo, illustrée par des démonstrations pertinentes, constitue un bon point de départ.</p><p>Cependant, et comme c&#8217;est malheureusement souvent le cas, les grands principes exposés ici se heurteront rapidement aux <em>réalités projet</em> (il est bien difficile de &#8216;vendre&#8217; un <em>pair programming</em> développeur Java / DBA, de multiplier les environnements bac à sable&#8230;).<br
/> Malgré tout, il est facile d&#8217;extraire quelques trucs et astuces pleins de bon sens de cette présentation (automatisation, rôle de l&#8217;intégration continue, de la gestion de sources&#8230;).</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2009/03/09/revue-de-presse-xebia-99/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Intégrer Hibernate avec GWT sans douleur</title><link>http://blog.xebia.fr/2008/12/17/integrer-hibernate-avec-gwt-sans-douleur/</link> <comments>http://blog.xebia.fr/2008/12/17/integrer-hibernate-avec-gwt-sans-douleur/#comments</comments> <pubDate>Wed, 17 Dec 2008 11:44:11 +0000</pubDate> <dc:creator>Amin Fathallah</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[GWT]]></category> <category><![CDATA[Hibernate]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=1149</guid> <description><![CDATA[Avez-vous essayé d&#8217;utiliser directement vos objets du Domaine directement dans votre application GWT sans avoir une longue liste d&#8217;erreurs ? Avez-vous essayé de résoudre le problème en créant des objets DTO (Data Transfer Object) ou en adaptant vos objets du Domaine ? Existe-t-il une solution légère et transparente pour faire cohabiter Hibernate avec GWT ? [...]]]></description> <content:encoded><![CDATA[<p>Avez-vous essayé d&#8217;utiliser directement vos objets du Domaine directement dans votre application GWT sans avoir une longue liste d&#8217;erreurs ? Avez-vous essayé de résoudre le problème en créant des objets DTO (Data Transfer Object) ou en adaptant vos objets du Domaine ? Existe-t-il une solution légère et transparente pour faire cohabiter Hibernate avec GWT ?</p><p>Dans cet article, nous présenterons une solution simple et propre pour vous permettre une meilleure intégration d&#8217;Hibernate avec GWT.</p><p>Ce billet se découpe de la façon suivante :</p><ul><li>Nous commencerons par introduire la <a
href="http://blog.xebia.fr/2008/12/17/integrer-hibernate-avec-gwt-sans-douleur#Introduction">problématique d&#8217;intégration d&#8217;Hibernate avec GWT</a>.</li><li>Nous introduirons ensuite une solution pour <a
href="http://blog.xebia.fr/2008/12/17/integrer-hibernate-avec-gwt-sans-douleur#FairecohabiterGWTetHibernate">faire cohabiter Hibernate avec GWT</a>.</li><li>Nous proposerons ensuite une <a
href="http://blog.xebia.fr/2008/12/17/integrer-hibernate-avec-gwt-sans-douleur#HibernateGWTarriveGWTaussi">solution légère et transparente pour intégrer Hibernate avec GWT</a>.</li><li>Nous détaillerons ensuite la <a
href="http://blog.xebia.fr/2008/12/17/integrer-hibernate-avec-gwt-sans-douleur#Etconcrtementquestcequeadonne">procédure d&#8217;intégration de la solution sur votre projet</a>.</li><li>Et nous terminerons par un petit <a
href="http://blog.xebia.fr/2008/12/17/integrer-hibernate-avec-gwt-sans-douleur#IntgrerHibernateGWTdansvotrepr">retour d&#8217;expérience</a>.</li></ul><h3><a
name="Introduction"></a>Introduction</h3><p>L&#8217;idée de base est d&#8217;utiliser mes objets du Domaine directement dans la couche présentation. Google Web Toolkit se basant sur Java, cela semblait l&#8217;une des forces de cette union. Mais malheureusement, les divergences techniques rendent la tâche difficile.</p><p>Plusieurs raisons empêchent d&#8217;utiliser les objets du Domaine directement dans la couche présentation :</p><ul><li><strong>Héritage différent</strong> : Les objets Java échangés entre le client et le serveur doivent implémenter une interface de sérialisation Google <code>IsSerializable</code>, tandis que les classes Hibernate implémentent l&#8217;interface <code>Serializable</code>. Autre problème gênant, le compilateur GWT dans sa version 1.4 ne supporte pas l&#8217;interface Java <code>Seriablizable</code> et affiche une erreur.</li><li><strong>Types de données incompatibles</strong> : Les classes <code>PersistentSet</code> et <code>java.sql.DateTime</code> utilisées par Hibernate ne sont pas reconnues par le compilateur GWT.</li><li><strong>Chargement partiel (Lazy-Loading)</strong> : GWT ne sait manipuler que des POJO (Plain Old Java Object) et non des objets Hibernate. À l&#8217;exécution, Hibernate remplace les instances par des Proxies, alors que JavaScript, mis en œuvre par GWT, accepte uniquement les types primitifs et les POJO qui en sont composés. Or une classe Proxy n&#8217;est pas un type primitif, ni un type déclaré comme sérialisable en JavaScript.</li></ul><p>Toutefois, intégrer Hibernate avec GWT est possible. Mais doit-on abandonner l&#8217;idée d&#8217;utiliser les objets du Domaine directement dans la couche présentation ? GWT 1.5 est peut-être la solution.</p><h3><a
name="FairecohabiterGWTetHibernate"></a>Faire cohabiter GWT et Hibernate</h3><p>Une solution consiste à créer une hiérarchie de classes DTO correspondant à la hiérarchie des classes Hibernate, puis à cloner les objets du Domaine en objets DTO afin de les véhiculer vers la couche présentation sans difficulté. L&#8217;opération de clonage est prise en charge par la couche service qui assure les conversions Hibernate&lt;-&gt;DTO en utilisant la librairie <a
href="http://beanlib.sourceforge.net/" title="bean-lib">bean-lib</a>. Celle-ci gère la duplication dynamique des objets Hibernate et convertit les données non supportées par GWT. Reste donc le problème de chargement partiel (Lazy loading) qui doit être géré par les développeurs.</p><p>Cette solution s&#8217;est avérée complexe et coûteuse en temps de développement. De plus, elle entraîne beaucoup trop de dépendances techniques. Elle a cependant le mérite de fonctionner.</p><p>Pour plus d&#8217;informations n&#8217;hésitez pas à <a
href="http://www.dotnetguru.org/temp/GWTHibernateinside.pdf" title="consulter le billet suivant" >consulter le billet suivant</a>.</p><h3><a
name="HibernateGWTarriveGWTaussi"></a>Hibernate4GWT arrive &#8230; GWT 1.5 aussi</h3><p>Hibernate4GWT est une librairie Java prenant en charge la cohabitation dynamique d&#8217;Hibernate avec GWT. Elle permet ainsi d&#8217;utiliser les objets du Domaine directement dans la couche présentation sans se soucier de créer une hiérarchie de classes DTO juste vos objets du Domaine et du <a
href="http://www.opentaps.org/docs/index.php/Domain_Driven_Architecture" title="Domain Driven Architecture" >Domain Driven Architecture</a>.</p><p>À noter que si vous utilisez toujours GWT 1.4, vos objets du Domaine doivent respecter la syntaxe Java 1.4, ce qui n&#8217;est pas facile à gérer et à intégrer dans du code existant. Et même avec Hibernate4GWT, vous êtes contraints de créer des classes DTO pour vous en sortir. Les objets du Domaine qui proviennent du serveur sont rapatriés et organisés dans les DTO par la librairie (l&#8217;opération de clone) et les objets DTO renvoyés vers le serveur sont également restitués par la librairie (l&#8217;opération de merge).</p><p>Avec l&#8217;arrivée de GWT1.5, vous n&#8217;avez plus ni à créer des classes DTO, ni à utiliser explicitement les opérations de merge et de clone. il est désormais possible d&#8217;utiliser vos objets du Domaine directement sur la couche présentation : d&#8217;où la nécessité de passer à GWT 1.5 pour une intégration transparente entre Hibernate et GWT.</p><div
align="center"> <img
src="http://blog.xebia.fr/wp-content/uploads/2008/12/hibernate-gwt.png" alt="" title="hibernate-gwt" width="500" height="190" class="aligncenter size-full wp-image-1151" /></div><p>La classe <code>HibernateBeanManager</code>, qui est le cœur de l&#8217;API, s&#8217;occupe de la suppression des proxies Hibernate. Elle gère la conversion des types de données incompatibles avec GWT en leur équivalent valide. Puis elle stocke les informations des attributs partiellement chargés (Lazy attributes) pour restituer correctement les objets du Domaine.</p><p>Hibernate4GWT, avec un minimum de configuration et des impacts techniques très légers, fournit un socle technique qui masque la complexité introduite par l&#8217;intégration d&#8217;Hibernate avec GWT et nous permet ainsi de respecter les règles de l&#8217;art.</p><h3><a
name="Etconcrtementquestcequeadonne"></a>Et concrètement qu&#8217;est-ce que ça donne ?!</h3><p>Hibernate4GWT s&#8217;adapte à plusieurs types de configurations, selon vos besoins et les contraintes du projet dans lequel vous souhaitez l&#8217;intégrer.</p><p>Plusieurs configurations sont possibles :</p><ul><li><strong>Stateless (configuration par défaut)</strong> : le serveur ne stocke aucune information sur l&#8217;état de la session. Les classes du Domaine doivent hériter de la classe <code>LazyPojo</code> pour stocker les attributs partiellement chargés (Lazy attributes).</li><li><strong>Dynamic Proxy</strong> : Une classe Proxy est générée par la librairie pour stocker les informations sur les attributs partiellement chargés (Lazy attributes) côté serveur et côté client. Les classes du Domaine doivent implémenter l&#8217;interface <code>Serializable</code>.</li><li><strong>Stateful</strong> : Les informations sur les attributs partiellement chargés (Lazy attributes) ne sont pas stockées dans les POJO mais dans la session HTTP. Les classes du Domaine ne nécessitent aucun héritage technique, mais votre serveur devient stateful (sticky session).</li><li><strong>Java5 support</strong> : GWT 1.4 ne supporte pas la syntaxe Java 5, Hibernate4GWT permet de cloner dynamiquement les classes du Domaine Java 5 en DTO associés compatibles Java 1.4. Pour cela, ces classes DTO doivent avoir le même nom que les classes du Domaine (placées dans un package différent) et doivent hériter de la classe <code>LazyPojo</code>.</li></ul><p>Pour démarrer, vous devez d&#8217;abord choisir une configuration pour votre projet. Pour un nouveau projet, ou si vous avez la possibilité d&#8217;ajouter des héritages techniques dans vos classes du Domaine, l&#8217;auteur de la librairie recommande la configuration <em>Dynamic proxy</em> ou le mode <em>Stateless</em>. Sinon, si vous ne voulez pas modifier l&#8217;existant, vous pouvez utiliser le mode <em>Stateful</em> ou la configuration <em>Dynamic proxy</em> si vos classes du Domaine implémentent l&#8217;interface <code>Serializable</code>.</p><p>À noter que si vous utilisez des classes du Domaine Java 5 et GWT 1.4, vous êtes contraints d&#8217;utiliser la configuration <em>Java5 support</em>.</p><h3><a
name="IntgrerHibernateGWTdansvotrepr"></a>Intégrer Hibernate4GWT dans votre projet</h3><h4><a
name="Installation"></a>Installation</h4><p>L&#8217;installation d&#8217;Hibernate4GWT dans un projet GWT :</p><ul><li>Décompression de l&#8217;archive hibernate4gwt-1.x.x.zip,</li><li>Ajout d&#8217;hibernate4gwt.jar et des dépendances présentes dans le répertoire lib dans le classpath de votre projet GWT,</li><li>Édition du fichier de configuration GWT :</li></ul><p><strong>Avec GWT 1.4 :</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;module&gt;
       &lt;!-- Inherit the core Web Toolkit stuff --&gt;
       &lt;inherits name='com.google.gwt.user.User'/&gt;
       &lt;!-- Inherit the hibernate4gwt stuff --&gt;
       &lt;inherits name='net.sf.hibernate4gwt.Hibernate4Gwt14'/&gt;
       &lt;!-- Specify the app entry point class --&gt;
       &lt;entry-point class='...'/&gt;
       &lt;!-- Additional source path --&gt;
       &lt;!-- To add for java5 support configuration --&gt;
       &lt;source path='dto'/&gt;
       &lt;!-- To add for other configurations --&gt;
       &lt;source path='domain'/&gt;
       &lt;source path='client'/&gt;
       &lt;!-- To add for dynamic proxy configuration --&gt;
       &lt;generate-with class=&quot;net.sf.hibernate4gwt.rebind.Gwt14ProxyGenerator&quot;&gt;
          &lt;when-type-assignable class=&quot;java.io.Serializable&quot; /&gt;
       &lt;/generate-with&gt;
       &lt;!-- Servlet path --&gt;
&lt;/module&gt;
</pre><p><strong>Avec GWT 1.5 :</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;module&gt;
       &lt;!-- Inherit the core Web Toolkit stuff --&gt;
       &lt;inherits name='com.google.gwt.user.User'/&gt;
       &lt;!-- Inherit the hibernate4gwt stuff --&gt;
       &lt;inherits name='net.sf.hibernate4gwt.Hibernate4Gwt15'/&gt;
       &lt;!-- Uncomment if your Domain class use JPA mapping annotations --&gt;
       &lt;!-- &lt;inherits name='net.sf.hibernate4gwt.emul.java5.ejb3.Ejb3'/&gt; --&gt;
       &lt;!-- Specify the app entry point class --&gt;
       &lt;entry-point class='...'/&gt;
       &lt;!-- Additional source path --&gt;
       &lt;!-- To add for java5 support configuration --&gt;
       &lt;source path='dto'/&gt;
       &lt;!-- To add for other configurations --&gt;
       &lt;source path='domain'/&gt;
       &lt;source path='client'/&gt;
       &lt;!-- To add for dynamic proxy configuration --&gt;
       &lt;generate-with class=&quot;net.sf.hibernate4gwt.rebind.Gwt15ProxyGenerator&quot;&gt;
         &lt;when-type-assignable class=&quot;java.io.Serializable&quot; /&gt;
       &lt;/generate-with&gt;
       &lt;!-- Servlet path --&gt;
&lt;/module&gt;
</pre><h4><a
name="ClassesduDomaine"></a>Classes du Domaine</h4><p>Pour utiliser vos classes du Domaine dans GWT, il y a quelques détails à régler :</p><ul><li>Ajouter vos classes du Domaine dans le classpath de l&#8217;application GWT,</li><li>Implémenter l&#8217;interface <code>Serializable</code> dans vos classes du Domaine pour le mode <em>Stateful</em> et la configuration <em>Dynamic proxy</em>,</li><li>Étendre la classe <code>net.sf.hibernate4gwt.pojo.java14.LazyPojo</code> (GWT 1.4) ou <code>net.sf.hibernate4gwt.pojo.java5.LazyPojo</code> (GWT 1.5) pour le mode <em>Stateless</em>,</li><li>Créer une hiérarchie de classes DTO compatibles avec GWT 1.4 pour la configuration <em>Java5 support</em>.</li></ul><h4><a
name="InitialisationdHibernateBeanMa"></a>Initialisation d&#8217;HibernateBeanManager</h4><p>Lors l&#8217;initialisation de l&#8217;instance d&#8217;<code>HibernateBeanManager</code>, il faut lui associer une instance d&#8217;Hibernate <code>SessionFactory</code>. Cette configuration est à faire dans le code d&#8217;initialisation serveur.</p><p><strong>Mode Stateless :</strong></p><pre class="brush: java; title: ; notranslate">
HibernateBeanManager.getInstance().setSessionFactory(sessionFactory);
// or HibernateBeanManager.getInstance().setEntityManagerFactory(emf);
</pre><p><strong>Configuration Java5 support :</strong></p><p>De plus, il faut également associer <code>HibernateBeanManager</code> à une instance de la classe <code>DirectoryCloneMapper</code> pour le mapping entre les classes du Domaine et les classes DTO.</p><pre class="brush: java; title: ; notranslate">
HibernateBeanManager.getInstance().setSessionFactory(sessionFactory);
// or HibernateBeanManager.getInstance().setEntityManagerFactory(emf);
DirectoryCloneMapper cloneMapper = new DirectoryClassMapper();
cloneMapper.setRootDomainPackage(&quot;com.testing.server.domain&quot;);
cloneMapper.setRootClonePackage(&quot;com.testing.dto&quot;);
cloneMapper.setCloneSuffix(&quot;DTO&quot;);
HibernateBeanManager.getInstance().setClassMapper(cloneMapper);
</pre><p><strong>Mode Stateful :</strong></p><p>En plus de la configuration de base, il faut associer une instance d&#8217;<code>HttpSessionPojoStore</code> à l&#8217;instance d&#8217;<code>HibernateBeanManager</code>.</p><pre class="brush: java; title: ; notranslate">
HibernateLazyManager.getInstance().setPojoStore(new HttpSessionPojoStore());
HibernateLazyManager.getInstance().setSessionFactory(sessionFactory);
// or HibernateLazyManager.getInstance().setEntityManagerFactory(emf);
</pre><p><strong>Configuration Dynamic proxy :</strong></p><p>Il est aussi nécessaire d&#8217;associer une instance de la classe <code>ProxyClassMapper</code> à l&#8217;instance d&#8217;<code>HibernateBeanManager</code> pour les opérations de clone et de merge.</p><pre class="brush: java; title: ; notranslate">
HibernateBeanManager.getInstance().setSessionFactory(sessionFactory);
// or HibernateBeanManager.getInstance().setEntityManagerFactory(emf);
HibernateBeanManager.getInstance().setClassMapper(new ProxyClassMapper());
</pre><h4><a
name="Servicedistant"></a>Service distant</h4><p>L&#8217;implémentation du service GWT distant doit hériter de la classe <code>HibernateRemoteService</code> au lieu de la classe <code>RemoteServiceServlet</code>.</p><pre class="brush: java; title: ; notranslate">
public class ProductRemoteImpl extends HibernateRemoteService
                            implements ProductRemote
{
    ...
    public Product getProduct(int id)
    {
         return _productDAO.getProductById(id);
    }
    public Product updateUser(Product product)
    {
         // Update the product in database
         _productDAO.updateProduct(product);
         // Send back a new clone (optimistic lock)
         return product;
    }
}
</pre><p>A noter qu&#8217;avec la configuration <em>Java5 support</em>, il faut merger les objets DTO en entrée et cloner les objets du Domaine en sortie.</p><pre class="brush: java; title: ; notranslate">
public class ProductRemoteImpl extends HibernateRemoteService
                            implements ProductRemote
{
    ...
    public ProductDTO getProduct(int id)
    {
         return (ProductDTO) clone(_productDAO.getProductById(id));
    }
    public ProductDTO updateUser(ProductDTO productDTO)
    {
         // Update the product in database
         product = (Product)merge(productDTO);
         _productDAO.updateProduct(product);
         // Send back a new clone (optimistic lock)
         return (ProductDTO) clone(product);
    }
}
</pre><h3><a
name="Conclusion"></a>Conclusion</h3><p>J&#8217;avais intégré l&#8217;API Hibernate4GWT sur un projet de petite taille avec une base de données de 10 tables et un nombre d&#8217;utilisateurs simultanés limité à 20. Lors de la mise en œuvre, l&#8217;API m&#8217;a facilité grandement la vie, et m&#8217;a permis une meilleure intégration d&#8217;Hibernate avec GWT. Je n&#8217;ai pas eu des problèmes particuliers en production ni d&#8217;impacts sur les performances de l&#8217;application, mais des questions se posent : peut-on utiliser l&#8217;API sur des grands projets ? Quel sera l&#8217;impact sur les performances lors de la montée en charge ?</p><p>Comme nous avons pu le voir, Hibernate4GWT est une petite librairie qui permet une intégration transparente et légère d&#8217;Hibernate avec GWT. L&#8217;auteur de la librairie nous promet beaucoup de choses dans l&#8217;avenir en renommant la librairie en <a
href="http://noon.gilead.free.fr/gilead/" title="Gilead" >Gilead</a> ou Generic Light Entity Adapter, une nouvelle version Hibernate4ALL pour les technologies (Flex/BlazeDS, Web Services &#8230;).</p><h4><a
name="Liensannexes"></a>Liens annexes :</h4><ul><li>Présentation d&#8217;<a
href="http://hibernate4gwt.sourceforge.net/" title="Hibernate4GWT sur le site officiel" >Hibernate4GWT sur le site officiel</a></li><li>Présentation de <a
href="http://noon.gilead.free.fr/gilead/" title="Gilead sur le site officiel" >Gilead sur le site officiel</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2008/12/17/integrer-hibernate-avec-gwt-sans-douleur/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/</link> <comments>http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/#comments</comments> <pubDate>Mon, 03 Nov 2008 16:55:56 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[AMQP]]></category> <category><![CDATA[Envers]]></category> <category><![CDATA[Flex]]></category> <category><![CDATA[Flunit]]></category> <category><![CDATA[GWT]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[J2EE]]></category> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Méthodes agiles]]></category> <category><![CDATA[Paris JUG]]></category> <category><![CDATA[RIA]]></category> <category><![CDATA[SCRUM]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[X2O]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=950</guid> <description><![CDATA[La revue de presse de l’actualité Java/J2EE hebdomadaire proposée par Xebia. Actualité éditeurs / SSII SpringSource rejoint le comité exécutif du JCP pour Java SE et EE Microsoft embrasse les Middlewares de Message Open Source Agilité Scrum et le lavage en machine RIA X2O framework ou comment faciliter la réalisation d&#8217;applications Flex. Pivot 1.0 : [...]]]></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 de l’actualité Java/J2EE hebdomadaire proposée par Xebia.</em></p><p><strong>Actualité éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/#SpringSourcerejointlecomitexcu">SpringSource rejoint le comité exécutif du JCP pour Java SE et EE</a></li><li><a
href="http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/#MicrosoftembrasselesMiddleware">Microsoft embrasse les Middlewares de Message Open Source</a></li></ul><p><strong>Agilité</strong></p><ul><li><a
href="http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/#Scrumetlelavageenmachine">Scrum et le lavage en machine</a></li></ul><p><strong>RIA</strong></p><ul><li><a
href="http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/#XOframeworkoucommentfaciliterl">X2O framework ou comment faciliter la réalisation d&#8217;applications Flex.</a></li><li><a
href="http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/#PivotdvelopperdesapplicationsR">Pivot 1.0 : développer des applications RIA en Java et XML</a></li><li><a
href="http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/#TestezvosapplicationsFlexavecF">Testez vos applications Flex avec Fluint</a></li></ul><p><strong>Le coin de la technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/#EnversrejointHibernate">Envers rejoint Hibernate</a></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/2008/11/03/revue-de-presse-xebia-81/#GWTauParisJUGdeNovembre">GWT au Paris JUG de Novembre</a></li><li><a
href="http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/#XKEleprogrammedelasessiondeNov">XKE, le programme de la session de Novembre</a></li></ul><h3><a
name="ActualitditeursSSII"></a>Actualité éditeurs / SSII</h3><h4><a
name="SpringSourcerejointlecomitexcu"></a>SpringSource rejoint le comité exécutif du JCP pour Java SE et EE</h4><p>SpringSource était déjà présent dans des Expert Groups clefs de Java EE (<a
href="http://jcp.org/en/jsr/detail?id=316" title="JSR-316 : JavaEE 6" >JSR-316 : JavaEE 6</a>, <a
href="http://jcp.org/en/jsr/detail?id=291" title="JSR-291 : Dynamic Component Support for Java SE" >JSR-291 : Dynamic Component Support for Java SE</a> &#8211; aka OSGi, etc). Rod Johnson fait un pas de plus dans cet organisme en se faisant élire membre du <a
href="http://jcp.org/en/participation/committee#SEEE" title="JCP Executive Committee for Java SE/EE" >JCP Executive Committee for Java SE/EE</a>, le comité qui encadre les JSR relatives à Java SE et Java EE. L&#8217;Executive Committee est à l&#8217;image de l&#8217;ouverture du JCP ; on y retrouve  principalement des grands acteurs du monde Java <em>(IBM, Oracle, Sun, etc)</em> mais aussi l&#8217;ancien trublion aujourd&#8217;hui assagi des serveurs Java EE JBoss/Redhat et des membres individuels comme l&#8217;universitaire Doug Lea ou le polémique auteur du <a
href="http://www.bileblog.org/" title="Bile Blog" >Bile Blog</a> Hani Suleiman <em>(qui ne s&#8217;est pas représenté cette année)</em>.</p><p>Rod Johnson place son mandat sous le signe de la transparence, de l&#8217;écoute de la communauté et du pragmatisme (Cf. <a
href="http://blog.springsource.com/2008/10/27/a-word-about-the-election/" title="A word about the election" >A word about the election</a> et <a
href="http://blog.springsource.com/2007/09/30/our-approach-to-the-jcp/" title="our approach to the JCP" >our approach to the JCP</a>). Cette vision s&#8217;inscrit dans la tendance actuelle du JCP dont les travaux s&#8217;ouvrent chaque année un peu plus <em>(participation gratuite pour les individuels, publicité des débats, Reference Implementation (RI) et Technology Compatibility Kit (TCK) open source, etc)</em>.</p><p>La présence de SpringSource dans les instances dirigeantes du JCP participera au maintien de l&#8217;équilibre entre <em>&laquo;&nbsp;petits et grands&nbsp;&raquo;</em> dans un monde en phase de concentration (Oracle/BEA, IBM/ILog, Progress/IONA, etc). De plus, on peut espérer que Rod Johnson facilite le rapprochement entre le JCP et l&#8217;OSGi Alliance dont le fonctionnement ressemble plus au JCP d&#8217;il y a 10 ans <em>(participation payante, membres essentiellement commerciaux, confidentialité des débats, des RI et des TCK, etc)</em> qu&#8217;à la communauté que nous connaissons aujourd&#8217;hui : certes perfectible mais exemplaire par son ouverture.</p><p>Pour en savoir plus : <a
href="http://www.sdtimes.com/link/33001" title="SD Time : Rod Johnson on a mission to open up JCP" >SD Time : Rod Johnson on a mission to open up JCP</a>, <a
href="http://blogs.the451group.com/opensource/2008/10/29/spring-foward/" title="The 451 group : Spring forward" >The 451 group : Spring forward</a>.</p><h4><a
name="MicrosoftembrasselesMiddleware"></a>Microsoft embrasse les Middlewares de Message Open Source</h4><p>Microsoft avait déjà surpris la communauté Open Source cet été en devenant <a
href="http://www.networkworld.com/news/2008/072508-microsoft-apache.html" title="Platinium Sponsor de la Fondation Apache" >Platinium Sponsor de la Fondation Apache</a>. La firme de Redmond poursuit aujourd&#8217;hui son rapprochement avec le monde Open Source en rejoignant l&#8217;<a
href="http://www.networkworld.com/news/2008/072508-microsoft-apache.html" title="AMQP Working Group " >AMQP Working Group </a> pour soutenir le développement du protocole open source de middleware de messages AMQP destiné à concurrencer le duopole d&#8217;IBM et de Tibco <em>(respectivement Websphere MQ et RendezVous)</em>.</p><p>Au delà de l&#8217;effet d&#8217;annonce, comment la firme de Redmond concrétisera-t-elle cet engagement ? Microsoft refondra-t-il <a
href="http://www.microsoft.com/windowsserver2003/technologies/msmq/default.mspx" title="Microsoft Message Queing (MSMQ)" >Microsoft Message Queing (MSMQ)</a> pour implémenter AMQP ? Contribuera-t-il à un projet Open Source comme par exemple <a
href="http://cwiki.apache.org/qpid/" title="Apache QPid" >Apache QPid</a>, projet largement supporté par Redhat qui en a fait le socle de sa solution <a
href="http://www.jboss.org/rhmessaging/" title="Redhat Messaging" >Redhat Messaging</a> ?</p><p>En attendant plus de détails, ce ralliement pourrait d&#8217;une part être le soutien qui semblait manquer à AMQP pour prendre son essor et d&#8217;autre part être un différenciateur clef de Microsoft pour se lancer à l&#8217;assaut des parts de marché d&#8217;IBM et de Tibco.</p><p>Pour en savoir plus : <a
href="http://www.interopnews.com/analysis/microsoft-embraces-amqp-open-middleware-standard.html" title="InteropNews : Microsoft embraces AMQP open middleware standard" >InteropNews : Microsoft embraces AMQP open middleware standard</a></p><h3><a
name="Agilit"></a>Agilité</h3><h4><a
name="Scrumetlelavageenmachine"></a>Scrum et le lavage en machine</h4><p>On connaissait la métaphore du Rugby pour expliquer Scrum, voici une comparaison plus originale : le lave-linge ! Le Touilleur Express fait l&#8217;analogie entre <a
href="http://www.touilleur-express.fr/2008/11/02/scrum-une-histoire-de-lave-linge/" title="Scrum et le lavage en machine" >Scrum et le lavage en machine</a> pour expliquer quelques notions :</p><ul><li>Product backlog : le linge sale représente la liste des tâches à faire.</li><li>Itérations : le lavage s&#8217;effectue par cycle, comme le développement itératif.</li><li>Capacité non extensible : ne demandez pas à votre lave-linge de laver plus de linge que sa capacité (5kg), de même une équipe ne peut produire qu&#8217;une quantité limitée de fonctionnalités par itération.</li><li>Gestion de priorités : il faut trier le linge en fonction des priorités, si l&#8217;on a besoin de la chemise pour demain ou si elle peut attendre le prochain lavage.</li><li>Ne pas perturber l&#8217;itération : il est impossible d&#8217;arrêter un programme en cours pour y ajouter une chemise oubliée. L&#8217;itération ne doit pas être perturbée non plus.</li></ul><p>On pourrait rajouter qu&#8217;il faut éviter de mélanger les couleurs et les domaines métier, sinon le résultat pourrait déteindre !</p><h3><a
name="RIA"></a>RIA</h3><h4><a
name="XOframeworkoucommentfaciliterl"></a>X2O framework ou comment faciliter la réalisation d&#8217;applications Flex.</h4><p>Après <a
href="http://blog.xebia.fr/2008/09/26/exadel-flamingo-applications-flex-amf-spring/" title="Exadel Flamingo" >Exadel Flamingo</a>, voici un nouveau framework nous facilitant le développement d&#8217;applications Flex : X2O. <a
href="http://www.infoq.com/news/2008/10/x2o-framework-for-flex" title="Dans cet article" >Dans cet article</a>, InfoQ interroge Ka Wai Cheung de <a
href="http://www.wearemammoth.com/" title="We Are Mammoth" >We Are Mammoth</a> sur ce nouvel outil. X2O est une plateforme permettant de réaliser des applications Flex sans toucher au code de la partie serveur. Grâce à ce framework, nous n&#8217;avons plus aucune intégration à réaliser, pas de base de données à mettre en place. Tout est géré par le framework.</p><p>Il suffit pour cela de se créer un compte sur <a
href="http://www.x2oframework.com/#" title="http://www.x2oframework.com/#" >http://www.x2oframework.com/#</a> puis de créer un modèle de données et de le soumettre à X2O.</p><p>Celui ci va ensuite générer :</p><ul><li>Un <a
href="http://fr.wikipedia.org/wiki/Syst%C3%A8me_de_gestion_de_contenu" title="CMS" >CMS</a> sécurisé permettant de gérer les données.</li><li>Un fichier SWC contenant les value objects du modèle de données ainsi que les CRUDs basiques et les méthodes de chargement qui ont été configurés dans le CMS.</li><li>La documentation ActionScript 3 du projet.</li></ul><p>Le CMS généré comprend une base de données, des procédures stockées, une couche d&#8217;accès aux données et une couche web service. Il est hébergé par le site et à tout moment, le développeur peut modifier son modèle de données dans le CMS et régénérer la librairie swc et la documentation ActionScript 3. La librairie fournit également des fonctionnalités supplémentaires comme l&#8217;envoi d&#8217;email et l&#8217;upload de fichiers. La plus grosse tâche est maintenant de créer son application Flex et d&#8217;appeler les méthodes du fichier swc pour charger les bonnes données.</p><p>Actuellement la version bêta est disponible et gratuite pour les développeurs. Ces derniers pourront donc tester ce framework (limité à deux projets par compte), donner leur avis et remonter des anomalies. La version définitive prévue en 2009 comportera probablement une version gratuite et une version payante sur plusieurs niveaux.</p><h4><a
name="PivotdvelopperdesapplicationsR"></a>Pivot 1.0 : développer des applications RIA en Java et XML</h4><p>Pivot est un framework Open Source pour le développement des applications RIA en Java. Ce dernier est le fruit d&#8217;un travail de l&#8217;équipe R&#038;D de <a
href="http://www.vmware.com/fr/" title="VMware" >VMware</a>, il fournit une alternative aux développeurs qui veulent développer leurs applications RIA en Java.</p><p>Les applications Pivot sont construites en Java et XML. La structure de l&#8217;interface utilisateur est décrite au format XML avec un langage de description d&#8217;écrans appelé WTKX, la gestion des événements et la logique applicative sont écrites en Java.</p><p>Pivot semble familier aux développeurs Swing, comme les deux utilisent Java2D et se basent sur une architecture MVC pour une séparation entre les données, la présentation et les traitements. Pivot fournit des composants graphiques dynamiques et réutilisables (panneaux, boutons, tables/grilles, boîtes de dialogues, menus et barres de menus &#8230;) pour créer des applications web de nouvelle génération.</p><p>Les applications Pivot peuvent s&#8217;exécuter à l&#8217;intérieur d&#8217;un applet java ou à déployer en local, tous systèmes d&#8217;exploitation confondus.</p><div
align="center"><img
src="http://blog.xebia.fr/wp-content/uploads/2008/11/pivot.png" alt="" title="pivot" /></div><p>Le code source du projet est fourni sous licence Apache Version 2.0.<br
/> Une démo de Pivot en action : <a
href="http://pivot-toolkit.org/tutorials/demo.standalone.html" title="http://pivot-toolkit.org/tutorials/demo.standalone.html" >http://pivot-toolkit.org/tutorials/demo.standalone.html</a>.</p><h4><a
name="TestezvosapplicationsFlexavecF"></a>Testez vos applications Flex avec Fluint</h4><p>Lors de l&#8217;une de nos <a
href="http://blog.xebia.fr/2008/10/20/revue-de-presse-xebia-79/#Testezunitairementetfonctionne" title="récentes revue de presse" >récentes revue de presse</a> nous vous parlions de <a
href="http://code.google.com/p/flexmonkey/" title="FlexMonkey" >FlexMonkey</a>, outil permettant d&#8217;enregistrer des tests fonctionnels à la manière d&#8217;un Selenium, mais sur des applications Flex.</p><p>Dans cet <a
href="http://www.infoq.com/news/2008/10/fluint-unit-test-for-flex" title="article de Moxie Zhang" >article de Moxie Zhang</a>, un autre outil nous est proposé et se nomme <a
href="http://code.google.com/p/fluint/" title="Fluint" >Fluint</a>. A l&#8217;origine développé chez <a
href="http://www.digitalprimates.net/" title="Digital Primates" >Digital Primates</a>, cet outil est passé Open Source et permet de mettre en place des tests unitaires ainsi que des tests d&#8217;intégrations. En effet la majorité des outils ne permettent pas de tester les interactions (souvent asynchrones) entre les composants, et Fluint permet d&#8217;effectuer ce genre de tests.</p><p>La documentation pour la mise en place est bien fournie, et permet de créer assez rapidement des suites de tests.</p><p>A travers ces outils, nous voyons que les technologies RIA, et plus particulièrement Flex remportent de plus en plus de succès, alors qu&#8217;attendez vous pour franchir le pas ?</p><h3><a
name="Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="EnversrejointHibernate"></a>Envers rejoint Hibernate</h4><p>Peu de temps après sa <a
href="http://blog.xebia.fr/2008/07/21/revue-de-presse-xebia-66/#EnversJBossajouteJPAleversioni" title="première release officielle" >première release officielle</a>, Adam Warski, développeur principal de <a
href="http://www.jboss.org/envers/" title="JBoss Envers" >JBoss Envers</a>, a annoncé cette semaine sur <a
href="http://www.warski.org/blog/?p=34" title="son blog" >son blog</a> l&#8217;intégration de ce framework de versioning d&#8217;entités comme module d&#8217;Hibernate. S&#8217;il n&#8217;apparaît pas encore sur <a
href="http://www.hibernate.org/" title="la page officielle du projet" >la page officielle du projet</a>, les sources ont d&#8217;ores et déjà été migrées sur le <a
href="http://anonsvn.jboss.org/repos/hibernate/core/trunk/" title="repository d'Hibernate" >repository d&#8217;Hibernate</a>. Aucun tag Hibernate ne dispose d&#8217;Envers pour le moment. Son intégration n&#8217;est d&#8217;ailleurs pas complètement terminée, <a
href="http://opensource.atlassian.com/projects/hibernate/secure/IssueNavigator.jspa?reset=true&#038;mode=hide&#038;pid=10031&#038;sorter/order=DESC&#038;sorter/field=priority&#038;resolution=-1&#038;component=10280" title="quelques modifications" >quelques modifications</a> restent à régler avant sa première release sous ce nouveau nom. <a
href=" http://opensource.atlassian.com/projects/hibernate/browse/HHH-3570" title="Par exemple" >Par exemple</a>, l&#8217;annotation <code>@Versioned</code> sera renommée <code>@Audited</code> pour éviter toute confusion avec <code>@Version</code> de JPA. La première version d&#8217;Hibernate proposant les fonctionnalités d&#8217;Envers devrait donc être la future 3.4.</p><p>Pour mémoire, Envers vous permet de versionner simplement la plupart de vos mappings JPA et Hibernate. A l&#8217;image de Subversion, il offre un mécanisme de révisions et un moyen d&#8217;effectuer des recherches sur son historique.</p><h3><a
name="EvnementsdenotrecommunautenFra"></a>Evènements de notre communauté en France et à l&#8217;étranger</h3><h4><a
name="GWTauParisJUGdeNovembre"></a>GWT au Paris JUG de Novembre</h4><p>Le <a
href="http://www.parisjug.org/xwiki/bin/view/Meeting/20081104" title="prochain Paris JUG" >prochain Paris JUG</a> se tient demain 4 Novembre, dans les locaux de <a
href="http://www.parisjug.org/xwiki/bin/view/Location/ISEP" title="l'ISEP" >l&#8217;ISEP</a>.</p><p>Au programme de la soirée:</p><ul><li>Une présentation de Google Web Toolkit, par Didier Girard, directeur technique de SFEIR.</li><li>Puis une démonstration de l&#8217;API Restlet portée sur GWT, <a
href="http://wiki.restlet.org/docs_1.1/13-restlet/144-restlet.html" title="Restlet-gwt" >Restlet-gwt</a>, par Jérôme Louvel, l&#8217;auteur de Restlet.</li></ul><h4><a
name="XKEleprogrammedelasessiondeNov"></a>XKE, le programme de la session de Novembre</h4><p>Le prochain XKE (Xebia Knowledge Exchange) aura lieu le jeudi 6 Novembre 2008. Les sujets suivants seront abordés :</p><ul><li>WSI-Basic profiles.</li><li><a
href="http://www.zeroturnaround.com/javarebel/" title="Java Rebel" >Java Rebel</a>.</li><li>La galaxie GWT, un tour d&#8217;horizon des projets qui gravitent et améliorent le célèbre framework de Google.</li><li>DDD &#8211; Domain Driven Design.</li><li><a
href="http://sourceforge.net/projects/liquibase/" title="Liquid Base" >Liquid Base</a>, un outil qui gère les modifications de schéma de base de données.</li><li><a
href="http://www.springsource.org/osgi" title="Spring Dynamic Modules" >Spring Dynamic Modules</a>, l&#8217;OSGI vu à la sauce Spring.</li><li>Les outils de la JVM.</li></ul><p>Comme nous l&#8217;<a
href="http://blog.xebia.fr/2008/02/06/xebia-ouvre-ses-journees-de-partage-de-la-connaissance-xke/" title="annoncions" >annoncions</a>, les XKE sont ouverts à l&#8217;ensemble des personnes à l&#8217;écoute du marché de l&#8217;emploi autour des technologies Java/J2EE. Si vous êtes l&#8217;une d&#8217;entre elles, n&#8217;hésitez pas à contacter <a
href="mailto:mbacrot@xebia.fr" title="Mélanie Bacrot" >Mélanie Bacrot</a> pour vous inscrire.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2008/11/03/revue-de-presse-xebia-81/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>AppFuse par l&#8217;exemple</title><link>http://blog.xebia.fr/2008/09/18/appfuse-par-lexemple/</link> <comments>http://blog.xebia.fr/2008/09/18/appfuse-par-lexemple/#comments</comments> <pubDate>Thu, 18 Sep 2008 09:37:14 +0000</pubDate> <dc:creator>Aurélien Maury</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[AppFuse]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[JSF]]></category> <category><![CDATA[Maven]]></category> <category><![CDATA[Spring]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=681</guid> <description><![CDATA[Les IDE d&#8217;antan &#8211; on pense tout particulièrement au vénérable JBuilder &#8211; proposaient un ensemble de &#171;&#160;wizards&#160;&#187;, permettant de générer en quelques clics le squelette de classes, de composants voir d&#8217;applications complètes. Rien à voir, bien sûr, avec les ambitions démesurées du MDA : les wizards se contentaient de générer un ensemble de sources plus [...]]]></description> <content:encoded><![CDATA[<p>Les IDE d&#8217;antan &#8211; on pense tout particulièrement au vénérable JBuilder &#8211; proposaient un ensemble de &laquo;&nbsp;wizards&nbsp;&raquo;, permettant de générer en quelques clics le squelette de classes, de composants voir d&#8217;applications complètes. Rien à voir, bien sûr, avec les ambitions démesurées du MDA : les wizards se contentaient de générer un ensemble de sources plus ou moins prêtes à l&#8217;emploi dans l&#8217;objectif d&#8217;accélérer certaines tâches de développement répétitives et peu valorisantes. Ruby on Rails a remis cette approche au goût du jour, et l&#8217;a baptisé du nom barbare de &laquo;&nbsp;<a
title="scaffolding" href="http://en.wikipedia.org/wiki/Scaffold_(programming)">scaffolding</a>&laquo;&nbsp;.</p><p>Le scaffolding fait le bonheur des rubyistes en leur permettant, au prix de l&#8217;exécution de quelques lignes de commandes, de disposer d&#8217;une application web opérationnelle, autorisant la manipulation élémentaire des données de leur modèle au travers d&#8217;écrans de saisie et de listes &#8211; charge au développeur d&#8217;enrichir ensuite le code généré pour implémenter un comportement plus sophistiqué.</p><p>Le projet <a
title="AppFuse" href="http://appfuse.org/display/APF/Home">AppFuse</a>, aujourd&#8217;hui dans sa version 2.0, s&#8217;appuie sur les archétypes Maven 2 pour offrir aux développeurs Java des fonctionnalités équivalentes. Dans cet article, nous vous proposons une introduction par l&#8217;exemple à AppFuse.</p><h3><a
name="Mavenrappels"></a>Maven : rappels</h3><p>Pour ceux qui ne sont pas encore familiers avec Maven, voici quelques rappels de base pour pouvoir suivre cet article.</p><p>Maven est un outil open-source de build pour les projets Java. Il a été conçu pour simplifier les tâches difficiles du processus de build. Maven offre la possibilité de démarrer un projet en utilisant des squelettes d&#8217;application. Ces squelettes, dans la terminologie Maven, sont appelés &laquo;&nbsp;archétypes&nbsp;&raquo;. Grâce à eux, une ligne de commande permet de démarrer avec une hiérarchie de répertoire standardisée (sources, resources, builds).</p><p>Tous les archétypes Maven comportent un fichier &laquo;&nbsp;pom.xml&nbsp;&raquo; contenant toutes les directives de construction du projet, ses dépendances et différents plugins accessibles. Les plugins Maven couvrent, entre autres, des outils d&#8217;analyse de code, de formatage et de génération de rapport.</p><p>Pour plus d&#8217;informations sur ces notions, je vous conseille de jeter un oeil sur les sites suivants :</p><ul><li>Maven : <a
href="http://maven.apache.org/">http://maven.apache.org/</a></li><li>Plugin d&#8217;intégration Maven/Eclipse : <a
href="http://m2eclipse.codehaus.org/">http://m2eclipse.codehaus.org/</a></li><li>Mojo Project (plugins Maven) : <a
href="http://mojo.codehaus.org/">http://mojo.codehaus.org/</a></li></ul><h3><a
name="AppFuse"></a>AppFuse</h3><h4><a
name="Concept"></a>Concept</h4><p>Initialement créé par Matt Raible, AppFuse est un projet open source pour développer des applications web J2EE. Il permet aux développeurs de démarrer rapidement et facilement en utilisant des technologies open-source telles que Spring, Hibernate et différents frameworks web (Struts2, Spring MVC, Tapestry, &#8230;).</p><p>AppFuse est un ensemble de scripts de génération de code permettant de faire le travail le plus pénible très rapidement, typiquement les écrans <a
title="CRUD" href="http://fr.wikipedia.org/wiki/CRUD">CRUD</a> (Create, Read, Update, Delete) de votre modèle de données.</p><h4><a
name="Utilisation"></a>Utilisation</h4><p>Initialement conçu avec Ant, Appfuse s&#8217;appuie, depuis sa version 2, sur Maven via des archétypes et des plugins de génération de code.</p><p><strong><a
name="ArchtypesMaven"></a>Archétypes Maven</strong></p><p>Les différents archétypes fournis par le projet AppFuse couvrent différents frameworks Web, couplés avec Hibernate et Spring :</p><ul><li><a
title="JSF" href="http://mbaron.ftp-developpez.com/javaee/jsf.pdf">JSF</a></li><li><a
title="Struts2" href="http://struts.apache.org/2.x/">Struts2</a></li><li><a
title="Spring MVC" href="http://springframework.org/node/277">Spring MVC</a></li><li><a
title="Tapestry" href="http://tapestry.apache.org/">Tapestry</a></li></ul><p>AppFuse propose pour tous ces outils de généré un projet d&#8217;application simple ou un projet multi-modules contenant un projet noyau et des projets modulaires. Il est également possible de générer uniquement le backend d&#8217;application. Vous pourrez brancher dessus votre framework préféré.</p><p>Chaque archétype AppFuse crée une application complète comprenant :</p><ul><li>la gestion de la sécurité</li><li>une interface d&#8217;administration des utilisateurs et des rôles.</li><li>plusieurs thèmes CSS</li><li>la création automatique de la base de données</li><li>la population automatique de la base avec un jeu de données de test.</li></ul><p><strong><a
name="Pluginsdegnrationdecode"></a>Plugins de génération de code</strong></p><p>Une fois votre projet démarré avec l&#8217;archétype de votre choix, vous pourrez ajouter vos beans de données et les mapping Hibernate associés selon la méthode que vous préférez (annotations ou fichiers hbm.xml).</p><p>Une fois votre modèle posé, le plugin Maven &laquo;&nbsp;appfuse:gen&nbsp;&raquo; s&#8217;occupera pour vous de créer les classes de DAO, Managers et vues correspondantes pour obtenir les écrans de gestion élémentaires (CRUD).<br
/> Chaque lancement du plugin se fait sur une classe du modèle de données et fournit :</p><ul><li>une vue avec un tableau triable contenant l&#8217;ensemble des instances persistées en base</li><li>un formulaire de saisie/suppression</li><li>un jeu de données pour les tests</li><li>les DAO et Managers associés</li></ul><p>Conformément aux principes du scaffolding, la génération de code et de configuration possède ses limites et il est souvent nécessaire d&#8217;effectuer quelques corrections manuelles lorsque le modèle de données est un peu évolué.</p><p>Par exemple, dans le cas de relations ManyToOne, le formulaire de saisie d&#8217;un bean doit comporter une liste permettant de sélectionner avec quel objets faire le lien. Ce cas nécessite de faire des modifications dans l&#8217;Action Struts pour que la liste s&#8217;affiche effectivement dans le formulaire web. Nous allons voir ce genre de manipulation dans la partie pratique.</p><h4><a
name="HandsonHibernateSpringStruts"></a>Hands-on : Hibernate, Spring, Struts2</h4><p>Un bon exemple valant souvent mieux qu&#8217;un long discours, nous vous proposons de créer pas à pas une application web simple, permettant de saisir des constructeurs automobiles et des voitures liées à ces constructeurs.</p><p>L&#8217;environnement technique est le suivant :</p><ul><li>Struts 2</li><li>Java 5</li><li>Maven (&gt;= 2.0.6 mais 2.0.9 est plus sûr pour les <a
title="corrections sur les classpaths" href="http://maven.apache.org/release-notes.html">corrections sur les classpaths</a> )</li><li>accès au web depuis le poste de développement</li></ul><h4><a
name="Dmarrageduprojet"></a>Démarrage du projet</h4><p>Création de notre squelette de projet avec l&#8217;archétype <strong>appfuse-basic-struts</strong> :</p><pre class="brush: java; title: ; notranslate">
mvn archetype:create -DarchetypeGroupId=org.appfuse.archetypes
-DarchetypeArtifactId=appfuse-basic-struts
-DremoteRepositories=http://static.appfuse.org/releases
-DarchetypeVersion=2.0.1
-DgroupId=fr.xebia.blog.voiture -DartifactId=voiture-app
</pre><p>Un répertoire &laquo;&nbsp;voiture-app&nbsp;&raquo; contenant notre squelette applicatif vient d&#8217;apparaître. Les amateurs d&#8217;Eclipse pourront ajouter :</p><pre class="brush: java; title: ; notranslate">
cd voiture-app
mvn eclipse:eclipse
</pre><p>&#8230; pour que Maven créé les fichiers indispensables à Eclipse pour importer le projet.</p><p>Les archétype AppFuse placent la majeure partie du code de l&#8217;application en dépendances dans le pom.xml.<br
/> Pour pouvoir modifier le comportement de l&#8217;application et avoir tout sous les yeux, nous devons couper ces dépendances avec AppFuse et rapatrier le code.</p><p>Cela se fait très simplement en lançant :</p><pre class="brush: java; title: ; notranslate">
mvn appfuse:full-source
</pre><h4><a
name="crituredumodle"></a>Écriture du modèle</h4><p>Ajoutons maintenant notre modèle de données. Pour plus de simplicité, nous allons y intégrer directement les annotations utiles à la persistance. Les classes que l&#8217;on souhaite passer au générateur de code doivent se trouver directement dans le package &laquo;&nbsp;model&nbsp;&raquo; du projet. Dans notre cas il s&#8217;agit de &laquo;&nbsp;fr.xebia.blog.voiture.model&nbsp;&raquo;.</p><p><strong><a
name="ClasseConstructeurAutomobile"></a>Classe : ConstructeurAutomobile</strong></p><p><strong>src/main/java/fr/xebia/blog/voiture/model/ConstructeurAutomobile.java</strong></p><pre class="brush: java; title: ; notranslate">
package fr.xebia.blog.voiture.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class ConstructeurAutomobile {
  private Long id;
  private String nom;
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }
  @Column(length=50)
  public String getNom() {
    return nom;
  }
  public void setNom(String nom) {
    this.nom = nom;
  }
}
</pre><p><strong><a
name="ClasseVoiture"></a>Classe : Voiture</strong></p><p><strong>src/main/java/fr/xebia/blog/voiture/model/Voiture.java</strong></p><pre class="brush: java; title: ; notranslate">
package fr.xebia.blog.voiture.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
public class Voiture {
  private Long id;
  private String nom;
  private ConstructeurAutomobile constructeur;
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }
  @Column(length=50)
  public String getNom() {
    return nom;
  }
  public void setNom(String nom) {
    this.nom = nom;
  }
  @ManyToOne
  @JoinColumn(name=&quot;constructeur_id&quot;)
  public ConstructeurAutomobile getConstructeur() {
    return constructeur;
  }
  public void setConstructeur(ConstructeurAutomobile constructeur) {
    this.constructeur = constructeur;
  }
}
</pre><h4><a
name="GnrationdesCRUD"></a>Génération des CRUD</h4><p>Maintenant que nous disposons des classes, nous pouvons lancer la génération des écrans CRUD :</p><pre class="brush: java; title: ; notranslate">
mvn appfuse:gen -Dentity=ConstructeurAutomobile
mvn appfuse:gen -Dentity=Voiture
</pre><p><em>N.B. : Si vous omettez l&#8217;option -Dentity le nom de la classe ciblée est demandé en prompt.</em></p><p>Le générateur de code comporte cependant une lacune. Les classes sont bien ajoutées aux mappings Hibernate, mais pas pour les tests unitaires. Par conséquent, un <strong>mvn test</strong> tombera en erreur.</p><p>Le palliatif à cela est de copier les lignes de mapping dans :</p><p><strong>src/main/resources/hibernate.cfg.xml</strong></p><pre class="brush: java; title: ; notranslate">
&lt;hibernate-configuration&gt;
    &lt;session-factory&gt;
        &lt;mapping class=&quot;fr.xebia.blog.model.User&quot;/&gt;
        &lt;mapping class=&quot;fr.xebia.blog.model.Role&quot;/&gt;
&lt;!-- Les deux lignes suivantes nous intéressent --&gt;
        &lt;mapping class=&quot;fr.xebia.blog.voiture.model.ConstructeurAutomobile&quot;/&gt;
        &lt;mapping class=&quot;fr.xebia.blog.voiture.model.Voiture&quot;/&gt;
&lt;!-- Stop, pas plus loin, deux lignes seulement --&gt;
    &lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;
</pre><p>et de les coller dans le fichier <strong>src/test/resources/hibernate.cfg.xml</strong> pour garder ces deux fichiers en phase.</p><p>Vous pouvez le vérifier par vous même en lançant :</p><pre class="brush: java; title: ; notranslate">
mvn clean test -P hsqldb
</pre><p>{quote}<br
/> Plusieurs profils de base de données sont disponibles dans le pom.xml fourni par AppFuse (MySQL, PostgreSQL, Oracle, etc). Par souci de simplicité nous utilisons ici <a
title="HSQLDB" href="http://hsqldb.org/">HSQLDB</a>.<br
/> {quote}</p><h4><a
name="SupportdulienManyToOne"></a>Support du lien ManyToOne</h4><p>Le générateur AppFuse, bien que pratique, n&#8217;est pas omnipotent. Nous avons donc quelques manipulations à réaliser manuellement pour que le formulaire de saisie d&#8217;une Voiture soit complet.</p><p>Dans le fichier <strong>src/main/webapp/WEB-INF/pages/voitureForm.jsp</strong> vous pouvez voir cette ligne :</p><pre class="brush: java; title: ; notranslate">
&lt;s:select name=&quot;voiture.constructeur.id&quot; list=&quot;constructeurList&quot; listKey=&quot;id&quot; listValue=&quot;id&quot;&gt;&lt;/s:select&gt;
</pre><p>Il s&#8217;agit du tag Struts qui affiche la liste de sélection des constructeurs. Cependant, la classe VoitureAction, générée, ne fournit pas cette liste à la JSP, qui restera en conséquence désespérément vide à l&#8217;exécution. Notons également que par défaut, AppFuse affiche l&#8217;identifiant de l&#8217;entité dans la liste &#8211; ce qui ne correspond qu&#8217;exceptionnellement au besoin. Remplaçons la valeur de l&#8217;attribut <em>listValue</em> du tag <em>select</em> par &laquo;&nbsp;nom&nbsp;&raquo;. Ainsi, le nom du constructeur sera présenté dans la liste de sélection, plutôt que son identifiant.</p><p>Attaquons-nous au support de cette fameuse liste. Nous allons rajouter ceci au fichier :</p><p><strong>src/main/java/fr/xebia/blog/voiture/webapp/action/VoitureAction.java</strong></p><pre class="brush: java; title: ; notranslate">
[...]
import fr.xebia.blog.voiture.model.ConstructeurAutomobile;
[...]
  private GenericManager constructeurAutomobileManager;
  public void setConstructeurAutomobileManager(GenericManager constructeurAutomobileManager) {
    this.constructeurAutomobileManager = constructeurAutomobileManager;
  }
  public List getConstructeurList () {
    return (List) constructeurAutomobileManager.getAll();
  }
[...]
</pre><p>Comme l&#8217;attribut que nous rajoutons respecte les conventions de nommage et que la configuration Spring générée par AppFuse est correcte, l&#8217;injection de dépendances se fait automatiquement pour le constructeur AutomobileManager.</p><p>La méthode getConstructeurList, quant à elle, sera appelée par la JSP pour obtenir le contenu de la liste de sélection.</p><h4><a
name="Dmarrage"></a>Démarrage</h4><p>Nous pouvons maintenant effectuer un premier lancement de notre application grâce au plugin Jetty de Maven.  :</p><pre class="brush: java; title: ; notranslate">
mvn jetty:run-war -P hsqldb
</pre><p>Je vous laisse faire le tour du propriétaire en allant avec votre navigateur web sur <em>localhost:8080</em> pour vous mettre l&#8217;eau à la bouche, voici une liste non exhaustive de tout ce que nous avons obtenu en une demi-heure de travail :</p><ul><li>filtres de sécurité</li><li>gestion des utilisateurs en base</li><li>envois de mail en cas d&#8217;oubli d&#8217;un mot de passe ou de création de compte</li><li>écrans CRUD pour les constructeurs automobiles</li><li>écrans CRUD pour les voitures</li><li>un jeu de données inséré à chaque lancement des tests</li><li>export des listes de constructeurs et de voitures en CSV, XLS, PDF ou XML (Merci à <a
title="DisplayTag" href="http://displaytag.sourceforge.net/11/">DisplayTag</a>)</li><li>une CSS propre (ça fait toujours plaisir)</li><li>une foule de plugins très utiles placés dans le pom.xml : Cobertura, PMD, DBunit et d&#8217;autres</li><li>le support de l&#8217;internationalisation</li></ul><p>Et j&#8217;en oublie.</p><h3><a
name="Conclusions"></a>Conclusions</h3><p>AppFuse est, à mon avis, un excellent plugin Maven pour démarrer un projet d&#8217;application Web classique. Il n&#8217;est pas très polyvalent mais permet de se libérer d&#8217;une part assez fastidieuse du développement web : l&#8217;écriture des CRUD.</p><p>Le squelette d&#8217;application standardisé permet de s&#8217;y retrouver rapidement quand on gère plusieurs applications et de respecter un bon découpage des fichiers de configuration.</p><p>En fait ce plugin en fournit presque trop : trois semaines après je trouvais encore des morceaux de code inutilisés provenant du squelette, et qui m&#8217;ont facilité la vie, notamment pour l&#8217;exposition de WebServices grâce à XFire.</p><p>À mon avis un très bon outil, bien ciblé, à essayer.</p><p>Quelques ressources complémentaires :</p><ul><li><a
title="Seven simple reasons to use AppFuse" href="https://www.ibm.com/developerworks/java/library/j-appfuse/">Seven simple reasons to use AppFuse</a> par Matt Raible</li><li><a
title="AppFuse QuickStart" href="http://appfuse.org/display/APF/AppFuse+QuickStart" target="_blank">AppFuse QuickStart</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2008/09/18/appfuse-par-lexemple/feed/</wfw:commentRss> <slash:comments>9</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2008/08/19/revue-de-presse-xebia-70/</link> <comments>http://blog.xebia.fr/2008/08/19/revue-de-presse-xebia-70/#comments</comments> <pubDate>Tue, 19 Aug 2008 06:23:51 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[AMQP]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[J2EE]]></category> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[Méthodes agiles]]></category> <category><![CDATA[SCRUM]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/?p=581</guid> <description><![CDATA[La revue de presse de l’actualité Java/J2EE hebdomadaire proposée par Xebia. Actualité éditeurs / SSII Hibernate 3.3 sous le signe de Maven et de JBoss Cache Agilité Scrum-ban Le coin de la technique AMQP, l&#8217;avenir des Middlewares Orientés Message ? Performance et monitoring d&#8217;une application Java Actualité éditeurs / SSII Hibernate 3.3 sous le signe [...]]]></description> <content:encoded><![CDATA[<p><img
style="margin: 1em 1em 1em 1em; float: right;" src="http://blog.xebia.fr/wp-content/uploads/2007/06/revuedepresse.png" alt="Revue de Presse Xebia" /><br
/> <em>La revue de presse de l’actualité Java/J2EE hebdomadaire proposée par Xebia.</em></p><p><strong>Actualité éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2008/08/19/revue-de-presse-xebia-70/#HibernatesouslesginedeMavenetd">Hibernate 3.3 sous le signe de Maven et de JBoss Cache</a></li></ul><p><strong>Agilité</strong></p><ul><li><a
href="http://blog.xebia.fr/2008/08/19/revue-de-presse-xebia-70/#Scrumban">Scrum-ban</a></li></ul><p><strong>Le coin de la technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2008/08/19/revue-de-presse-xebia-70/#AMQPlavenirdesMiddlewareOrient">AMQP, l&#8217;avenir des Middlewares Orientés Message ?</a></li><li><a
href="http://blog.xebia.fr/2008/08/19/revue-de-presse-xebia-70/#Performanceetmonitoringduneapp">Performance et monitoring d&#8217;une application Java</a></li></ul><h3><a
name="ActualitditeursSSII"></a>Actualité éditeurs / SSII</h3><h4><a
name="HibernatesouslesginedeMavenetd"></a>Hibernate 3.3 sous le signe de Maven et de JBoss Cache</h4><p>Steve Ebersole, JBoss, présente dans <a
title="Hibernate 3.3: Redesigned, Modular JARs and a Refactored Caching System" href="http://www.infoq.com/news/2008/08/hibernate-33">Hibernate 3.3: Redesigned, Modular JARs and a Refactored Caching System</a> les grandes nouveautés de la version 3.3 du célèbre framework de persistence. Nous retiendrons :</p><ul><li>La migration du projet vers un nouveau build basé sur Maven 2 alors que JBoss semblait jusqu&#8217;ici réticent à cet outil de la fondation Apache.</li><li>La modularisation du monolythique hibernate.jar vers un ensemble de jars plus petits qui faciliteront la gestion des dépendances.</li><li>Le redesign du système de cache de second niveau, pour offrir aux utilisateurs un contrôle plus fin de celui ci à travers une nouvelle SPI. Cette nouvelle SPI introduit le partitionnement du cache par &#8216;région&#8217;.</li><li>L&#8217;intégration de <a
title="JBoss Cache 2.x" href="http://www.jboss.org/jbosscache/">JBoss Cache 2.x</a> comme cache de second niveau, utilisant cette nouvelle SPI en exploitant le nouveau mécanisme de partitionnement. A noter que JBoss Cache 2.x est le seul cache supporté nativement par cette nouvelle SPI, les autres implémentations (EHCache, etc) étant &#8216;bridgées&#8217; sur l&#8217;ancienne SPI aujourd&#8217;hui dépréciée.</li></ul><p>On notera aussi que JBoss, jusqu&#8217;ici agnostique avec <a
title="JBoss Micro Container" href="http://www.jboss.org/jbossmc/">JBoss Micro Container</a>, s&#8217;ouvre à OSGI avec l&#8217;appel de Steve Ebersole à la communauté pour participer à l&#8217;osgi-fication d&#8217;Hibernate (en réglant les problèmes de classloading et de redéfinition dynamique de la <code>SessionFactory</code> <a
title="déclarés dans Jira" href="http://opensource.atlassian.com/projects/hibernate/secure/IssueNavigator.jspa?reset=true&amp;&amp;pid=10031&amp;query=osgi&amp;summary=true&amp;description=true&amp;body=true&amp;environment=true">déclarés dans Jira</a>)</p><p>Sur le futur d&#8217;Hibernate, Steve Ebersole reste flou et rappelle que JBoss communique peu sur les roadmaps. On peut y voir le mode de gouvernance exclusive des projets open source de JBoss à la différence des gouvernances partagées que nous connaissons notamment avec la Fondation Apache qui débat de ces sujets sur les mailing lists publiques. Nous noterons deux des axes de travail pour la futures version 3.4 :</p><ul><li>Amélioration des performances et de l&#8217;utilisation des ressources dans le cadre des scénarios de <em>fail over en cluster</em>. On peut y voir des synergies avec les travaux menés sur <a
title="JBoss Application Server 5" href="http://www.infoq.com/news/2008/06/jboss-as5-rc1">JBoss Application Server 5</a> et JBoss Cache.</li><li>Introduction des &laquo;&nbsp;fetch profiles&nbsp;&raquo; qui rappellent <a
title="JDO" href="http://java.sun.com/jdo/">JDO</a> . Ces profiles permettent de définir des stratégies de requêtage en tant que metadata, et de les utiliser dynamiquement en Session à l&#8217;exécution.</li></ul><p><a
title="L'intégralité de l'article à lire sur InfoQ " href=" http://www.infoq.com/news/2008/08/hibernate-33">L&#8217;intégralité de l&#8217;article à lire sur InfoQ.</a></p><h3><a
name="Agilit"></a>Agilité</h3><h4><a
name="Scrumban"></a>Scrum-ban</h4><p><a
title="Corey Ladas" href="http://leansoftwareengineering.com/ksse/scrum-ban/">Corey Ladas</a> propose aux équipes Scrum d&#8217;évoluer vers le <a
title="Lean" href="http://fr.wikipedia.org/wiki/Lean">Lean</a> en <a
title="introduisant un système de Kanban" href="http://www.infoq.com/news/2008/08/Scrum-kanban">introduisant un système de Kanban</a>.</p><p>Le tableau des tâches utilisé par certaines équipes Scrum (avec les 3 colonnes <em>A faire, En cours, Terminée</em>) peut en effet rappeler le système des <a
title="Kanban" href="http://fr.wikipedia.org/wiki/Kanban">Kanban</a> utilisé dans les méthode de gestion de la production <a
title="Juste à temps (JAT)" href="http://fr.wikipedia.org/wiki/Juste-%C3%A0-temps_(gestion)">Juste à temps (JAT)</a>.<br
/> Corey propose de compléter ou de remplacer certaines pratiques Scrum pour aller vers un vrai Kanban :</p><ul><li>Limiter le nombre de fiches (user stories) en circulation pour éviter d&#8217;avoir un tas de fiches &laquo;&nbsp;en cours&nbsp;&raquo;</li><li>Amorcer une spécialisation fonctionnelle si le contexte s&#8217;y prête (si elle permet d&#8217;améliorer la productivité)</li><li>Remplacer le Burndown chart par un <a
title="Cumulative Flow Diagram" href="http://bdn1.borland.com/borcon2004/article/paper/0,1963,32096,00.html">Cumulative Flow Diagram</a> qui apportent d&#8217;avantage d&#8217;informations</li></ul><p>Il affirme également que la plupart des efforts dépensés dans les estimations sont du gâchis. Il rejoint ainsi le <a
title="débat" href="http://www.infoq.com/news/2008/08/estimates-wasteful">débat</a> initié par J.B. Rainsberger sur le <a
title="groupe Yahoo! extreme programming" href="http://tech.groups.yahoo.com/group/extremeprogramming/message/144469">groupe Yahoo! extreme programming</a>.</p><p>Au final Corey présente Scrum comme un cadre pouvant être utile à la construction d&#8217;une équipe avant d&#8217;aller vers une solution plus optimisée grâce au Kanban et au Lean.</p><h3><a
name="Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="AMQPlavenirdesMiddlewareOrient"></a>AMQP, l&#8217;avenir des Middlewares Orientés Message ?</h4><p>Jeff Gouyd, <a
title="Interop Systems" href="http://www.interopsystems.com/">Interop Systems</a>, présente dans <a
title="Can AMQP break IBM's MOM monopoly?" href="http://www1.interopsystems.com/analysis/can-amqp-break-ibms-mom-monopoly-part-1.html">Can AMQP break IBM&#8217;s MOM monopoly?</a> (<a
title="part 2" href="http://www1.interopsystems.com/analysis/can-amqp-break-ibms-mom-monopoly-part-2.html">part 2</a> et <a
title="part 3" href="http://www1.interopsystems.com/analysis/can-amqp-break-ibms-mom-monopoly-part-3.html">part 3</a>) les grands enjeux de l&#8217;initiative <a
title="AMQP" href="http://jira.amqp.org/confluence/display/AMQP/Advanced+Message+Queuing+Protocol">AMQP</a> (Advanced Message Queuing Protocol). Les points essentiels :</p><ul><li>AMQP vise à standardiser le protocole de transport des &laquo;&nbsp;middleware orientés message&nbsp;&raquo; (MOM) ; son objectif, très ambitieux, est de devenir le protocole le <em>business messaging</em> sur Internet à côté d&#8217;HTTP et de SMTP.</li><li>Le marché des MOM est aujourdhui dominé par IBM (Websphere MQ) et Tibco (RendezVous et EMS) qui totalisent 93% des parts de marché selon Gartner ; le troisième acteur, Progress Software (Sonic MQ) ne détient que 2% du marché. Beaucoup de clients estiment qu&#8217;IBM et Tibco profitent de leur position pour pratiquer des tarifs élevés et être peu enclin à l&#8217;interropérabilité.</li><li>AMQP a été initié par un client, JP Morgan Chase (JPMC) ; la version 1 du protocole est attendue pour la fin 2008 et les principales implémentations, toutes open source, sont <a
title="OpenAmq" href="http://www.openamq.org/">OpenAmq</a> (développé par <a
title="iMatix" href="http://www.imatix.com/">iMatix</a> pour JPMC), <a
title="Apache QPid" href="http://cwiki.apache.org/confluence/display/qpid/Index">Apache QPid</a> (ardement supporté par <a
title="RedHat" href="http://rhm.et.redhat.com/page/Main_Page">RedHat</a>) et <a
title="RabbitMQ" href="http://www.rabbitmq.com/">RabbitMQ</a> (<a
title="LShift" href="http://www.lshift.net/">LShift</a> et <a
title="CohesiveFT" href="http://www.cohesiveft.com/">CohesiveFT</a>.</li><li>AMQP et JMS : JMS standardise l&#8217;API Java d&#8217;accès à un MOM quand AMQP standardise le protocole de communication du MOM. Ces deux standards sont complémentaires, il y aura des connecteurs JMS pour AMQP comme il en existe aujourd&#8217;hui pour Websphere MQ et pour Tibco EMS.</li><li>AMQP et <a
title="WS-RM" href="http://en.wikipedia.org/wiki/WS-ReliableMessaging">WS-RM</a> (Reliable Messaging) : WS-RM a été introduit pour pallier au manque de fiabilité intrinsèque à HTTP alors qu&#8217;AMQP est un protocole qui intègre nativement la fiabilité ; il y a donc chevauchement. Les grandes différences d&#8217;AMQP par rapport à WS-RM sont le concept de file d&#8217;attente et le support de messages binaires. La participation de Paul Fremantle, président du comité du WS-RM à l&#8217;Oasis Group, à l&#8217;<a
title="AMQP Working Group" href="http://jira.amqp.org/confluence/display/AMQP/AMQP+Working+Group">AMQP Working Group</a> laisse augurer des synergies.</li><li>AMQP et ESB : les ESB utilisent traditionnellement un MOM pour leur couche transport ; AMQP se positionne comme le protocole possible du MOM sous-jacent d&#8217;un ESB. Par exemple, l&#8217;implémentation AMQP RabbitMQ annonce avoir séduit des clients initialement intéressés par Websphere MQ comme transport pour leur ESB Mule.</li></ul><h4><a
name="Performanceetmonitoringduneapp"></a>Performance et monitoring d&#8217;une application Java</h4><p>Dans un précédent article, nous vous avons présenté le <a
title="top 10 des problèmes de performance" href="http://blog.xebia.fr/2007/05/03/le-top-10-des-problemes-de-performances-des-applications-j2ee/">top 10 des problèmes de performance</a>.</p><p>Nicholas Whitehead présente dans <a
title="Java Runtime Monitoring" href="http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=Java+run-time+monitoring">Java Runtime Monitoring</a> (<a
title="part 1" href="http://www-128.ibm.com/developerworks/library/j-rtm1">part 1</a>, <a
title="part 2" href="http://www-128.ibm.com/developerworks/library/j-rtm2">part 2</a> et <a
title="part 3" href="http://www-128.ibm.com/developerworks/library/j-rtm3">part 3</a>) un guide sur le monitoring et la démarche d&#8217;évaluation de performance d&#8217;une application Java.</p><p>La gestion des performances applicatives suit des bonnes pratiques (APM, <em>application performance management</em>). Elle doit être :</p><ul><li><strong>Exhaustive</strong> : tous les éléments applicatifs et leurs dépendances doivent être monitorés. Cela va de l&#8217;application au matériel, en passant par le système d&#8217;exploitation ,les différents middlewares, et toute la chaine réseau.</li><li><strong>Précise</strong> : afin de localiser au mieux la source des problèmes, il faut des mesures en boite blanche. Si les mesures sont faites en boîte noire (par exemple au niveau de la JVM), le problème ne pourra pas être identifié et les pistes seront nombreuses (problème mémoire, thread, garbage collector, configuration de la JVM&#8230;).</li><li><strong>Cohérente</strong> : un problème a, la plupart du temps, des causes multiples. Il faut relier les causes entre elles mais aussi les lier aux conséquences. Par exemple, un problème de base de données peut être remonté par les logs applicatives.</li><li><strong>Constante</strong> : le monitoring doit être effectué 7 jours sur 7, 24 heures sur 24. De plus, les intervalles de relevé de mesures doivent être suffisamment courts pour ne pas avoir un manque d&#8217;information. Attention cependant à l&#8217;<em>overhead</em>.</li><li><strong>Efficace</strong> : La règle d&#8217;or du monitoring est que les outils de monitoring doivent avoir un <strong>overhead</strong> minimal et garanti. Il est difficile de justifier une dégradation des performances dûe aux outils de monitoring.</li><li>(proche du) <strong>temps-réel</strong> : selon le besoin de réactivité, les mesures doivent être collectées le plus rapidement possible.</li><li><strong>Tracée </strong>: Historisation, souvent négligé, est un outil très intéressant pour exploiter les applications J2EE. En effet, un problème de performance apparait dans un contexte défini (généralement de charge). Grâce à l&#8217;historisation des mesures et des problèmes, on peut caractériser repérer un problème identifié et (éventuellement) résolu. Ainsi les futures apparitions de ce problème pourront être anticipées.</li></ul><p>Ainsi les difficultés du monitoring résident essentiellement dans :</p><ul><li><strong>L&#8217;exhausitivité et la précision</strong> des informations relevées.</li><li><strong>L&#8217;intégration et l&#8217;articulation</strong> de sources d&#8217;information hétérogènes et nombreuses (matériel, OS, logs applicatives..)</li><li><strong>La gestion des spécificités de la plate-forme</strong> (spécificités applicatives, infrastructure réseau&#8230;)</li></ul><p>Depuis la JVM 5 et surtout 6, Sun fournit beaucoup d&#8217;efforts afin de résoudre ces problèmes de performance et de monitoring sur la partie JVM. Plusieurs outils et techniques sont maintenant à votre disposition pour réaliser différentes mesures :</p><ul><li>API JMX, pour le monitoring à distance</li><li>API d&#8217;instrumentation du code afin de réaliser des mesures boites blanches (<code>java.lang.instrument</code>)</li><li>Un panel d&#8217;outils : <a
title="hprof" href="http://java.sun.com/developer/technicalArticles/Programming/HPROF.html">hprof</a> pour le profiling heap/CPU, <a
title="jconsole" href="http://java.sun.com/javase/6/docs/technotes/tools/share/jconsole.html">jconsole</a> pour la gestion et monitoring de la JVM (à distance), <a
title="jhat" href="http://java.sun.com/javase/6/docs/technotes/tools/share/jhat.html">jhat</a> pour l&#8217;analyse de la heap, <a
title="jstat" href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html">jstat</a> pour collecter des informations de performance sur la JVM, <a
title="VisualVM" href="https://visualvm.dev.java.net/">VisualVM</a> &#8230;</li></ul><p>Retrouvez l&#8217;intégralité des articles :</p><ul><li><a
title="part 1 : Run-time performance and availability monitoring for Java systems" href="http://www-128.ibm.com/developerworks/library/j-rtm1">part 1 : Run-time performance and availability monitoring for Java systems</a></li><li><a
title="part 2 : Postcompilation instrumentation and performance monitoring" href="http://www-128.ibm.com/developerworks/library/j-rtm2">part 2 : Postcompilation instrumentation and performance monitoring</a></li><li><a
title="part 3 : Monitoring performance and availability of an application's ecosystem" href="http://www-128.ibm.com/developerworks/library/j-rtm3">part 3 : Monitoring performance and availability of an application&#8217;s ecosystem</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2008/08/19/revue-de-presse-xebia-70/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Revue de Presse Xebia</title><link>http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/</link> <comments>http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/#comments</comments> <pubDate>Mon, 28 Apr 2008 17:04:41 +0000</pubDate> <dc:creator>Xebia France</dc:creator> <category><![CDATA[Revue de presse]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[J2EE]]></category> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[JBoss]]></category> <category><![CDATA[JPA]]></category> <category><![CDATA[Méthodes agiles]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[OSGi]]></category> <category><![CDATA[REST]]></category> <category><![CDATA[Sun]]></category> <category><![CDATA[Websphere]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/</guid> <description><![CDATA[La revue de presse de l’actualité Java/J2EE hebdomadaire proposée par Xebia. Actualité éditeurs / SSII MySQL by Sun : Revirement de stratégie open source ? Choquant ? Superpackages (JSR-294) vs. OSGI : Episode n° 34291567&#8230;. Agilité User stories &#171;&#160;En tant que &#8230; je veux &#8230;&#160;&#187; Le coin de la technique De la sérialisation au parallélisme, [...]]]></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 de l’actualité Java/J2EE hebdomadaire proposée par Xebia.</em></p><p><strong>Actualité éditeurs / SSII</strong></p><ul><li><a
href="http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/#MySQLbySunRevirementdestratgie">MySQL by Sun : Revirement de stratégie open source ? Choquant ?</a></li><li><a
href="http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/#SuperpackagesJSRvsOSGIEpisoden">Superpackages (JSR-294) vs. OSGI : Episode n° 34291567&#8230;.</a></li></ul><p><strong>Agilité</strong></p><ul><li><a
href="http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/#UserstoriesEntantquejeveux">User stories &laquo;&nbsp;En tant que &#8230; je veux &#8230;&nbsp;&raquo;</a></li></ul><p><strong>Le coin de la technique</strong></p><ul><li><a
href="http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/#Delasrialisationauparalllismeu">De la sérialisation au parallélisme, une évolution incarnée par java.util.concurrent</a></li><li><a
href="http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/#InnovationautourdeJPAJBossHibe">Innovation autour de JPA : JBoss Hibernate confirme son domination avec Envers</a></li><li><a
href="http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/#VideoIntroductiontoWebSphereeX">Cas d&#8217;utilisation des grilles Java avec WebSphere eXtreme Scale/ ObjectGrid</a></li><li><a
href="http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/#JSRJAXRSRESTunehistoiredeRESTa">JSR-311 JAX-RS REST une histoire de RESTaurant</a></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/2008/04/28/revue-de-presse-xebia-54/#XKEleprogrammedelasessiondemai">XKE, le programme de la session de mai</a></li></ul><h3><a
name="ActualitditeursSSII"></a>Actualité éditeurs / SSII</h3><h4><a
name="MySQLbySunRevirementdestratgie"></a>MySQL by Sun : Revirement de stratégie open source ? Choquant ?</h4><p><a
href="http://slashdot.org/" title="Slashdot" >Slashdot</a> essaie de nous emmener sur une polémique &laquo;&nbsp;Sun gâche MySQL&nbsp;&raquo; avec <a
href="http://developers.slashdot.org/article.pl?sid=08/04/16/2337224" title="Sun May Begin Close Sourcing MySQL Features" >Sun May Begin Close Sourcing MySQL Features</a> à l&#8217;occasion de l&#8217;annonce par l&#8217;éditeur de fonctionnalités (online backup, etc) qui seront uniquement disponibles dans la version payante <a
href="http://www.mysql.com/products/enterprise/" title="MySQL Enterprise" >MySQL Enterprise</a>. Au delà de l&#8217;insinuation peu crédible quand on se rappelle que l&#8217;essentiel du catalogue de Sun est disponible gratuitement, on retrouve le défi aujourd&#8217;hui classique de la monétisation de l&#8217;Open Source. Le rachat de MySQL par Sun change complétement le modèle économique de l&#8217;éditeur de base de données.</p><p>Hier, la startup MySQL, financée par des fonds de capital risque, se permettait d&#8217;être déficitaire car les candidats au rachat (Oracle puis finalement Sun) ne valorisaient pas MySQL Inc sur ses revenus mais sur les parts de marché de sa base de données. La stratégie a magnifiquement porté ses fruits puisque MySQL Inc s&#8217;est vendue un milliard de dollars à Sun, félicitations au management.</p><p>Aujourd&#8217;hui, MySQL est vraisemblablement devenue une division &#8216;classique&#8217; de Sun et doit donc devenir rentable. L&#8217;équation de la rentabilité de l&#8217;open source est complexe, Red Hat et JBoss by Red Hat ont été des pionniers sur ce chemin, souhaitons à MySql by Sun de trouver lui aussi son modèle.</p><p><a
href="http://www.theserverside.com/news/thread.tss?thread_id=49087" title="TSS : MySQL to get new features in Enterprise version" >TSS : MySQL to get new features in Enterprise version</a></p><p><i><strong>Modification du billet le 29 Avril 2008 : Jonathan Schwartz est finalement revenu en arrière et a annoncé que tous les produits que Sun distribue, sans exception, sont proposés gratuitement en licence Open source à la communauté. Pour plus de détails sur cette histoire, nous vous recommandons la série de <a
href="http://www.the451group.com/">The 451 Group</a> : <a
href="http://blogs.the451group.com/opensource/2008/04/17/mysqls-business-model-in-a-state-of-flux/">MySQL’s business model in a state of flux</a>, <a
href="http://blogs.the451group.com/opensource/2008/04/24/finding-the-right-balance-mysql%e2%80%99s-changing-development-model/">Finding the right balance &#8211; MySQL’s changing development model</a> et <a
href="http://blogs.the451group.com/opensource/2008/04/28/jonathan-schwartz-has-the-last-word-on-mysql/">Jonathan Schwartz has the last word on MySQL</a></strong></i></p><h4><a
name="SuperpackagesJSRvsOSGIEpisoden"></a>Superpackages (JSR-294) vs. OSGI : Episode n° 34291567&#8230;.</h4><p>La guerre continue entre les partisans de OSGI et ceux des JSR de SuperPackage et de JAM. Cependant, l&#8217;attaque vient cette fois-ci d&#8217;<a
href="http://blogs.sun.com/abuckley/" title="Alex Buckley" >Alex Buckley</a> de chez Sun.</p><p>Il explique dans son <a
href="http://altair.cs.oswego.edu/pipermail/jsr294-modularity-eg/2008-March/000171.html" title="email" >email</a> les inconvénients qu&#8217;il voit dans l&#8217;implémentation actuelle des superpackages[1]. En substance, il propose d&#8217;introduire à la place un nouvel &#8216;access modifier&#8217; (module).</p><p>Peter Kriens de l&#8217;OSGi Alliance semble plutôt emballé par cette <a
href="http://www.osgi.org/blog/2008/04/jsr-294-superpackages-no-more.html" title="proposition" >proposition</a>.</p><p>[1] Pour mémoire, nous avons publié en février dernier un <a
href="http://blog.xebia.fr/2008/02/27/jsr-294-les-superpackages/" title="article présentant les superpackages" >article présentant les superpackages</a></p><h3><a
name="Agilit"></a>Agilité</h3><h4><a
name="UserstoriesEntantquejeveux"></a>User stories &laquo;&nbsp;En tant que &#8230; je veux &#8230;&nbsp;&raquo;</h4><p>Mike Cohn nous rappelle les 3 raisons pour lesquelles il préconise de décomposer les <a
href="http://www.mountaingoatsoftware.com/presentation/63-an-introduction-to-user-stories" title="user stories" >user stories</a> sous forme de phrase <a
href="http://blog.mountaingoatsoftware.com/?p=24" title=""En tant que &lt;role&gt;, je veux &lt;but&gt;, pour que &lt;raison&gt;"" >&laquo;&nbsp;En tant que &lt;role&gt;, je veux &lt;but&gt;, pour que &lt;raison&gt;&nbsp;&raquo;</a> (la raison est optionnelle) :</p><ul><li>L&#8217;emploi de la 1ère personne du singulier aide les développeurs à s&#8217;identifier à l&#8217;utilisateur</li><li>La structure de la phrase &#8211; représentée par 3 colonnes dans le <a
href="http://www.mountaingoatsoftware.com/product_backlog" title="Product backlog" >Product backlog</a> &#8211; aide le <a
href="http://www.mountaingoatsoftware.com/product_owner" title="Product Owner" >Product Owner</a> à comprendre et prioriser les user stories</li><li>Pour ne pas rajouter de bruit dans la description des user stories, il suffit de nommer les colonnes du Product backlog &laquo;&nbsp;En tant que &#8230;&nbsp;&raquo;, &laquo;&nbsp;je veux &#8230;&nbsp;&raquo;, &laquo;&nbsp;pour que &#8230;&nbsp;&raquo; et le backlog devient intuitif à lire.</li></ul><h3><a
name="Lecoindelatechnique"></a>Le coin de la technique</h3><h4><a
name="Delasrialisationauparalllismeu"></a>De la sérialisation au parallélisme, une évolution incarnée par java.util.concurrent</h4><p>La programmation multi-threadée en java a évoluée : anciennement on utilisait la sérialisation incarnée par <code>synchronized</code>, désormais on peut faire du parallélisme avec l&#8217;introduction des API <code>java.util.concurrent</code> en Java 5.</p><p>Sharadjava nous présente dans sa Java Concurrency Series les différents aspects de cette nouvelle librairie :</p><ul><li><a
href="http://www.techgrasp.com/blogs/sharadjava/java-concurrency-series-simple-executor-example" title="Simple Executor example" >Simple Executor example</a> pour la parallélisation des tâches.</li><li><a
href="http://www.techgrasp.com/blogs/sharadjava/java-concurrency-series-examples-barrier" title="Barrier" >Barrier</a> pour l&#8217;attente entre tâches (on n&#8217;oubliera pas sur ce sujet le <a
href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html" title="CountDownLatch" >CountDownLatch</a>).</li><li><a
href="http://www.techgrasp.com/blogs/sharadjava/java-concurrency-series-meaning-volatile-variable" title="Meaning of volatile" >Meaning of volatile</a> pour la visibilité inter-threads des valeurs des variables.</li></ul><h4><a
name="InnovationautourdeJPAJBossHibe"></a>Innovation autour de JPA : JBoss Hibernate confirme son domination avec Envers</h4><p>Après l&#8217;intégration de la recherche full text Lucene [1] et le support du Database Sharding, <a
href="http://www.hibernate.org" title="Hibernate" >Hibernate</a> confirme sa domination de l&#8217;innovation autour de JPA en ouvrant le chantier du versionnage des données. Cette problématique, bien que récurrente et accentuée par les nouvelles contraintes réglementaires (Sarbane &#038; Oaxley, etc), restait largement ignorées par nos frameworks et nos très chers design patterns. Seul Martin Fowler nous éclairait sur ce sujet délicat avec <a
href="http://www.martinfowler.com/ap2/timeNarrative.html" title="Patterns for things that change with time" >Patterns for things that change with time</a>.</p><p>JBoss comble aujourd&#8217;hui ce vide en lançant <a
href="http://www.jboss.org/envers/" title="Envers" >Envers</a>, une extension d&#8217;Hibernate qui versionne les données persistantes selon un pattern similaire au <a
href="http://www.martinfowler.com/ap2/temporalObject.html" title="Temporal Object" >Temporal Object</a> de Martin Fowler. Envers n&#8217;est qu&#8217;en version preview mais le projet est très prometteur et déjà une source d&#8217;inspiration pour les projets qui n&#8217;ont pas le temps d&#8217;attendre la première version stable.</p><p>On notera au passage qu&#8217;Envers préfère l&#8217;API standard JPA EntityManager à l&#8217;historique Session Hibernate ; on peut y voir un signe que le temps est venu pour les équipes projets de privilégier les standards JPA aux API historiques Hibernate.</p><p>Exemple d&#8217;entité persistante versionnée avec JBoss Envers</p><pre class="brush: java; title: ; notranslate">
@Entity
public class Person {
    @Id
    @GeneratedValue
    private Integer id;
    @Versioned
    private String name;
    @Versioned
    private String surname;
    @Versioned
    @ManyToOne
    private Address address;
   ...
}
</pre><p>[1] cf notre billet <a
href="http://blog.xebia.fr/2008/03/06/introduction-a-hibernate-search-googling-your-persistent-domain-model/" title="Introduction à Hibernate Search (Googling your Persistent Domain Model)" >Introduction à Hibernate Search (Googling your Persistent Domain Model)</a></p><h4><a
name="VideoIntroductiontoWebSphereeX"></a>Cas d&#8217;utilisation des grilles Java avec WebSphere eXtreme Scale/ ObjectGrid</h4><p>Billy Newport présente dans <a
href="http://www.devwebsphere.com/devwebsphere/2008/04/video-introduct.html" title="Video: Introduction to WebSphere eXtreme Scale/ObjectGrid with patterns and use cases" >Video: Introduction to WebSphere eXtreme Scale/ObjectGrid with patterns and use cases</a> les scénarios typiques d&#8217;utilisation de la grille Java d&#8217;IBM :</p><ul><li>Cache de proximité classique : la grille sert de Map distribuée ; l&#8217;application métier gère les données (chargement depuis les backends, mise en cache et sauvegarde des modifications dans les backends).</li><li>Cache de proximité avec &laquo;&nbsp;Loader synchrone&nbsp;&raquo; dans la grille : l&#8217;application métier se limite à demander des données à la grille et à les modifier ; la grille, grâce à un Loader, s&#8217;occupe de charger les données depuis les backends et sauvegarde en synchrone les données modifiées dans les backends.</li><li>Cache de proximité avec un &laquo;&nbsp;Loader à écriture différée&nbsp;&raquo; dans la grille : similaire au scénario précédent mais la sauvegarde des modifications dans les backends est asynchrone.</li><li>Cache collocalisé : l&#8217;application et la grille s&#8217;éxécutent dans les même JVM, chaque JVM héberge un noeud du cluster de l&#8217;application et un noeud de la grille. Ce scénario est typique de la mise en cache des sessions HTTP.</li></ul><p>On notera que les architectures de type <a
href="http://en.wikipedia.org/wiki/MapReduce" title="Map/Reduce" >Map/Reduce</a>, qui nécessitent une conception radicalement différente, ne semblent pas encore très répandues.</p><h4><a
name="JSRJAXRSRESTunehistoiredeRESTa"></a>JSR-311 JAX-RS REST une histoire de RESTaurant</h4><p>Dans cet <a
href="http://www.touilleur-express.fr/2008/04/25/jsr-311-jax-rs-rest-une-histoire-de-restaurant/" title="article" >article</a>, Nicolas Martignole nous présente l&#8217;architecture REST (<a
href="http://en.wikipedia.org/wiki/Representational_State_Transfer" title="Representational State Transfer" >Representational State Transfer</a>) et <a
href="http://jcp.org/en/jsr/detail?id=311" title="JSR 311: JAX-RS: The Java API for RESTful Web Services" >JSR 311: JAX-RS: The Java API for RESTful Web Services</a>. L&#8217;objectif de cette JSR est de faciliter la programmation d&#8217;applications REST en Java.<br
/> La première partie est consacrée à une introduction de REST (définition d&#8217;une ressource, lecture, création, mise à jour, suppression d&#8217;une ressource, Services Webs RESTfull).<br
/> La deuxième partie nous présente quelques détails sur l&#8217;implémentation JAX-RS avec Java.</p><h3><a
name="EvnementsdenotrecommunautenFra"></a>Evènements de notre communauté en France et à l&#8217;étranger</h3><h4><a
name="XKEleprogrammedelasessiondemai"></a>XKE, le programme de la session de mai</h4><p>Le prochain XKE (Xebia Knowledge Exchange) aura lieu le <strong>mardi</strong> 6 Mai 2008. Les sujets suivants seront abordés :</p><ul><li>Sessions Pratiques<ul><li>Terracotta, the Network Attached Memory (NAM)</li><li>java.util.concurrent, concours de developpement</li></ul></li></ul><ul><li>Technique<ul><li>Java et la Cryptographie</li></ul></li></ul><ul><li>Architecture<ul><li>Retour sur l&#8217;architecture de l&#8217;un des plus grand site de ecommerce de France</li><li><a
href="http://xp-france.net/index.php?option=com_content&#038;task=view&#038;id=48&#038;Itemid=120#S836" title="Tests unitaires avec les librairies de Mock" >Tests unitaires avec les librairies de Mock</a></li></ul></li></ul><ul><li>Xebia Hollande<ul><li>Intervention du CTO de <a
href="http://www.xebia.com" title="Xebia Hollande" >Xebia Hollande</a></li></ul></li></ul><p>Comme nous l&#8217;annoncions, les XKE sont <a
href="http://blog.xebia.fr/2008/02/06/xebia-ouvre-ses-journees-de-partage-de-la-connaissance-xke/" title="ouverts" >ouverts</a> à l&#8217;ensemble des personnes à l&#8217;écoute du marché de l&#8217;emploi autour des technologies Java/J2EE. Si vous êtes l&#8217;une d&#8217;entre elles , n&#8217;hésitez pas à contacter <a
href="mailto:mbacrot@xebia.fr" title="Mélanie Bacrot" >Mélanie Bacrot</a> pour vous inscrire.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2008/04/28/revue-de-presse-xebia-54/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Hands on Hibernate Search : Recherche full-text</title><link>http://blog.xebia.fr/2008/03/28/hands-on-hibernate-search-recherche-full-text/</link> <comments>http://blog.xebia.fr/2008/03/28/hands-on-hibernate-search-recherche-full-text/#comments</comments> <pubDate>Fri, 28 Mar 2008 07:29:48 +0000</pubDate> <dc:creator>Christophe Heubès</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[développement]]></category> <category><![CDATA[Hibernate]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/2008/03/28/hands-on-hibernate-search-recherche-full-text/</guid> <description><![CDATA[Comme nous l&#8217;avions vu dans notre précédent billet (&#171;&#160;Introduction à Hibernate Search (Googling your Persistent Domain Model)&#171;&#160;), Hibernate Search vise à réconcilier la recherche full-text et les modèles de persistance relationnels. Pour ce faire, Hibernate Search se base sur Apache Lucene, un moteur d’indexation et de recherche full-text standalone très puissant et permet ainsi d’utiliser [...]]]></description> <content:encoded><![CDATA[<p>Comme nous l&#8217;avions vu dans notre précédent billet <em>(&laquo;&nbsp;<a
href="http://blog.xebia.fr/2008/03/06/introduction-a-hibernate-search-googling-your-persistent-domain-model/">Introduction à Hibernate Search (Googling your Persistent Domain Model)</a>&laquo;&nbsp;)</em>, Hibernate Search vise à réconcilier la recherche full-text et les modèles de persistance relationnels.<br
/> Pour ce faire, Hibernate Search se base sur <a
href="http://lucene.apache.org">Apache Lucene</a>, un moteur d’indexation et de recherche full-text standalone très puissant et permet ainsi d’utiliser ses capacités dans le cadre d’une couche de mapping Hibernate.</p><p>Ce billet présente, au travers d&#8217;un exemple simple, les capacités de recherche full-text d&#8217;Hibernate Search.<br
/> L&#8217;exemple proposé permet l&#8217;indexation et la recherche de documents auxquels sont attachés des auteurs.<br
/> Vous retrouverez l&#8217;ensemble des sources présentées dans ce billet dans le repository <a
href="http://code.google.com/p/xebia-france/source/browse/trunk/search/hibernate-search-demo/">SVN de Xebia France</a>.</p><h3>Structuration du projet et démarrage</h3><p>Le projet utilise maven. Une fois les sources récupérées depuis notre dépot SVN, vous pouvez donc générer une configuration Eclipse à l&#8217;aide de la commande :</p><pre class="brush: bash; title: ; notranslate">
mvn eclipse:eclipse
</pre><p>Le projet déclare des dépendances vers :</p><ul><li>hibernate-search en version 3.0.0.ga.</li><li>hibernate-annotations en version 3.3.0.ga.</li><li>hibernate-entitymanager en version 3.3.1.ga.</li><li>lucene-analyzers en version 2.3.1.</li></ul><pre class="brush: xml; title: ; notranslate">
&lt;dependency&gt;
	&lt;groupId&gt;org.hibernate&lt;/groupId&gt;
	&lt;artifactId&gt;hibernate-search&lt;/artifactId&gt;
	&lt;version&gt;3.0.0.ga&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
	&lt;groupId&gt;org.hibernate&lt;/groupId&gt;
	&lt;artifactId&gt;hibernate-annotations&lt;/artifactId&gt;
	&lt;version&gt;3.3.0.ga&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
	&lt;groupId&gt;org.hibernate&lt;/groupId&gt;
	&lt;artifactId&gt;hibernate-entitymanager&lt;/artifactId&gt;
	&lt;version&gt;3.3.1.ga&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
	&lt;groupId&gt;org.apache.lucene&lt;/groupId&gt;
	&lt;artifactId&gt;lucene-analyzers&lt;/artifactId&gt;
	&lt;version&gt;2.3.1&lt;/version&gt;
&lt;/dependency&gt;
</pre><p>Le projet est structuré sur l&#8217;arborescence classique maven :</p><ul><li><code>src\main\java</code> contient les sources du projet :<br
/> &nbsp;&nbsp;&nbsp;-&nbsp;Le package <code>fr.xebia.demo.hibernate.search.model</code> contient les entités persistées qui seront mappées dans un index Lucene.<br
/> &nbsp;&nbsp;&nbsp;-&nbsp;Le package <code>fr.xebia.demo.hibernate.search.analysis</code> contient un analyseur de langue anglaise.</li><li><code>src\main\test</code> contient les sources des tests. Les tests &laquo;&nbsp;unitaires&nbsp;&raquo; ont ici été détournés pour faire la démonstration des capacités d&#8217;indexation et de recherche full-text d&#8217;Hibernate Search.</li></ul><h3>Mapping des entités sur l&#8217;index</h3><p>Le mapping des entités dans un index Lucene se fait par annotation :</p><ul><li>L&#8217;annotation <strong><code>@Indexed</code></strong> déclare une classe comme indexable</li><li>L&#8217;annotation <strong><code>@Analyzer</code></strong> définit l&#8217;implémentation d&#8217;analyseur syntaxique à utiliser pour cette indexation :</li></ul><pre class="brush: java; title: ; notranslate">
@Entity
@Indexed
@Analyzer(impl = SimpleEnglishAnalyzer.class)
@Table(name = DOCUMENT_TABLE_NAME)
public class Document {
</pre><ul><li>L&#8217;annotation <strong><code>@DocumentId</code></strong> indique l&#8217;attribut à utiliser en tant qu&#8217;identifiant. Cet identifiant est utilisé par Hibernate Search afin d&#8217;assurer l&#8217;unicité des entités dans l&#8217;index :</li></ul><pre class="brush: java; title: ; notranslate">
@Id
@DocumentId
@Column(name = &quot;id&quot;, nullable = false)
public Long getId() {
	return this.id;
}
</pre><ul><li>L&#8217;annotation <strong><code>@Field</code></strong> marque un attribut comme devant être indexé. La propriété <code>index = Index.TOKENIZED</code> indique que le texte va être &laquo;&nbsp;tokenisé&nbsp;&raquo; via l&#8217;analyseur définit au niveau de la classe. La propriété <code>store = Store.NO</code> indique que le texte de l&#8217;attribut ne sera pas stocké dans l&#8217;index.</li></ul><pre class="brush: java; title: ; notranslate">
@Column(name = &quot;title&quot;)
@Field(index = Index.TOKENIZED, store = Store.NO)
public String getTitle() {
	return title;
}
@Column(name = &quot;summary&quot;)
@Field(index = Index.TOKENIZED, store = Store.NO)
public String getSummary() {
	return summary;
}
</pre><ul><li>Dans le cadre d&#8217;une association, l&#8217;annotation <strong><code>@IndexedEmbedded</code></strong> indique que l&#8217;objet associé doit être indexé dans l&#8217;index de l&#8217;entité racine. Dans notre exemple, cette méthode permet d&#8217;effectuer une recherche full-text sur les entités de type <code>Document</code> basée sur les propriétés de son attribut <code>author</code> :</li></ul><pre class="brush: java; title: ; notranslate">
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE,
		CascadeType.REFRESH }, fetch = FetchType.EAGER)
@JoinColumn(name = &quot;author_id&quot;)
@Fetch(FetchMode.JOIN)
@ForeignKey(name = &quot;fk_document_author_id&quot;)
@IndexedEmbedded
public Author getAuthor() {
	return author;
}
</pre><h4>Analyseur et tokeniseur</h4><p>La &laquo;&nbsp;tokenisation&nbsp;&raquo; consiste à découper un texte en mots. Ce découpage se fait en suivant les règles définies dans un analyseur. Hibernate Search propose par défaut l&#8217;utilisation de <code>org.apache.lucene.analysis.standard.StandardAnalyzer</code>.<br
/> Il est possible de définir son propre analyseur en étendant la classe abstraite <code>Analyzer</code> dont il faut implémenter la méthode</p><pre class="brush: java; title: ; notranslate">
public abstract TokenStream tokenStream(String fieldName, Reader reader);
</pre><p>C&#8217;est ce que propose la classe <code>SimpleEnglishAnalyzer</code> :</p><pre class="brush: java; title: ; notranslate">
@Override
public final TokenStream tokenStream(String fieldName, Reader reader) {
	if (fieldName == null)
		throw new IllegalArgumentException(&quot;fieldName must not be null&quot;);
	if (reader == null)
		throw new IllegalArgumentException(&quot;reader must not be null&quot;);
	TokenStream result = new StandardTokenizer(reader);
	result = new StandardFilter(result);
	result = new LowerCaseFilter(result);
	result = new StopFilter(result, stopTable);
	result = new PorterStemFilter(result);
	return result;
}
</pre><p>Cette implémentation passe les mots en minuscule, supprime les mots courants, et utilise le <code>PorterStemFilter</code> pour supprimer les terminaisons morphologiques communes.</p><h3>Configuration Hibernate Search</h3><p>La configuration d&#8217;Hibernate Search est câblée sur le système d&#8217;écoute d&#8217;événements. Elle est donc transparente avec Hibernate Annotations.<br
/> Dans le cadre de notre exemple, la configuration Hibernate est réalisée dans le set up de la classe <code>HibernateSearchDemoTestCase</code>. La seule propriété de configuration que nous spécifions pour Hibernate Search est le répertoire de stockage des index :</p><pre class="brush: java; title: ; notranslate">
@Override
protected void setUp() throws Exception {
	AnnotationConfiguration cfg = new AnnotationConfiguration();
	[...]
	cfg.setProperty(&quot;hibernate.search.default.indexBase&quot;, &quot;target&quot;);
	[...]
}
</pre><h3>Création et indexation des données de test</h3><p>La création des données de test se fait dans la méthode <code>populateDB</code> de la classe de test <i>(<code>HibernateSearchDemoTestCase</code>)</i>. L&#8217;indexation des données de test est faite de manière transparente au moment du commit de la transaction :</p><pre class="brush: java; title: ; notranslate">
Transaction tx = this.testSession.beginTransaction();
Author bTate = new Author(
		&quot;Bruce&quot;,
		&quot;Tate&quot;,
		&quot;Bruce A. Tate is a [...]&quot;);
[...]
Document beyondJava = new Document();
beyondJava.setTitle(&quot;Beyond Java&quot;);
beyondJava
		.setSummary(&quot;In Beyond Java, [...]&quot;);
beyondJava.setAuthor(bTate);
this.testSession.persist(beyondJava);
[...]
tx.commit();
</pre><h3>Recherches full-text sur les entités</h3><p>La recherche full-text de documents dans l&#8217;index se fait au travers de la méthode <code>searchDocuments</code> de la classe de test <i>(<code>HibernateSearchDemoTestCase</code>)</i> :</p><pre class="brush: java; title: ; notranslate">
private List&lt;Document&gt; searchDocuments(String queryString) {
	FullTextSession searchSession = Search
			.createFullTextSession(this.testSession);
	Transaction tx = searchSession.beginTransaction();
	MultiFieldQueryParser parser = new MultiFieldQueryParser(new String[] {
			&quot;title&quot;, &quot;summary&quot;, &quot;author.lastName&quot;, &quot;author.firstName&quot;,
			&quot;author.resume&quot; }, new SimpleEnglishAnalyzer());
	FullTextQuery query;
	try {
		query = searchSession.createFullTextQuery(
				parser.parse(queryString), Document.class);
	} catch (ParseException pe) {
		logger.error(&quot;Error while parsing query.&quot;, pe);
		return new ArrayList&lt;Document&gt;(0);
	}
	List&lt;Document&gt; result = query.list();
	tx.commit();
	return result;
}
</pre><p>Pour effectuer une recherche full-text, il faut :</p><ul><li>Créer une <code>FullTextSession</code> à partir de la session Hibernate.</li><li>Créer un parseur (<code>MultiFieldQueryParser</code>) en lui indiquant les champs sur lesquels la recherche doit avoir lieu et l&#8217;analyseur à utiliser pour tokeniser les chaînes de recherche <i>(il est bien évidemment préférable d&#8217;utiliser le même que pour l&#8217;indexation des documents)</i>.</li><li>Créer une requête de recherche full-text à partir de la chaîne de recherche tokenisée.</li><li>Exécuter la méthode <code>list</code> sur la requête.</li></ul><p>Hibernate Search retourne alors une liste d’entités &laquo;&nbsp;managées&nbsp;&raquo;.</p><h4>Les cas de test</h4><p>La démonstration peut être lancée via maven avec la commande :</p><pre class="brush: bash; title: ; notranslate">
mvn test
</pre><p>Les cas de test proposés sont :</p><ul><li>Recherches simples (<code>"java"</code>, <code>"father"</code>, <code>"JAVA"</code>):</li></ul><pre class="brush: bash; title: ; notranslate">
=====================================================
Simple Test (query == &quot;java&quot;):
Results list:
Document 1: Beyond Java:
   &gt; Summary: In Beyond Java, Bruce Tate, author of the Jolt Award-winning Better, Faster, Lighter Java, chronicles the rise of the most  ...
   &gt; Author: Bruce Tate (1)
             &gt; Resume: Bruce A. Tate is a kayaker, mountain biker, and father of two. In his spare time, he is an independent consultant in Austin ...
Document 2: From Java to Ruby:
   &gt; Summary: If you're trying to adopt Ruby in your organization and need some help, this is the book for you. Based on a decision tree  ...
   &gt; Author: Bruce Tate (1)
             &gt; Resume: Bruce A. Tate is a kayaker, mountain biker, and father of two. In his spare time, he is an independent consultant in Austin ...
Document 4: AspectJ Cookbook:
   &gt; Summary: This hands-on book shows readers why and how common Java development problems can be solved by using new Aspect-oriented pr ...
   &gt; Author: Russell Miles (3)
             &gt; Resume: Russell Miles is a software engineer for General Dynamics UK where he works with Java and Distributed Systems, although his ...
=====================================================
=====================================================
Simple Test (query == &quot;father&quot;):
Results list:
Document 1: Beyond Java:
   &gt; Summary: In Beyond Java, Bruce Tate, author of the Jolt Award-winning Better, Faster, Lighter Java, chronicles the rise of the most  ...
   &gt; Author: Bruce Tate (1)
             &gt; Resume: Bruce A. Tate is a kayaker, mountain biker, and father of two. In his spare time, he is an independent consultant in Austin ...
Document 2: From Java to Ruby:
   &gt; Summary: If you're trying to adopt Ruby in your organization and need some help, this is the book for you. Based on a decision tree  ...
   &gt; Author: Bruce Tate (1)
             &gt; Resume: Bruce A. Tate is a kayaker, mountain biker, and father of two. In his spare time, he is an independent consultant in Austin ...
=====================================================
=====================================================
Simple Case Test (query == &quot;JAVA&quot;):
Results list:
Document 1: Beyond Java:
   &gt; Summary: In Beyond Java, Bruce Tate, author of the Jolt Award-winning Better, Faster, Lighter Java, chronicles the rise of the most  ...
   &gt; Author: Bruce Tate (1)
             &gt; Resume: Bruce A. Tate is a kayaker, mountain biker, and father of two. In his spare time, he is an independent consultant in Austin ...
Document 2: From Java to Ruby:
   &gt; Summary: If you're trying to adopt Ruby in your organization and need some help, this is the book for you. Based on a decision tree  ...
   &gt; Author: Bruce Tate (1)
             &gt; Resume: Bruce A. Tate is a kayaker, mountain biker, and father of two. In his spare time, he is an independent consultant in Austin ...
Document 4: AspectJ Cookbook:
   &gt; Summary: This hands-on book shows readers why and how common Java development problems can be solved by using new Aspect-oriented pr ...
   &gt; Author: Russell Miles (3)
             &gt; Resume: Russell Miles is a software engineer for General Dynamics UK where he works with Java and Distributed Systems, although his ...
=====================================================
</pre><ul><li>Recherche par approximation (<code>"jav~"</code>):</li></ul><pre class="brush: bash; title: ; notranslate">
=====================================================
Approximation Test (query == &quot;jav~&quot;):
Results list:
Document 1: Beyond Java:
   &gt; Summary: In Beyond Java, Bruce Tate, author of the Jolt Award-winning Better, Faster, Lighter Java, chronicles the rise of the most  ...
   &gt; Author: Bruce Tate (1)
             &gt; Resume: Bruce A. Tate is a kayaker, mountain biker, and father of two. In his spare time, he is an independent consultant in Austin ...
Document 2: From Java to Ruby:
   &gt; Summary: If you're trying to adopt Ruby in your organization and need some help, this is the book for you. Based on a decision tree  ...
   &gt; Author: Bruce Tate (1)
             &gt; Resume: Bruce A. Tate is a kayaker, mountain biker, and father of two. In his spare time, he is an independent consultant in Austin ...
Document 4: AspectJ Cookbook:
   &gt; Summary: This hands-on book shows readers why and how common Java development problems can be solved by using new Aspect-oriented pr ...
   &gt; Author: Russell Miles (3)
             &gt; Resume: Russell Miles is a software engineer for General Dynamics UK where he works with Java and Distributed Systems, although his ...
=====================================================
</pre><ul><li>Recherche par proximité (<code>""engineer UK"~5"</code>):</li></ul><pre class="brush: bash; title: ; notranslate">
=====================================================
Proximity Test (query == &quot;&quot;engineer UK&quot;~5&quot;):
Results list:
Document 4: AspectJ Cookbook:
   &gt; Summary: This hands-on book shows readers why and how common Java development problems can be solved by using new Aspect-oriented pr ...
   &gt; Author: Russell Miles (3)
             &gt; Resume: Russell Miles is a software engineer for General Dynamics UK where he works with Java and Distributed Systems, although his ...
=====================================================
</pre>]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2008/03/28/hands-on-hibernate-search-recherche-full-text/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Introduction à Hibernate Search (Googling your Persistent Domain Model)</title><link>http://blog.xebia.fr/2008/03/06/introduction-a-hibernate-search-googling-your-persistent-domain-model/</link> <comments>http://blog.xebia.fr/2008/03/06/introduction-a-hibernate-search-googling-your-persistent-domain-model/#comments</comments> <pubDate>Thu, 06 Mar 2008 07:00:42 +0000</pubDate> <dc:creator>Christophe Heubès</dc:creator> <category><![CDATA[Java / JEE]]></category> <category><![CDATA[développement]]></category> <category><![CDATA[Hibernate]]></category> <guid
isPermaLink="false">http://blog.xebia.fr/2008/03/06/introduction-a-hibernate-search-googling-your-persistent-domain-model/</guid> <description><![CDATA[J&#8217;ai eu l&#8217;occasion courant décembre de rencontrer Emmanuel Bernard [1] pour, entre autres, une présentation d&#8217;Hibernate Search. La vulgarisation et la généralisation de l&#8217;utilisation des moteurs de recherche ont définitivement changé les habitudes et les exigences des utilisateurs. Pourquoi la fonctionnalité de recherche d&#8217;une application de gestion ne serait-elle pas aussi simple et performante que [...]]]></description> <content:encoded><![CDATA[<p>J&#8217;ai eu l&#8217;occasion courant décembre de rencontrer <a
href="http://blog.emmanuelbernard.com/">Emmanuel Bernard</a> [1] pour, entre autres, une présentation d&#8217;Hibernate Search.</p><p>La vulgarisation et la généralisation de l&#8217;utilisation des moteurs de recherche ont définitivement changé les habitudes et les exigences des utilisateurs. Pourquoi la fonctionnalité de recherche d&#8217;une application de gestion ne serait-elle pas aussi simple et performante que Google ?<br
/> Difficile d&#8217;expliquer à son responsable que cela est dû à une divergence de paradigme entre l&#8217;indexation documentaire et SQL.<br
/> <a
href="http://search.hibernate.org/">Hibernate Search</a> vise à répondre à cette question, à moindre coût, en s&#8217;appuyant sur <a
href="http://lucene.apache.org">Apache Lucene</a> afin d&#8217;offrir au travers du modèle de persistance d&#8217;Hibernate des capacités de recherche full-text.</p><h3>Réconcilier la recherche full-text et les modèles de persistance relationnels</h3><p>Par nature, SQL nous limite à l&#8217;écriture de requête de recherche par mot <em>(par terme)</em> avec l&#8217;aide éventuelle de wildcard (&#8216;%&#8217;, &#8216;?&#8217;).<br
/> La recherche SQL sur un modèle relationnel n&#8217;offre pas <em>(ou en tout cas pas sans de très gros efforts)</em> un ensemble de capacités dignes d&#8217;un moteur de recherche moderne :</p><ul><li>L&#8217;<strong>approximation</strong> qui permet de s&#8217;affranchir des fautes de frappe (Ex : &laquo;&nbsp;xebi&nbsp;&raquo; -&gt; &laquo;&nbsp;xebia&nbsp;&raquo;).</li><li>La <strong>recherche par synonyme</strong> qui permet de remonter des résultats pertinents mais ne contenant pas le terme recherché (En SQL, &laquo;&nbsp;JEE&nbsp;&raquo; est différent de &laquo;&nbsp;J2EE&nbsp;&raquo;).</li><li>La <strong><a
href="http://en.wikipedia.org/wiki/Proximity_search_%28text%29">recherche par proximité</a></strong> (Ex : &laquo;&nbsp;persistance java&nbsp;&raquo; -&gt; &laquo;&nbsp;Hibernate&nbsp;&raquo;).</li><li>Le <strong>classement des résultats</strong> par pertinence <em>(result scoring)</em>.</li><li>La recherche <strong>multi-colonnes</strong>.</li></ul><p>Ces fonctionnalités sont traditionnellement offertes par les solutions de recherche full-text qui s&#8217;appuient sur l&#8217;utilisation <a
href="http://en.wikipedia.org/wiki/Inverted_index">d&#8217;index inversés</a>. Malheureusement, de telles solutions se marient souvent mal avec les systèmes de bases de données relationnelles en raison de décalages entre les deux paradigmes :</p><ul><li>Un <strong>déséquilibre structurel</strong> tout d&#8217;abord : Les index full-text ne sont que du texte. Ils ne reflètent pas une quelconque structuration des données. De plus, ils ne permettent pas de gérer des relations entre les documents.</li><li>De plus, le mariage des deux systèmes pose des problèmes de <strong>synchronisation</strong> : comment s&#8217;assurer que le contenu de la base de données et l&#8217;index documentaire sont à jour et cohérents l&#8217;un vis-à-vis de l&#8217;autre ?</li><li>Enfin, les <strong>résultats</strong> de recherches full-text sont des documents. En effet, les index ne stockent pas d&#8217;objets. Encore moins des objets <em>&laquo;&nbsp;managés&nbsp;&raquo;</em>.</li></ul><p>A cela s&#8217;ajoute des problèmes de portabilité et de flexibilité dus au fait que la plupart des implémentations ne sont que des surcouches propriétaires au dessus du SQL.</p><p>L&#8217;objet d&#8217;Hibernate Search est de résoudre ces décalages et de réconcilier la recherche full-text et les modèles de persistance relationnels. Pour ce faire, Hibernate Search se base sur <a
href="http://lucene.apache.org">Apache Lucene</a>, un moteur d&#8217;indexation et de recherche full-text standalone très puissant, mais plutôt bas niveau <em>(et donc facile à mal utiliser)</em>.<br
/> Hibernate Search permet ainsi d&#8217;utiliser les capacités d&#8217;Apache Lucene dans le cadre d&#8217;une couche de mapping Hibernate.</p><h3>Architecture</h3><p>Hibernate Search est donc un moteur d&#8217;indexation et de recherche full-text reposant sur Apache Lucene. Il prend ainsi en charge la gestion d&#8217;un index Lucene et sa synchronisation avec une structure objet persistée en base de données.</p><p>La mise à jour de l&#8217;index est déclenchée au travers de la capture d&#8217;événements JPA : quand une entité est insérée, mise à jour ou supprimée en base de données, Hibernate Search récupère l&#8217;événement et programme une mise à jour de l&#8217;index. Cette mise à jour est effectuée de façon transparente par Hibernate Search et ne nécessite pas l&#8217;utilisation directe des API Lucene.<br
/> Par souci d&#8217;efficacité, les opérations d&#8217;écritures dans l&#8217;index Lucene sont traitées par lots. Le traitement de ces lots s&#8217;inscrit dans la transaction courante. De cette façon, la mise à jour de l&#8217;index n&#8217;est déclenchée que si celle-ci est &laquo;&nbsp;commitée&nbsp;&raquo;, permettant ainsi de garantir l&#8217;<a
href="http://fr.wikipedia.org/wiki/Propri%C3%A9t%C3%A9s_ACID">ACID</a>-ité du système.</p><p>La recherche dans l&#8217;index se fait au travers des APIs <tt>}}<a
href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Query.html">org.hibernate.Query</a> ou <a
href="http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html">javax.persistence.Query</a>{{</tt> de la même façon que l&#8217;on écrirait des requêtes natives, HQL ou JPA-QL. Une requête de recherche Hibernate Search retourne une liste d&#8217;entités &laquo;&nbsp;managées&nbsp;&raquo; sans que le développeur ait à se soucier du fastidieux travail de mapping Objet &lt;-&gt; Document Lucene.</p><p>Le traitement des opérations de mise à jour de l&#8217;index peut être traité par différents backend en fonction de l&#8217;architecture et des scénarii mis en place. Hibernate Search propose deux &laquo;&nbsp;backend sur étagère&nbsp;&raquo; : Un backend Lucene <em>(synchrone)</em> et un backend JMS <em>(asynchrone)</em>.</p><h4>Backend synchrone</h4><p>Ce mode est le plus simple : toutes les opérations de mise à jour de l&#8217;index sont traitées par le nœud (la JVM) à l&#8217;origine de l&#8217;événement déclencheur. Le traitement des mises à jour est effectué de façon synchrone <em>(au commit de la transaction)</em>.<br
/> Ce backend adresse des environnements standalones <em>(non clusterisés)</em> ou en clusters symétriques <em>(tous les nœuds partagent la même instance d&#8217;index Lucene)</em>. C&#8217;est alors Lucene qui est en charge de la gestion de la stratégie de locking.</p><div
align="center"><img
src="http://blog.xebia.fr/wp-content/uploads/2008/03/hibernatesearchbackend.png" alt="Hibernate Search Back End" /></div><p>Les avantages de ce mode sont sa simplicité de mise en œuvre et la visibilité immédiate des mises à jour de l&#8217;index puisqu&#8217;elles sont traitées en synchrone.<br
/> Par contre, cette approche synchrone peut dégrader les performances de l&#8217;application front.</p><h4>Backend asynchrone</h4><p>Ce backend met en jeu le pattern maître / esclaves : Les opérations de mise à jour de l&#8217;index sont effectuées sur un index maître tandis que les opérations de lecture <em>(recherche)</em> sont effectuées sur des index esclaves. A intervalles réguliers, l&#8217;index maître est répliqué sur les esclaves <em>(copies du maître)</em>.</p><p>Ce backend adresse des environnements clusterisés répondant à des besoins de haute performance de l&#8217;application front. Dans ce mode, chaque nœud utilise un index esclave en local. Ces indexes sont exclusivement utilisés en lecture. Lorsqu&#8217;un événement nécessite une opération de mise à jour de l&#8217;index, l&#8217;ordre de mise à jour est envoyé sur une queue JMS <em>(tous les nœuds utilisant la même queue)</em>. Cette queue est dépilée par un consommateur unique en charge du traitement <em>(asynchrone)</em> des opérations de mise à jour qu&#8217;il effectue sur l&#8217;index maître.</p><div
align="center"><img
src="http://blog.xebia.fr/wp-content/uploads/2008/03/hibernatesearchbackendasync.png" alt="Hibernate Search Asynchronous Back End" /></div><p>Le principal avantage de ce mode est de ne pas surcharger l&#8217;application front avec les traitements de mise à jour de l&#8217;index.<br
/> Il entraîne par contre un délai de mise à jour des index de recherche <em>(Traitement asynchrone des mises à jour + délai de réplication)</em>.</p><h3>Pour bien commencer</h3><ul><li>Le site du projet <a
href="http://search.hibernate.org">Hibernate Search</a>.</li><li>La <a
href="http://www.hibernate.org/hib_docs/search/reference/en/html_single/">documentation Hibernate Search</a>.</li><li>La documentation de la <a
href="http://lucene.apache.org/java/2_3_1/queryparsersyntax.html">syntaxe de requêtes</a>.</li></ul><p>Et rendez-vous fin mars sur notre blog pour <a
href="http://blog.xebia.fr/2008/03/28/hands-on-hibernate-search-recherche-full-text/">un premier sample</a>.</p><hr
/> [1] <a
href="http://blog.emmanuelbernard.com/">Emmanuel Bernard</a> est membre de l&#8217;équipe Hibernate, Core developer à JBoss, lead developer sur les projets Hibernate Annotations, Hibernate EntityManager et Hibernate Search ainsi que membre des groupes d&#8217;expert EJB 3.0 et JSR-303.</p> ]]></content:encoded> <wfw:commentRss>http://blog.xebia.fr/2008/03/06/introduction-a-hibernate-search-googling-your-persistent-domain-model/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> </channel> </rss>
