<?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/"
	>

<channel>
	<title>Everything is wrong &#187; Conteneurs embarqués</title>
	<atom:link href="http://everythingiswrong.free.fr/index.php/category/java-j2ee/conteneurs-embarques/feed/" rel="self" type="application/rss+xml" />
	<link>http://everythingiswrong.free.fr</link>
	<description>Un blog dédié à l&#039;informatique en général</description>
	<lastBuildDate>Wed, 06 Oct 2021 21:20:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Maven et SeamTest</title>
		<link>http://everythingiswrong.free.fr/index.php/2011/03/22/maven-et-seamtest/</link>
		<comments>http://everythingiswrong.free.fr/index.php/2011/03/22/maven-et-seamtest/#comments</comments>
		<pubDate>Tue, 22 Mar 2011 22:10:46 +0000</pubDate>
		<dc:creator>Yan</dc:creator>
				<category><![CDATA[Conteneurs embarqués]]></category>
		<category><![CDATA[Java J2EE]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Tests unitaires]]></category>
		<category><![CDATA[JBoss]]></category>
		<category><![CDATA[Seam]]></category>
		<category><![CDATA[Tests]]></category>

		<guid isPermaLink="false">http://yan.langlois.free.fr/wordpress/?p=1098</guid>
		<description><![CDATA[Comment intégrer des tests d'intégration avec SeamTest ou DBUnitSeamTest dans un projet Maven.]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">L&#8217;intégration des tests unitaires SeamTest dans un projet <a href="http://maven.apache.org/" target="_blank">Maven</a> est assez compliquée. Voici un exemple concret :</p>
<h1 style="text-align: justify;">Présentation du projet</h1>
<p style="text-align: justify;">Avant de rentrer dans des détails techniques, je préfère vous parler de l&#8217;application qui va me servir de base pour intégrer mon test SeamTest.</p>
<h2>Vision fonctionnelle</h2>
<p style="text-align: justify;">J&#8217;ai choisi de me baser sur l&#8217;exemple &#8220;hello world&#8221; du livre <em>Seam Framework:  Experience the Evolution of Java EE 2nd edition</em>. Vous pouvez retrouver les sources des exemples du livre à l&#8217;adresse suivante : <a href="http://solutionsfit.com/blog/books/" target="_blank">http://solutionsfit.com/blog/books/</a>. Malheureusement, l&#8217;auteur utilise <a href="http://ant.apache.org/" target="_blank">Ant</a> et non Maven pour gérer la compilation de ses projets.</p>
<p style="text-align: justify;">J&#8217;ai rajouté l&#8217;utilisation d&#8217;un service EJB Stateless pour démontrer la possibilité d&#8217;utiliser SeamTest dans un contexte technique hétérogène. Voici le diagramme des cas d&#8217;utilisation de l&#8217;application :</p>
<p style="text-align: center;"><img class="aligncenter" title="Cas d'utilisation de l'application" src="http://yuml.me/diagram/scruffy/usecase/[Utilisateur]-(Enregistrer une personne), [Utilisateur]-(Visualiser les personnes enregistrées)" alt="Cas d'utilisation de l'application" /></p>
<h2>Vision maven</h2>
<p>Le projet est composé d&#8217;un module père ayant trois modules fils :</p>
<p class="wp-caption" style="text-align: justify;">seamtest-parent<br />
|&#8211; seamtest-ear<br />
|&#8211; seamtest-ejb<br />
`&#8211; seamtest-webapp</p>
<p style="text-align: justify;">Vous pouvez checkouter les sources à l&#8217;adresse suivante : <a href="https://subversion.assembla.com/svn/everythingiswrong/seamtest-parent/" target="_blank">https://subversion.assembla.com/svn/everythingiswrong/seamtest-parent/</a>.</p>
<p style="text-align: justify;">Dans le reste de l&#8217;article, je vais me focaliser sur le module seamtest-ejb car c&#8217;est lui qui contient le composant Seam, la persistance et l&#8217;EJB Stateless à tester.</p>
<h2 style="text-align: justify;">Composant Seam à tester</h2>
<p>Nous allons tester le composant qui va :</p>
<ul>
<li>Enregistrer une nouvelle personne dans la base de données</li>
<li>Rechercher toutes les personnes de la base de données</li>
</ul>
<pre class="brush: java; toolbar: true;">@Stateful
@Name("manager")
public class ManagerAction extends Manager {
  @In
  private Person person;

  @Out
  private List&lt;Person&gt; fans;

  @EJB
  private CalculService calculService;

  @PersistenceContext
  private EntityManager em;

  //Méthode à tester.
  public void sayHello () {
    em.persist (person);
    fans = em.createQuery("select p from Person p").getResultList();
  }

  // Méthode pour vérifier l'injection de l'EJB Stateless dans le composant Seam
  public int additionner(int a, int b) {
    return (int) calculService.addition(a, b);
  }

  @Remove
  @Destroy
  public void destroy() {
  }
}</pre>
<h1 style="text-align: justify;">Installation et configuration</h1>
<p style="text-align: justify;">Pour information, SeamTest utilise le serveur <a href="http://community.jboss.org/wiki/EmbeddedJBoss" target="_blank">JBoss embedded</a>.</p>
<h2 style="text-align: justify;">Installation de JBoss Embedded</h2>
<p style="text-align: justify;">Cette installation se résume à la copie du répertoire booststrap qui est dans la distribution de Seam (par exemple <a href="http://anonsvn.jboss.org/repos/seam/branches/community/Seam_2_2/bootstrap/" target="_blank">ici</a>) dans le répertoire src/test.</p>
<h2 style="text-align: justify;">Le fichier &#8220;pom.xml&#8221;</h2>
<p style="text-align: justify;">Ce fichier doit contenir l&#8217;ensemble des librairies qui vont permettre de démarrer et d&#8217;exécuter le serveur JBoss embedded. Il doit aussi prendre en compte le répertoire de <em>bootstrap</em> ajouté précédemment dans les ressources des tests.</p>
<pre class="brush: xml; toolbar: true;">&lt;dependencies&gt;
  ...
  &lt;!-- dépendances des tests unitaites : http://community.jboss.org/thread/18299 --&gt;
  &lt;!-- dependencies related to JBoss Embedded for Seam 2.X.X --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.jboss.seam.embedded&lt;/groupId&gt;
    &lt;artifactId&gt;jboss-embedded-all&lt;/artifactId&gt;
    &lt;version&gt;beta3.SP12&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
    &lt;exclusions&gt;
      &lt;exclusion&gt;
        &lt;groupId&gt;org.jboss.microcontainer&lt;/groupId&gt;
        &lt;artifactId&gt;jboss-deployers-client-spi&lt;/artifactId&gt;
      &lt;/exclusion&gt;
      &lt;exclusion&gt;
        &lt;groupId&gt;org.jboss.microcontainer&lt;/groupId&gt;
        &lt;artifactId&gt;jboss-deployers-core-spi&lt;/artifactId&gt;
      &lt;/exclusion&gt;
    &lt;/exclusions&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.jboss.seam.embedded&lt;/groupId&gt;
    &lt;artifactId&gt;hibernate-all&lt;/artifactId&gt;
    &lt;version&gt;beta3.SP12&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.jboss.seam.embedded&lt;/groupId&gt;
    &lt;artifactId&gt;thirdparty-all&lt;/artifactId&gt;
    &lt;version&gt;beta3.SP12&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;

  &lt;!-- dependencies related to JBoss MicroContainer --&gt;
  &lt;!-- java.lang.NoClassDefFoundError: javax/faces/application/Application --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;javax.faces&lt;/groupId&gt;
    &lt;artifactId&gt;jsf-api&lt;/artifactId&gt;
    &lt;version&gt;1.2_09&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;

  &lt;!-- java.lang.NoClassDefFoundError: org/jboss/el/ExpressionFactoryImpl --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.jboss.el&lt;/groupId&gt;
    &lt;artifactId&gt;jboss-el&lt;/artifactId&gt;
    &lt;version&gt;1.0_02.CR4&lt;/version&gt;    &lt;!-- http://seamframework.org/Community/IllegalAccessErrorAfterUpgradingTo212CR1 --&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;

  &lt;!-- dependencies related to TestNG --&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.testng&lt;/groupId&gt;
    &lt;artifactId&gt;testng&lt;/artifactId&gt;
    &lt;version&gt;5.8&lt;/version&gt;
    &lt;classifier&gt;jdk15&lt;/classifier&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;build&gt;
  &lt;testResources&gt;
    &lt;testResource&gt;
      &lt;directory&gt;src/test/resources&lt;/directory&gt;
      &lt;filtering&gt;true&lt;/filtering&gt;
    &lt;/testResource&gt;
    &lt;testResource&gt;
      &lt;directory&gt;src/test/bootstrap&lt;/directory&gt;
      &lt;filtering&gt;false&lt;/filtering&gt;
    &lt;/testResource&gt;
    &lt;testResource&gt;
      &lt;directory&gt;src/test/bootstrap&lt;/directory&gt;
      &lt;filtering&gt;true&lt;/filtering&gt;
      &lt;includes&gt;
        &lt;include&gt;**/*.xml&lt;/include&gt;
      &lt;/includes&gt;
    &lt;/testResource&gt;
  &lt;/testResources&gt;
  ...
&lt;/build&gt;</pre>
<p style="text-align: justify;"><span style="text-decoration: underline;">Remarque</span> : à l&#8217;heure actuelle la version la plus récente du conteneur est la beta3.SP12.</p>
<h2 style="text-align: justify;">Fichiers de tests</h2>
<p style="text-align: justify;">Dans la pratique, on ajoute toujours un fichier seam.properties vide dans le classpath des jar contenant des composants Seam. Dans le cas du test, ce fichier doit contenenir au minimum l&#8217;information sur le nom JNDI des EJB :</p>
<p class="wp-caption" style="text-align: justify;">org.jboss.seam.core.init.jndiPattern = #{ejbName}/local</p>
<p style="text-align: justify;">La classe de test doit étendre SeamTest. Elle peut ensuite utiliser l&#8217;EL pour référencer les composants Seam :</p>
<pre class="brush: java; toolbar: true;">public class ManagerActionTest extends SeamTest {
  private static Logger LOGGER = Logger.getLogger(ManagerActionTest.class);

  @Test
  public void testSayHello() {
    try {
      new ComponentTest() {
        @Override
        protected void testComponents() throws Exception {
          setValue("#{person.name}", "Yan");
          invokeMethod("#{manager.sayHello}");
          List&lt;Person&gt; fans = (List&lt;Person&gt;) getValue("#{fans}");
          assertNotNull(fans);
          assertEquals(1, fans.size());
          assertEquals("Yan", fans.get(0).getName());
          // Test le service EJB
          assertEquals(3, invokeMethod("#{manager.additionner(1, 2)}"));
        }
      }.run();
    } catch (Exception e) {
      LOGGER.error("TEST KO : " + e.getMessage());
      fail("TEST KO : " + e.getMessage());
    }
  }
}</pre>
<p style="text-align: justify;">En utilisant Hibernate, vous pouvez exécuter des scripts SQL au déploiement de votre test en ajoutant un fichier <em>import.sql</em> dans le classpath de test (src/test/resources). Cela dit,  dans ce cas, je conseillerai plutôt d&#8217;utiliser l&#8217;intégration avec DBUnit.</p>
<h2 style="text-align: justify;">Exécution</h2>
<p style="text-align: justify;">Pour exécuter les tests il faut lancer la commande <em>mvn clean test</em>.</p>
<h1 style="text-align: justify;">Variantes</h1>
<h2 style="text-align: justify;">Intégration avec DBUnit</h2>
<p style="text-align: justify;">L&#8217;intégration est possible entre seamTest et DBUnit. La classe de test doit étendre <em>DBunitSeamTest</em> et implémenter la méthode <em>prepareDBUnitOperations()</em>. Il faut aussi donner à TestNg la nom JNDI de la source de données vers la base de données ainsi que le type de la base de données (HSQL ou MYSQL). Pour cela, il faut configurer le plugin surefire comme cela :</p>
<pre class="brush: xml; toolbar: true;">&lt;build&gt;
  ...
  &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.4.3&lt;/version&gt;
    &lt;configuration&gt;
      &lt;systemProperties&gt;
        &lt;property&gt;
          &lt;name&gt;datasourceJndiName&lt;/name&gt;
          &lt;value&gt;java:/DefaultDS&lt;/value&gt;
        &lt;/property&gt;
        &lt;property&gt;
          &lt;name&gt;database&lt;/name&gt;
          &lt;value&gt;HSQL&lt;/value&gt;
        &lt;/property&gt;
      &lt;/systemProperties&gt;
      &lt;argLine&gt;-Dsun.lang.ClassLoader.allowArraySyntax=true&lt;/argLine&gt;
    &lt;/configuration&gt;
 ...
&lt;/build&gt;</pre>
<p style="text-align: justify;"><span style="text-decoration: underline;">Remarque</span> : deux propriétés pour déclarer le type de la source de données et son nom JNDI ainsi qu&#8217;un argument pour permettre au serveur JBoss Embedded de s&#8217;éxécuter avec une JDK 1.6 (par défaut ce serveur n&#8217;est compatible qu&#8217;avec une JDK1.5).</p>
<p style="text-align: justify;">Pour information, DBUnit propose deux implémentations différentes pour décrire les données d&#8217;une base : le <a href="http://dbunit.sourceforge.net/apidocs/org/dbunit/dataset/xml/FlatXmlDataSet.html">FlatXmlDataSet</a> et le <a href="http://dbunit.sourceforge.net/apidocs/org/dbunit/dataset/xml/XmlDataSet.html">XmlDataSet</a> (<a href="http://dbunit.sourceforge.net/components.html" target="_blank">http://dbunit.sourceforge.net/components.html</a>).  SeamTest ne support que le FlatXmlDataSet.</p>
<h2 style="text-align: justify;">Dépendances sur des projets ou modules de type EJB</h2>
<p style="text-align: justify;">Dans le cas où votre module dépende d&#8217;un autre module EJB, il faut arriver à déployer la dépendance de type EJB dans le conteneur JBoss embedded. Il est possible de faire cette opération avec le plugin maven <a href="http://maven.apache.org/plugins/maven-dependency-plugin/" target="_blank">maven-dependency-plugin</a> comme cela :</p>
<pre class="brush: xml; toolbar: true;">&lt;build&gt;
  ...
  &lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-dependency-plugin&lt;/artifactId&gt;
    &lt;executions&gt;
      &lt;execution&gt;
        &lt;id&gt;copy&lt;/id&gt;
        &lt;phase&gt;process-test-resources&lt;/phase&gt;
        &lt;goals&gt;
          &lt;goal&gt;copy&lt;/goal&gt;
        &lt;/goals&gt;
        &lt;configuration&gt;
          &lt;artifactItems&gt;
            &lt;artifactItem&gt;
              &lt;groupId&gt;...&lt;/groupId&gt;
              &lt;artifactId&gt;...&lt;/artifactId&gt;
              &lt;version&gt;...&lt;/version&gt;
              &lt;type&gt;...&lt;/type&gt;
              &lt;classifier&gt;...&lt;/classifier&gt;
              &lt;overWrite&gt;false&lt;/overWrite&gt;
              &lt;outputDirectory&gt;${project.build.directory}/test-classes/deploy&lt;/outputDirectory&gt;
            &lt;/artifactItem&gt;
          &lt;/artifactItems&gt;
        &lt;/configuration&gt;
      &lt;/execution&gt;
    &lt;/executions&gt;
  &lt;/plugin&gt;
  ...
&lt;/build&gt;</pre>
<p><span style="text-decoration: underline;">Remarque</span> : la copie de la dépendance se déroule avant la phase d&#8217;exécution des tests.</p>
]]></content:encoded>
			<wfw:commentRss>http://everythingiswrong.free.fr/index.php/2011/03/22/maven-et-seamtest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EJB3 : intercepteurs</title>
		<link>http://everythingiswrong.free.fr/index.php/2011/01/21/ejb3-intercepteurs/</link>
		<comments>http://everythingiswrong.free.fr/index.php/2011/01/21/ejb3-intercepteurs/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 21:47:17 +0000</pubDate>
		<dc:creator>Yan</dc:creator>
				<category><![CDATA[Conteneurs embarqués]]></category>
		<category><![CDATA[Java J2EE]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[EJB]]></category>
		<category><![CDATA[J2EE]]></category>
		<category><![CDATA[openEJB]]></category>

		<guid isPermaLink="false">http://yan.langlois.free.fr/wordpress/?p=793</guid>
		<description><![CDATA[Intercepteur EJB3]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Les intercepteurs sont des petits programmes qui interviennent avant et après l&#8217;exécution d&#8217;une méthode. ils permettent de faire de la programmation orientée AOP sur les méthodes publics des EJB. Il est possible de s&#8217;en servir pour logger les entrées et sorties d&#8217;une méthode comme je le propose dans mon <a href="https://subversion.assembla.com/svn/everythingiswrong/tutorial-interceptor-openejb" target="_blank">exemple</a> qui se base sur un simple &#8220;HelloWorld&#8221; en EJB3. J&#8217;utilise openEJB pour simplifier l&#8217;exécution et vous permettre d&#8217;utiliser l&#8217;exemple tel quel.</p>
<p style="text-align: justify;"><span style="text-decoration: underline;">Création de l&#8217;intercepteur</span> : c&#8217;est un EJB standard avec une méthode public annotée avec <em>@AroundInvoke</em>.</p>
<pre class="brush:java;toolbar: true;">public @Stateless class LoggerServiceBean implements LoggerService {
    @AroundInvoke
    public Object c(InvocationContext ctx) throws Exception {
        // Affiche le nom de la méthode
        System.out.println(ctx.getMethod().toGenericString());
        // Liste les paramètres passés à la méthode
        for (int i = 0; i &lt; ctx.getParameters().length; i++) {
            if (i != 0) {
                System.out.print(",");
            }
            System.out.print("parameter " + i +" : " + ctx.getParameters()[i]);
        }
        System.out.println();
        return ctx.proceed(); //Exécute de la méthode
    }
}</pre>
<p style="text-align: justify;">Comme vous pouvez le voir, c&#8217;est l&#8217;objet InvocationContext qui va vous permettre de visualiser la méthode et les paramètres utilisés.</p>
<p style="text-align: justify;"><span style="text-decoration: underline;">Déclaration de l&#8217;EJB en tant qu&#8217;intercepteur</span> : ajouter ces quelques lignes dans le fichier META-INF/ejb-jar.xml :</p>
<pre class="brush:xml;toolbar: true;">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
    version="3.0"&gt;

  &lt;interceptors&gt;
    &lt;interceptor&gt;
      &lt;interceptor-class&gt;org.everythingiswrong.tutorial.interceptor_openejb.interceptor.LoggerServiceBean&lt;/interceptor-class&gt;
    &lt;/interceptor&gt;
  &lt;/interceptors&gt;

  &lt;assembly-descriptor&gt;
    &lt;interceptor-binding&gt;
      &lt;ejb-name&gt;*&lt;/ejb-name&gt;
      &lt;interceptor-class&gt;org.everythingiswrong.tutorial.interceptor_openejb.interceptor.LoggerServiceBean&lt;/interceptor-class&gt;
    &lt;/interceptor-binding&gt;
  &lt;/assembly-descriptor&gt;

&lt;/ejb-jar&gt;</pre>
<p>Voici l&#8217;adresse SVN du projet : <a href="https://subversion.assembla.com/svn/everythingiswrong/tutorial-interceptor-openejb" target="_blank">https://subversion.assembla.com/svn/everythingiswrong/tutorial-interceptor-openejb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://everythingiswrong.free.fr/index.php/2011/01/21/ejb3-intercepteurs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Utiliser l&#8217;annuaire JNDI d&#8217;un JBoss embedded</title>
		<link>http://everythingiswrong.free.fr/index.php/2010/12/12/utiliser-lannuaire-jndi-dun-jboss-embedded/</link>
		<comments>http://everythingiswrong.free.fr/index.php/2010/12/12/utiliser-lannuaire-jndi-dun-jboss-embedded/#comments</comments>
		<pubDate>Sun, 12 Dec 2010 12:54:17 +0000</pubDate>
		<dc:creator>Yan</dc:creator>
				<category><![CDATA[Conteneurs embarqués]]></category>
		<category><![CDATA[Java J2EE]]></category>
		<category><![CDATA[J2EE]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JBoss]]></category>
		<category><![CDATA[jndi]]></category>

		<guid isPermaLink="false">http://yan.langlois.free.fr/wordpress/?p=665</guid>
		<description><![CDATA[Ajouter une chaine de caractère dans le JNDI de JBoss embedded.]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Il est toujours difficile de paramétrer les conteneurs embarqués. Encore plus lorsque ces derniers ne sont plus très récents et donc pas très bien documentés. C&#8217;est pourquoi je vous propose cet article  qui va vous apprendre à enregistrer une chaine de caractère (java.lang.String) dans l&#8217;annulaire JNDI de JBoss embedded. Pour cela, il faut ajouter ce code XML dans le fichier embedded-jboss-beans.xml de votre classpath :</p>
<pre class="brush: xml; title: ; notranslate">
&lt;bean name=&quot;&quot; class=&quot;org.jboss.ejb3.embedded.JndiBinder&quot;&gt;
    &lt;property name=&quot;target&quot;&gt;La valeur de la variable&lt;/property&gt;
    &lt;property name=&quot;bindTo&quot;&gt;variableName&lt;/property&gt;
    &lt;property name=&quot;serializable&quot;&gt;true&lt;/property&gt;
&lt;/bean&gt;
</pre>
<p style="text-align: justify;">Voici un exemple concret : <a href="https://subversion.assembla.com/svn/everythingiswrong/embedded-jboss-jndi-exemple" target="_blank">https://subversion.assembla.com/svn/everythingiswrong/embedded-jboss-jndi-exemple</a>.</p>
<p style="text-align: justify;">Pour plus d&#8217;information sur le conteneur embarqué  de JBoss que j&#8217;utilise dans l&#8217;exemple : <a href="http://docs.jboss.org/ejb3/embedded/embedded.html" target="_blank">http://docs.jboss.org/ejb3/embedded/embedded.html</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://everythingiswrong.free.fr/index.php/2010/12/12/utiliser-lannuaire-jndi-dun-jboss-embedded/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Traitements longs et batchs sur un serveur d&#8217;application Java</title>
		<link>http://everythingiswrong.free.fr/index.php/2010/10/09/traitements-longs-et-batchs-sur-un-serveur-dapplication-java/</link>
		<comments>http://everythingiswrong.free.fr/index.php/2010/10/09/traitements-longs-et-batchs-sur-un-serveur-dapplication-java/#comments</comments>
		<pubDate>Sat, 09 Oct 2010 20:25:12 +0000</pubDate>
		<dc:creator>Yan</dc:creator>
				<category><![CDATA[Conteneurs embarqués]]></category>
		<category><![CDATA[Java J2EE]]></category>
		<category><![CDATA[Batchs]]></category>
		<category><![CDATA[J2EE]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://yan.langlois.free.fr/wordpress/?p=424</guid>
		<description><![CDATA[Faut-il utiliser un serveur d'application Java pour ses batchs et les traitements longs ?]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">La question posée dans ce article est de savoir s&#8217;il est opportun d&#8217;utiliser JavaJ2EE et donc un serveur d&#8217;application pour des traitements longs. Je pense notamment à des traitements batch ou à des traitements lourds provoqués par une demande d&#8217;un utilisateur sur une page web. Pour répondre à cette question il faut comprendre le fonctionnement d&#8217;un serveur d&#8217;application.</p>
<h1>Principe de fonctionnement</h1>
<p style="text-align: justify;">Lorsqu&#8217;un serveur d&#8217;application reçoit à une demande cliente (HTTP, RMI, etc.), il utilise une thread pour y répondre puis la libère à la fin du traitement. Vous pouvez vérifier ce comportement avec une requête HTTP ou bien un MBean. Pour visualiser les threads dans les log il faut paramétrer le <a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html" target="_blank">PatternLayout</a> Log4J avec <em>%t</em>. Lorsque toutes les threads sont occupées, le serveur ne peut plus répondre aux demandes clientes.</p>
<p style="text-align: justify;">Pour information, sur un serveur d&#8217;application, le nombre de thread est limité mais configurable. Par exemple, le nombre maximum de threads sur JBoss est de 100 par défaut.</p>
<h1>Traitements longs</h1>
<p style="text-align: justify;">Dans un serveur d&#8217;application, certaines ressources ont une durée de vie ou d&#8217;activité limitée. Par exemple, une transaction sur une base de données ne peut pas excéder 5 minutes par défaut sur une serveur JBoss sous peine de provoquer l&#8217;exception suivante :</p>
<pre class="wp-caption" style="overflow: scroll;">Transaction is not active: tx=TransactionImple &lt; ac, BasicAction: -3f57f10b:911:49fb4a4b:3e status: ActionStatus.ABORT_ONLY &gt;; - nested throwable: (javax.resource.ResourceException: Transaction is not active: tx=TransactionImple &lt; ac, BasicAction: -3f57f10b:911:49fb4a4b:3e status: ActionStatus.ABORT_ONLY &gt;)</pre>
<p style="text-align: justify;">La seule solution est de découper son traitement en plusieurs traitements plus petit ou de modifier le timeout. Dans ce dernier cas, il faut faire attention car un timeout top grand peut avoir des effets néfastes sur les  performances de l&#8217;application. Voici comment gérer les démarcations de transaction pour découper un traitement long en plusieurs petits traitements :</p>
<p style="text-align: justify;"><em>Client (sans transaction) -&gt; EJB (transaction supportée : TransactionAttributeType.SUPPORTS) -&gt; EJBs (nouvelle transaction pour chaque appel EJB : TransactionAttributeType.REQUIRED ou TransactionAttributeType.REQUIRES_NEW)</em></p>
<h1>Dissociation entre le web et les traitements lourds</h1>
<p style="text-align: justify;">Après avoir vu le principe de fonctionnement d&#8217;un serveur d&#8217;application et comment développer un traitement long sans provoquer d&#8217;exception de timeout, il ne faut pas oublier qu&#8217;une application web peut être utilisée par un grand nombre d&#8217;utilisateurs. Si les requêtes HTTP provoquent des traitements longs cela peut rapidement provoquer une indisponibilité du serveur.</p>
<p style="text-align: justify;">Une des solutions possibles est d&#8217;utiliser deux serveurs d&#8217;applications différents : un serveur d&#8217;application pour les traitements lourds et un pour l&#8217;IHM. Les échanges entre ces deux serveurs doivent se faire en asynchrone pour ne pas pénaliser la partie web de l&#8217;application. Ainsi une augmentation du nombre d&#8217;utilisateur n&#8217;impactera pas votre application, à moins de mal configurer le serveur s&#8217;occupant de l&#8217;IHM.</p>
<p style="text-align: justify;">Au final, tout n&#8217;est qu&#8217;une question de paramétrage des serveurs. Il ne faut pas oublier qu&#8217;avec un serveur d&#8217;application le clustering est toujours possible, et dans ce cas, le nombre de threads disponibles pour traiter les demandes augment lui aussi.</p>
<p style="text-align: justify;">Vous pouvez utiliser le serveur d&#8217;application pour exécuter seulement des batchs. il faut alors vous assurer que le nombre de threads disponibles sur le serveur soit assez grand et que vos traitements successifs n&#8217;engendrent pas de problèmes de mémoire ou de réservation de ressources, car votre serveur ne sera pas réinitialisé au début de chaque traitement.</p>
<h1>Cas du conteneur embarqué</h1>
<p style="text-align: justify;">Si vous préférez avoir une JVM par traitement et donc une architecture plus proche d&#8217;un batch classique, des conteneurs embarqués sont désormais disponibles et ils fonctionnent très bien. J&#8217;ai déjà testé <a href="http://openejb.apache.org/" target="_blank">openEJB</a> et <a href="http://community.jboss.org/wiki/JBossEmbeddedAS" target="_blank">JBossEmbedded</a>, <a href="https://glassfish.dev.java.net/" target="_blank">glassfish</a>, etc. je n&#8217;ai jamais remarqué de problème sur leur utilisation. De plus, dans ce cas, comme il y a une JVM non partagée par traitement, les problèmes de disponibilités lié à l&#8217;utilisation de thread n&#8217;existe plus. J&#8217;ajouterai que l&#8217;utilisation d&#8217;un conteneur embarqué est très simple, voici un exemple avec openEJB :</p>
<p style="text-align: justify;">Créer un project maven avec l&#8217;archetype quickstart et ajouter openEJB dans les dépendances. Voici l&#8217;allure du fichier POM :</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.apache.openejb&lt;/groupId&gt;
            &lt;artifactId&gt;openejb-core&lt;/artifactId&gt;
            &lt;version&gt;3.1.2&lt;/version&gt;
                &lt;exclusions&gt;
                    &lt;exclusion&gt;
                        &lt;groupId&gt;org.apache.activemq&lt;/groupId&gt;
                        &lt;artifactId&gt;activeio-core&lt;/artifactId&gt;
                    &lt;/exclusion&gt;
                &lt;/exclusions&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
</pre>
<p>L&#8217;exclusion d&#8217;activeMq est nécessaire car l&#8217;artefact n&#8217;existe pas sur le repository maven. L&#8217;étape suivante est de rajouter deux fichiers de configuration : <em>jndi.properties</em> avec la ligne</p>
<pre class="wp-caption" style="text-align: justify;">java.naming.factory.initial = org.apache.openejb.client.LocalInitialContextFactory</pre>
<p>et un fichier &#8220;vide&#8221; <em>META-INF/ejb-jar.xml</em> qui ne contient que la ligne :</p>
<pre class="wp-caption" style="text-align: justify;">&lt;ejb-jar/&gt;</pre>
<p>Ce fichier XML vide indique au conteneur de rechercher les EJBs présents dans le classpath. Le serveur embarqué se démarre et déploie les  services EJB tout seul et vous n&#8217;avez plus qu&#8217;a les appeler <em>:</em></p>
<pre class="brush: java; title: ; notranslate">
    public class App {
       public static void main( String[] args ) {
          try {
             Context context = new InitialContext();
             HelloWorldService helloWorldService =
                (HelloWorldService) context.lookup(&quot;HelloWorldServiceHandlerLocal&quot;);
             System.out.println(helloWorldService.sayHello(&quot;Smith&quot;));
          } catch (NamingException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
          }
    }
}
</pre>
<p>Pour plus de précisions, voici l&#8217;URL où vous pouvez retrouver mon exemple : <a href="https://subversion.assembla.com/svn/everythingiswrong/tutorial-embedded-openejb/" target="_blank">https://subversion.assembla.com/svn/everythingiswrong/tutorial-embedded-openejb/</a></p>
<h1 style="text-align: justify;">Conclusion</h1>
<p style="text-align: justify;">
<p style="text-align: justify;">Pour conclure cet article, je dirais qu&#8217;utiliser un serveur d&#8217;application pour ses batchs ou traitements longs est très intéressant car cela vous permet de disposer de la stack Java J2EE. Cela peut  éventuellement vous permettre de mutualiser du code entre traitement batch et IHM, si vous avez une application qui nécessite les deux. Si l&#8217;utilisation d&#8217;un &#8220;vrai&#8221; serveur d&#8217;application vous fait peur, il est toujours possible d&#8217;utiliser un conteneur embarqué pour bénéficier, là aussi, de la stack logiciel fournie par Java J2EE.</p>
<p style="text-align: justify;">Les traitements longs sur les serveurs d&#8217;applications J2EE ne sont donc qu&#8217;une question de paramétrage. Ils ne sont pas à proscrire, surtout si vous utilisez un conteneur embarqué.</p>
<p style="text-align: justify;">Pour ceux qui ne sont toujours pas convaincus, voici 4 articles intéressants sur les batchs J2EE et le multithreading dans un serveur J2EE :</p>
<ul>
<li><a href="http://javablog.franksalinas.net/2009/03/01/the-ejb-specification-concurrency-and-batch-processing/" target="_blank">http://javablog.franksalinas.net/2009/03/01/the-ejb-specification-concurrency-and-batch-processing/</a></li>
<li><a href="http://www.javaworld.com/javaworld/jw-07-2003/jw-0718-mdb.html?page=1" target="_blank">http://www.javaworld.com/javaworld/jw-07-2003/jw-0718-mdb.html?page=1</a></li>
<li><a href="http://java.sys-con.com/node/415321" target="_blank">http://java.sys-con.com/node/415321</a></li>
<li><a href="http://www.devx.com/java/article/20791" target="_blank">http://www.devx.com/java/article/20791</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://everythingiswrong.free.fr/index.php/2010/10/09/traitements-longs-et-batchs-sur-un-serveur-dapplication-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
