Category: Java J2EE

Maven et SeamTest

By , 22/03/2011

L’intégration des tests unitaires SeamTest dans un projet Maven est assez compliquée. Voici un exemple concret :

Présentation du projet

Avant de rentrer dans des détails techniques, je préfère vous parler de l’application qui va me servir de base pour intégrer mon test SeamTest.

Vision fonctionnelle

J’ai choisi de me baser sur l’exemple “hello world” du livre Seam Framework: Experience the Evolution of Java EE 2nd edition. Vous pouvez retrouver les sources des exemples du livre à l’adresse suivante : http://solutionsfit.com/blog/books/. Malheureusement, l’auteur utilise Ant et non Maven pour gérer la compilation de ses projets.

J’ai rajouté l’utilisation d’un service EJB Stateless pour démontrer la possibilité d’utiliser SeamTest dans un contexte technique hétérogène. Voici le diagramme des cas d’utilisation de l’application :

Cas d'utilisation de l'application

Vision maven

Le projet est composé d’un module père ayant trois modules fils :

seamtest-parent
|– seamtest-ear
|– seamtest-ejb
`– seamtest-webapp

Vous pouvez checkouter les sources à l’adresse suivante : https://subversion.assembla.com/svn/everythingiswrong/seamtest-parent/.

Dans le reste de l’article, je vais me focaliser sur le module seamtest-ejb car c’est lui qui contient le composant Seam, la persistance et l’EJB Stateless à tester.

Composant Seam à tester

Nous allons tester le composant qui va :

  • Enregistrer une nouvelle personne dans la base de données
  • Rechercher toutes les personnes de la base de données
@Stateful
@Name("manager")
public class ManagerAction extends Manager {
  @In
  private Person person;

  @Out
  private List<Person> 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() {
  }
}

Installation et configuration

Pour information, SeamTest utilise le serveur JBoss embedded.

Installation de JBoss Embedded

Cette installation se résume à la copie du répertoire booststrap qui est dans la distribution de Seam (par exemple ici) dans le répertoire src/test.

Le fichier “pom.xml”

Ce fichier doit contenir l’ensemble des librairies qui vont permettre de démarrer et d’exécuter le serveur JBoss embedded. Il doit aussi prendre en compte le répertoire de bootstrap ajouté précédemment dans les ressources des tests.

<dependencies>
  ...
  <!-- dépendances des tests unitaites : http://community.jboss.org/thread/18299 -->
  <!-- dependencies related to JBoss Embedded for Seam 2.X.X -->
  <dependency>
    <groupId>org.jboss.seam.embedded</groupId>
    <artifactId>jboss-embedded-all</artifactId>
    <version>beta3.SP12</version>
    <scope>test</scope>
    <exclusions>
      <exclusion>
        <groupId>org.jboss.microcontainer</groupId>
        <artifactId>jboss-deployers-client-spi</artifactId>
      </exclusion>
      <exclusion>
        <groupId>org.jboss.microcontainer</groupId>
        <artifactId>jboss-deployers-core-spi</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.jboss.seam.embedded</groupId>
    <artifactId>hibernate-all</artifactId>
    <version>beta3.SP12</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.jboss.seam.embedded</groupId>
    <artifactId>thirdparty-all</artifactId>
    <version>beta3.SP12</version>
    <scope>test</scope>
  </dependency>

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

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

  <!-- dependencies related to TestNG -->
  <dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>5.8</version>
    <classifier>jdk15</classifier>
    <scope>test</scope>
  </dependency>
</dependencies>
<build>
  <testResources>
    <testResource>
      <directory>src/test/resources</directory>
      <filtering>true</filtering>
    </testResource>
    <testResource>
      <directory>src/test/bootstrap</directory>
      <filtering>false</filtering>
    </testResource>
    <testResource>
      <directory>src/test/bootstrap</directory>
      <filtering>true</filtering>
      <includes>
        <include>**/*.xml</include>
      </includes>
    </testResource>
  </testResources>
  ...
</build>

Remarque : à l’heure actuelle la version la plus récente du conteneur est la beta3.SP12.

Fichiers de tests

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’information sur le nom JNDI des EJB :

org.jboss.seam.core.init.jndiPattern = #{ejbName}/local

La classe de test doit étendre SeamTest. Elle peut ensuite utiliser l’EL pour référencer les composants Seam :

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<Person> fans = (List<Person>) 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());
    }
  }
}

En utilisant Hibernate, vous pouvez exécuter des scripts SQL au déploiement de votre test en ajoutant un fichier import.sql dans le classpath de test (src/test/resources). Cela dit,  dans ce cas, je conseillerai plutôt d’utiliser l’intégration avec DBUnit.

Exécution

Pour exécuter les tests il faut lancer la commande mvn clean test.

Variantes

Intégration avec DBUnit

L’intégration est possible entre seamTest et DBUnit. La classe de test doit étendre DBunitSeamTest et implémenter la méthode prepareDBUnitOperations(). 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 :

<build>
  ...
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.4.3</version>
    <configuration>
      <systemProperties>
        <property>
          <name>datasourceJndiName</name>
          <value>java:/DefaultDS</value>
        </property>
        <property>
          <name>database</name>
          <value>HSQL</value>
        </property>
      </systemProperties>
      <argLine>-Dsun.lang.ClassLoader.allowArraySyntax=true</argLine>
    </configuration>
 ...
</build>

Remarque : deux propriétés pour déclarer le type de la source de données et son nom JNDI ainsi qu’un argument pour permettre au serveur JBoss Embedded de s’éxécuter avec une JDK 1.6 (par défaut ce serveur n’est compatible qu’avec une JDK1.5).

Pour information, DBUnit propose deux implémentations différentes pour décrire les données d’une base : le FlatXmlDataSet et le XmlDataSet (http://dbunit.sourceforge.net/components.html).  SeamTest ne support que le FlatXmlDataSet.

Dépendances sur des projets ou modules de type EJB

Dans le cas où votre module dépende d’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 maven-dependency-plugin comme cela :

<build>
  ...
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
      <execution>
        <id>copy</id>
        <phase>process-test-resources</phase>
        <goals>
          <goal>copy</goal>
        </goals>
        <configuration>
          <artifactItems>
            <artifactItem>
              <groupId>...</groupId>
              <artifactId>...</artifactId>
              <version>...</version>
              <type>...</type>
              <classifier>...</classifier>
              <overWrite>false</overWrite>
              <outputDirectory>${project.build.directory}/test-classes/deploy</outputDirectory>
            </artifactItem>
          </artifactItems>
        </configuration>
      </execution>
    </executions>
  </plugin>
  ...
</build>

Remarque : la copie de la dépendance se déroule avant la phase d’exécution des tests.

Test unitaires : mauvaises pratiques (TDD anti-pattern)

By , 20/03/2011

Depuis pas mal de temps, je me pose des questions sur les bonnes pratiques à mettre en œuvre dans le développement de mes tests unitaires. N’ayant jamais rencontré de personne ayant beaucoup d’expérience dans le domaine, je me suis toujours restreint à développer des tests :

  • Rapides à développer
  • Faciles à maintenir
  • limités à une fonctionnalité

C’est dans ce contexte que j’ai cherché sur internet des propositions de bonnes pratiques sur les tests unitaires automatisés. J’ai trouvé mieux : des pratiques à éviter (http://blog.james-carr.org/2006/11/03/tdd-anti-patterns/).

Profiler une application J2EE avec JBoss et TPTP

By , 10/03/2011

Cet article va vous expliquer comment utiliser Eclipse pour vérifier les performances d’une application sous JBoss. Je vous laisserai découvrir les écrans de reporting par vous même car ils dépendent de votre code source.

Installation

Il est nécessaire d’installer les plugins suivant dans eclipse :

Puis il faut créer un serveur JBoss depuis la vue Server.

TPTP

JBoss TPTP

Exécution

Pour exécuter le profilage, il faut démarrer votre serveur JBoss avec le bouton Profile. Eclipse vous demande de choisir le type d’informations à mesurer. Une seule possibilité à la fois (je n’ai pas encore compris pourquoi je ne peux pas avoir plusieurs data collector en même temps…) :

Avant de cliquer sur le bouton Finish, n’hésitez pas à ajouter ou modifier les filtres par défaut en double-cliquant sur Java Profiling. Cela va vous permettre de focaliser votre attention sur votre code et non celui des librairies tierces que vous utilisez :

Après le démarrage de votre serveur en mode profile, le collecteur de données se synchronise à intervalle de temps régulier. Pour éviter d’enregistrer des informations inutiles, vous pouvez le mettre en pause par exemple.

Problèmes rencontrés et astuces

JRebel

Il faut savoir que JRebel ne fonctionne pas lorsqu’on utilise TPTP. Donc si vous utilisez cet outil, il faudra le désactiver (démarrer votre serveur JBoss sans les paramètres JRebel) pour pouvoir profiler votre application.

Profiles indisponibles

Si lorsque vous essayez de démarrer votre serveur en mode profile vous avez une exception vous parlant de collecteur de données, vérifier que vos plugins soient bien à jour.

Performances

TPTP est très gourmand en mémoire donc ne vous étonnez pas de voire les performances de votre application chuter rapidement. J’ai aussi remarqué que les performances d’éclipse s’effondrent rapidement lors de l’analyse des données quand celles-ci sont très volumineuses.

Fiji 2.0 : Intégration de FusionCharts et JSF

By , 01/03/2011

Après avoir parlé de Fiji il y a quelques mois, j’ai souhaité développer un petit exemple pour mettre en pratique l’intégration Flex dans une page JSF 2. Pour cela j’ai choisis d’intégrer un graphique FusionCharts dans une page JSF. Pour information, FusionCharts est une librairie graphique qui permet de développer des graphiques à partir d’un fichier XML (lignes, histogrammes, cartes du monde, etc.).

Mise en place du projet

Pour faire simple, j’ai choisis de commencer une nouvelle application Java J2EE6 grâce au squelette de projet weld : org.jboss.weld.archetypes:weld-jsf-servlet-minimal. Je suis ensuite aller chercher les librairies tierces suivantes :

Développement

Mon but est de reproduire le premier exemple de graphique proposé sur la gallerie du site internet de FusionCharts :

Tout d’abord, il faut déposer la librairie Fiji 2.0 dans le répertoire src/main/webapp/WEB-INF/lib puis un graphique fusionChart (*.swf) dans un répertoire web du projet. Ensuite, deux fichiers sont nécessaires :

  • Un fichier XHTML pour générer le XML qui décrit le graphique
  • Un fichier XHTML pour  décrire la page JSF qui va intégrer le graphique

Voici le fichier XHTML qui va décrire le graphique :

<?xml version="1.0" encoding="UTF-8"?>

<f:view xmlns="http://www.w3.org/1999/xhtml"
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:h="http://java.sun.com/jsf/html"
 xmlns:f="http://java.sun.com/jsf/core" contentType="text/xml">

 <graph yAxisName='Sales Figure' caption='Top 5 Sales Person' numberPrefix='$'
    decimalPrecision='1' divlinedecimalPrecision='0' limitsdecimalPrecision='0'>
   <ui:repeat var="item" value="#{dynaGraphique.listPersonne}">
      <set name='#{item.name}' value='#{item.sales}' color='#{item.color}' />
   </ui:repeat>
 </graph>

</f:view>

On peut remarquer que j’utilise le tag <ui:repeat/> pour itérer sur une liste de données qui va représenter plusieurs séries sur mon histogramme. Ci-dessous, le fichier qui décrit le même graphique en static :

<?xml version="1.0" encoding="UTF-8"?>
<f:view xmlns="http://www.w3.org/1999/xhtml"
   xmlns:ui="http://java.sun.com/jsf/facelets"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:f="http://java.sun.com/jsf/core" contentType="text/xml">

   <graph yAxisName='Sales Figure' caption='Top 5 Sales Person' numberPrefix='$'
      decimalPrecision='1' divlinedecimalPrecision='0' limitsdecimalPrecision='0'>
        <set name='Alex' value='25000' color='AFD8F8' />
        <set name='Mark' value='35000' color='F6BD0F' />
        <set name='David' value='42300' color='8BBA00' />
        <set name='Graham' value='35300' color='FF8E46' />
        <set name='John' value='31300' color='008E8E' />
   </graph>

</f:view>

Les deux classes java qui vont contenir les données pour le graphique. Vous allez retrouver les données précédentes dans la première classe :

@Model
public class DynaGraphique {
 private List<Personne> listPersonne = new ArrayList<Personne>();

 @PostConstruct
 public void initialize() {
   listPersonne.add(new Personne("Alex", 25000, "AFD8F8"));
   listPersonne.add(new Personne("Mark", 35000, "F6BD0F"));
   listPersonne.add(new Personne("David", 42300, "8BBA00"));
   listPersonne.add(new Personne("Graham", 35300, "FF8E46"));
   listPersonne.add(new Personne("John", 31300, "008E8E"));
 }
 // Getter et Setter

}
public class Personne {
 private String name;
 private int sales;
 private String color;

 public Personne() {
 }

 public Personne(String name, int sales, String color) {
 super();
 this.name = name;
 this.sales = sales;
 this.color = color;
 }
//Getter et Setter ...
...
}

Le fichier XHTML qui va générer la page JSF :

<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
   xmlns:ui="http://java.sun.com/jsf/facelets"
   xmlns:f="http://java.sun.com/jsf/core"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:fiji="http://exadel.com/fiji"
   template="/WEB-INF/templates/default.xhtml"
   xmlns:a4j="http://richfaces.org/a4j">
      <ui:define name="content">
         <!-- static : voir le fichier fusionChart/fusion01.jsf -->
         <fiji:swf src="fusionChart/FCF_Column3D.swf" bgcolor="#FFFFFF" width="520" height="400">
            <f:param name="dataURL" value="fusionChart/fusion01.jsf" />
         </fiji:swf>
         <!-- dynamique -->
         <fiji:swf src="fusionChart/FCF_Column3D.swf" bgcolor="#FFFFFF" width="520" height="400">
            <f:param name="dataURL" value="fusionChart/fusion02.jsf" />
         </fiji:swf>
      </ui:define>
</ui:composition>

Pour information, il ne faut pas oublier de préciser les attributs bgcolor, width et height pour éviter une erreur d’exécution de Fiji.

Exécution du projet

Pour exécuter le projet, j’utilise la commande maven mvn compile tomcat:run. L’application est alors disponible à l’adresse : http://localhost:9090/jsf.servlet.minimal.

Vous pouvez checkouter le projet à l’adresse suivante : http://subversion.assembla.com/svn/everythingiswrong/tutorial-fiji-fusionchart/

jaxb2-maven-plugin : plusieurs exécutions successives de jaxb2:xjc

By , 11/02/2011

Dans ce ticket, je vais expliquer comment bien configurer le plugin jaxb2-maven-plugin dans le cas où l’on souhaite transformer des fichiers XSD en classes java vers des packages différents. Il faut savoir qu’avec ce plugin il n’est pas possible de définir plusieurs packages de destination dans une même exécution.

Dans l’exemple choisi, je génère deux classes Java à partir de deux fichier XSD vers deux packages différents :

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>jaxb2-maven-plugin</artifactId>
  <executions>
    <execution>
      <id>id1</id>
      <phase>generate-sources</phase>
      <goals>
        <goal>xjc</goal>
      </goals>
      <configuration>
        <clearOutputDir>false</clearOutputDir>
        <staleFile>${project.build.directory}/generated-sources/jaxb/.staleFlag-id1</staleFile>
        <schemaDirectory>${basedir}/src/main/resources/id1</schemaDirectory>
        <packageName>id1</packageName> <!-- The name of your generated source package -->
      </configuration>
    </execution>
    <execution>
      <id>id2</id>
      <phase>generate-sources</phase>
      <goals>
        <goal>xjc</goal>
      </goals>
      <configuration>
        <clearOutputDir>false</clearOutputDir>
        <staleFile>${project.build.directory}/generated-sources/jaxb/.staleFlag-id2</staleFile>
        <schemaDirectory>${basedir}/src/main/resources/id2</schemaDirectory>
        <packageName>id2</packageName> <!-- The name of your generated source package -->
      </configuration>
    </execution>
  </executions>
  <dependencies>
     <dependency>
       <groupId>xerces</groupId>
       <artifactId>xercesImpl</artifactId>
       <version>2.8.1</version>
     </dependency>
  </dependencies>
</plugin>

A noter que pour chaque exécution :

  • Il est nécessaire d’utiliser un identifiant unique. Sinon maven n’arrivera pas à exécuter le plugin.
  • Il faut impérativement utiliser l’option staleFile pour associer un fichier différent à chaque exécution (ce fichier sert au plugin pour savoir si les classes Java sont déjà générées). Sans cela, la seconde exécution ne génèrera pas de classe Java.
  • Il faut indiquer au plugin de ne pas nettoyer le répertoire de génération avant l’exécution (option clearOutputDir à false) car c’est son comportement par défaut. Sans cela, la seconde exécution supprimera les classes générées pas la première.

Voici l’adresse de l’exemple associé : https://subversion.assembla.com/svn/everythingiswrong/tutorial-jaxb2-maven-plugin/.

EJB3 : intercepteurs

By , 21/01/2011

Les intercepteurs sont des petits programmes qui interviennent avant et après l’exécution d’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’en servir pour logger les entrées et sorties d’une méthode comme je le propose dans mon exemple qui se base sur un simple “HelloWorld” en EJB3. J’utilise openEJB pour simplifier l’exécution et vous permettre d’utiliser l’exemple tel quel.

Création de l’intercepteur : c’est un EJB standard avec une méthode public annotée avec @AroundInvoke.

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 < 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
    }
}

Comme vous pouvez le voir, c’est l’objet InvocationContext qui va vous permettre de visualiser la méthode et les paramètres utilisés.

Déclaration de l’EJB en tant qu’intercepteur : ajouter ces quelques lignes dans le fichier META-INF/ejb-jar.xml :

<?xml version="1.0" encoding="UTF-8"?>
<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">

  <interceptors>
    <interceptor>
      <interceptor-class>org.everythingiswrong.tutorial.interceptor_openejb.interceptor.LoggerServiceBean</interceptor-class>
    </interceptor>
  </interceptors>

  <assembly-descriptor>
    <interceptor-binding>
      <ejb-name>*</ejb-name>
      <interceptor-class>org.everythingiswrong.tutorial.interceptor_openejb.interceptor.LoggerServiceBean</interceptor-class>
    </interceptor-binding>
  </assembly-descriptor>

</ejb-jar>

Voici l’adresse SVN du projet : https://subversion.assembla.com/svn/everythingiswrong/tutorial-interceptor-openejb

jaxws-maven-plugin : générer des services SOAP à partir de plusieurs WSDL

By , 03/01/2011

Dans ce poste je vais générer des services SOAP java à partir de deux fichiers WSDL. La contrainte que je m’impose est de générer dans un même package toutes les classes java. Il faut paramétrer le plugin jaxws-maven-plugin en lui donnant un nom de package pour l’ensemble des WSDL (ou bien utiliser le même namespace pour les deux WSDL et leurs objets associés) :

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>jaxws-maven-plugin</artifactId>
   <executions>
      <execution>
         <goals>
            <goal>wsimport</goal>
         </goals>
      </execution>
   </executions>
   <configuration>
      <packageName>com.example.myschema</packageName>
   </configuration>
...
</plugin>

Le problème c’est que le plugin génère les objets dans l’ordre de traitement des WSDL. Cela implique que la classe ObjectFactory.java qui permet d’instancier les objets issus de la génération est créée une première fois pour les objets du premier WSDL puis écrasée par la seconde génération avec les objets du second WSDL.

Pour résoudre ce problème, il est possible de mutualiser les objets des deux WSDL dans un même schéma XSD qui va englober tous les objets des deux WSDL. La première génération va toujours être écrasée par la seconde mais cette fois si, les deux générations produisent exactement les mêmes objets et l’objet ObjectFactory va pouvoir instancier tous les objets des deux WSDL.

Voici un exemple : https://subversion.assembla.com/svn/everythingiswrong/multiple-wsdl-same-package/

Eclipse : autocompletion sur les imports statiques

By , 13/12/2010

Eclipse propose l’autocompletion sur les méthodes des objets importés statiquement qu’après les avoir déclarés manuellement. Par exemple, pour utiliser les asserts JUnit dans un test TestNg, il faut ajouter l’import statique suivant avant de pouvoir bénéficier de l’aide à la saisie :

import static org.testng.AssertJUnit.*;

Pour profiter de l’autocompletion sans ajouter cette ligne au préalable, il faut se diriger dans le menu : Window -> Preferences puis Java -> Editor -> Content Assist -> Favorites et ajouter le nouveau type org.testng.AssertJUnit.

Utiliser l’annuaire JNDI d’un JBoss embedded

By , 12/12/2010

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’est pourquoi je vous propose cet article  qui va vous apprendre à enregistrer une chaine de caractère (java.lang.String) dans l’annulaire JNDI de JBoss embedded. Pour cela, il faut ajouter ce code XML dans le fichier embedded-jboss-beans.xml de votre classpath :

<bean name="" class="org.jboss.ejb3.embedded.JndiBinder">
    <property name="target">La valeur de la variable</property>
    <property name="bindTo">variableName</property>
    <property name="serializable">true</property>
</bean>

Voici un exemple concret : https://subversion.assembla.com/svn/everythingiswrong/embedded-jboss-jndi-exemple.

Pour plus d’information sur le conteneur embarqué  de JBoss que j’utilise dans l’exemple : http://docs.jboss.org/ejb3/embedded/embedded.html.

Rechercher les jar contenant une classe Java

By , 11/12/2010

En programmation Java il arrive de temps en temps qu’un programme tombe en erreur car il manque des classes dans le classpath d’exécution. Jusqu’à présent, je me suis toujours arrangé pour retrouver les artefacts (jar) contenant les classes manquant avec de l’expérience et surtout de la change.

Maintenant c’est fini ! Je viens de découvrir le site internet findjar. Grâce à lui, je retrouve facilement les artefacts contenant ma classe absente !

OfficeFolders theme by Themocracy