Architecture Maven d'un projet Seam 2

L'outil Seam-gen est bien pratique, mais pour ce qui est des projets générés, le seul outil de compilation possible reste ant.
De plus l'architecture proposée reste simpliste et limitée, voir précaire.
C'est un utilitaire en console, présent dans chaque release téléchargeable de Seam.
Il permet en répondant à des questions simples (nom du projet, ear ou war, type de base de données ...) de créer une structure de projet complète avec toute la configuration XML déjà prête.
Les projets générés Seam-gen contiennent tout ce dont vous avez besoin pour démarrer votre projet instantanémment sans avoir besoin de configurer quoi que ce soit.
Il permet aussi de générer des pages JSF, des composants Seam et des mécanisme CRUD, simplement en répondant à quelques questions en ligne de commande.
Maven est aujourd'hui l'outil de compilation/gestion des dépendances incontournable en java, il facilite énormément cet aspect de la gestion du projet.
C'est pourquoi lorsque je crée un nouveau projet Seam je préfère utiliser Maven 2.
Néanmoins, pourquoi se priver des facilités de seam-gen ?
Nous allons donc voir, à partir d'un projet généré par Seam-gen comment créer une architecture 4 tiers avec gestion des dépendances automatisée.

Article lu   fois.

L'auteur

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Afin d'être relativement large dans les explications, nous couvrirons ici, la création d'un projet de type EAR, pour pouvoir y inclure des EJB.
Si vous souhaitez créer simplement une webapp simple (vous ne voulez pas d'un serveur d'application avec conteneur d'EJB par exemple), le principe reste le même.
Cependant il est bon de savoir que Seam permet la gestion des EJBs dans un serveur web type tomcat, grâce à un système interne d'émulation de conteneur d'EJB, cela peut être très
pratique si vous travaillez dans un environnement rigide que vous ne pouvez faire évoluer. Je vous invite à vous référer à la documentation pour ce cas là.
Je vois d'ici arriver les commentaires du type «Pourquoi s'embêter et ne pas mettre un JBoss ou un Glassfish à la place ?», la réponse est simple : en entreprise on a pas toujours
le choix de l'environnement. La robustesse de ce type de projet est à mes yeux douteuse, mais si on n'a pas le choix … Bref ce n'est pas le sujet de cet article.
Personnellement j'ai passé beaucoup de temps sur mes premiers projets à faire la structure Maven et les poms.
Et à l'époque un exemple m'aurait été bien utile, c'est pourquoi j'ai décidé d'écrire cet article.
Dans le cas présent, admettons que l'on souhaite créer un outil de blog relativement large, l'équivalent d'un wordpress un genre de cms donc.
Le projet s'appellera alors dans mon article dreamisle-cms, à vous de modifier tout ce qui suivra pour votre projet.
Bien entendu, il est nécessaire de savoir utiliser l'outil Maven pour pouvoir comprendre et appliquer les explications données ci-après.
Il n'y a en effet rien de nouveau si ce n'est la gestion des dépendances de Seam, le but est surtout de donner un exemple.
Ici j'ai utilisé Eclipse et le plug-in maven2 pour eclipse mais cela fonctionne quelque soit l'IDE.

II. Structure des projets

La première partie pour la création de votre projet va donc consister à créer ce dernier avec seam-gen, comme expliqué dans la documentation officielle.
Cette étape est très simple et seam-gen vous guide pas à pas. Ainsi, nous évitons la laborieuse étape de création des fichiers de configurations xml et properties,
que nous n'aurons qu'a déplacer dans notre architecture Maven une fois celle-ci en place.

Seam-gen est un utilitaire en console, présent dans chaque release téléchargeable de Seam.
Il permet en répondant à des questions simples (nom du projet, ear ou war, type de base de données ...) de créer une structure de projet complète avec toute la configuration XML déjà prête.
Les projets générés Seam-gen contiennent tout ce dont vous avez besoin pour démarrer votre projet instantanémment sans avoir besoin de configurer quoi que ce soit.
Il permet aussi de générer des pages JSF, des composants Seam et des mécanisme CRUD, simplement en répondant à quelques questions en ligne de commande.
Enfin, gardez ce projet dans un coin de votre disque dur, il vous servira toujours.

On va maintenant créer un projet vide. Dans Eclipse : new project, général, project.

Ici on l'appelle dreamisle-cms.
Dans celui ci on crée alors 4 répertoires :
- dreamisle-cms-ear ce sera le sous-projet qui contiendra le pom utilisé par maven pour générer l'ear de votre application.
- dreamisle-cms-entities qui sera le projet qui contiendra vos EJB Entity, il représentera la couche modèle.
- dreamisle-cms-services sera le projet qui contiendra la couche service (action/contrôleur) de votre application : les EJB sessions, messages et les composants Seam.
Vous pouvez aussi décider de mettre vos EJB Entity dans un package entities dans ce projet, mais personnellement je préfère les séparer dans un projet externe,
ainsi l'abstraction des données est indépendante du reste du projet (Cas classique d'architecture 4-tiers).
- dreamisle-cms-war : le war de votre application, la webapp si vous préférez. La couche vue.
Enfin importez ces répertoires comme nouveaux projets vides dans Eclipse. (Utilisez l'outil de création de projet vide, mais changez l'emplacement du projet, et donnez lui
le même nom que le répertoire.)

Désormais on va créer les sous répertoires de votre architecture Maven typique.

Image non disponible

J'ai pensé que des captures d'écran seraient plus claires qu'un long texte.
Vous voyez donc ici la structure du projet principal.

II-A. Les projets Ear et Entities

Image non disponible

Ici donc l'arborescence du projet EAR et du projet entities.
Vous pouvez aussi voir quels fichiers vous devez placer dans quels répertoires.
Reprenez ceux de votre projet seam gen créé en première partie.

II-B. Le projet Services

Image non disponible

On constate la présence du fichier seam.properties, dans mon cas il est vide mais absolument nécessaire et il doit être présent dans tous les projets ou des composants
seam sont déployés.
En effet lors de son démarrage, Seam scanne les archives qui contiennent ce fichier.
La structure doit être identique à la capture. Sauf bien sûr, le package org.dreamisle.services : c'est à vous de décider de votre packaging.

II-C. Le projet War

Et enfin le war. La partie Web-inf est la plus importante, une bonne partie de la configuration de votre
application va se trouver ici.
Je n'ai pas étendu img, layout, stylesheet mais vous vous doutez bien de leur contenu.

Image non disponible

III. Création des fichiers pom.xml

On va pouvoir attaquer les choses sérieuses désormais : les fameux pom.
Ils sont souvent la hantise des développeurs java, mais une fois en place, ils font gagner un temps fou et évitent une sacrée perte de temps due au versioning des
librairies et frameworks utilisés. Et au moins, si vous êtes plusieurs dans l'équipe, vous êtes sûr que tout le monde travaille sur la même version de chaque librairie.

Et puis pom, moi ça me rappelle un certain constructeur d'ordinateurs que j'affectionne particulièrement … pas vous ?

Tout d'abord vous pouvez ajouter le dépôt : http://repository.jboss.org/maven2 dans votre settings.xml de Maven.
Vous l'avez vu, chaque sous projet à son fichier pom.xml.

Le projet principal qui contient les autres : dreamisle-cms, a aussi son pom.
Il s'agit pour maven du projet parent, il contient donc le pom principal, c'est lui qui contient en statique les versions de chaque dépendance, référencées dans les pom
fils grâce à provided ou à ${pom.version} pour vos dépendances personnelles.
Il faut donc vérifier que chaque jar est inclut une fois et une seule dans l'ear final généré.

III-A. Le pom du projet parent

Commençons donc par voir le pom parent : Comme vous pouvez le voir, j'exclue parfois des librairies lors d'inclusion : c'est simplement pour éviter les redondances de
librairies dans l'archive finale.
En effet, lorsqu'on inclue une librairie via Maven, on appelle le pom de celle-ci, donc si vous incluez une librairie qui inclue d'autres librairies que vous avez déjà
vous allez vous retrouver avec des jars en double dans votre archive, autant dire que c'est pas génial.
Conclusion quand vous faites un EAR avec Maven, regardez bien ce qu'il contient et adaptez votre pom, cela peut éviter des bêtises.
Typiquement j'ai eu le cas avec javaassist inclut par deux librairies. Cela a résulté d'un comportement anarchique et incompréhensible dans l'application.

Pom du projet parent
Sélectionnez

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>dreamisle-cms</groupId>
  <artifactId>dreamisle-cms</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>

  <name>dreamisle-cms</name>
  <description>Parent project for Dreamisle CMS project.</description>
  <inceptionYear>2008</inceptionYear>
  <organization>
    <name>Dreamisle</name>
    <url>http://www.dreamisle.net</url>
  </organization>


  <modules>
    <module>dreamisle-cms-services</module>
    <module>dreamisle-cms-entities</module>
    <module>dreamisle-cms-war</module>
    <module>dreamisle-cms-ear</module>
  </modules>

  <developers>
    <developer>
      <id>mikael</id>
      <name>Mikael</name>
      <email>mikael@dreamisle.net</email>
      <roles>
        <role>Developer</role>
      </roles>
    </developer>
  </developers>

  <repositories>
    <!--repository>
      <id>jboss.com</id>
      <url>http://repository.jboss.com/maven2</url>
    </repository-->
    <!--repository>
      <id>java.net</id>
      <url>http://download.java.net/maven/2</url>
    </repository-->
  </repositories>

  <dependencyManagement>
    <dependencies>
     <!-- JBoss Seam -->
      <dependency>
        <groupId>org.jboss.seam</groupId>
        <artifactId>jboss-seam</artifactId>
        <!--  type>ejb</type -->
        <version>2.1.1.GA</version>
        <exclusions>
          <exclusion>
            <groupId>jboss</groupId>
            <artifactId>javassist</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      <dependency>
        <groupId>org.jboss.seam</groupId>
        <artifactId>jboss-seam-debug</artifactId>
        <version>2.1.1.GA</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.seam</groupId>
        <artifactId>jboss-seam-ui</artifactId>
        <version>2.1.1.GA</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.seam</groupId>
        <artifactId>jboss-seam-pdf</artifactId>
        <version>2.1.1.GA</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.seam</groupId>
        <artifactId>jboss-seam-mail</artifactId>
        <version>2.1.1.GA</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.seam</groupId>
        <artifactId>jboss-seam-remoting</artifactId>
        <version>2.1.1.GA</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.seam</groupId>
        <artifactId>jboss-seam-ioc</artifactId>
        <version>2.1.1.GA</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.el</groupId>
        <artifactId>jboss-el</artifactId>
        <version>1.0_02.CR2</version>
      </dependency>
	  <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.3.GA</version>
        <scope>provided</scope>
      </dependency>
      
  <!-- [...] -->
  </dependencies>
</project>

Téléchargez le pom du projet parent intégralTéléchargez le pom du projet parent intégral. qui n'a pas été directement mis dans l'article par soucis de lisibilité. Je ne vais pas rentrer dans le détail sur le contenu du pom, si vous ne comprenez pas ce code xml, commencez par vous reporter à des documentations sur maven, il y en a de très bonnes sur developpez.com.
Par exemple : Introduction à MavenIntroduction à Maven

III-B. Le pom du projet EAR

Et maintenant le pom de l'ear : c'est lui qui contient les instructions de build pour maven, donc faites celui-ci avec une attention particulière. Lisez attentivement la partie build, j'y utilise un plugin qui permet de déplacer l'ear final vers le répertoire de déploiement de votre serveur d'application (ici jboss). Ce plug-in maven ne fait que copier/coller l'archive dans le deploy à votre place mais c'est bien pratique.

 
Sélectionnez

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <parent>
    <groupId>dreamisle-cms</groupId>
    <artifactId>dreamisle-cms</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>dreamisle-cms</groupId>
  <artifactId>dreamisle-cms-ear</artifactId>
  <packaging>ear</packaging>

  <name>dreamisle-cms-ear</name>
  <description>ear archive for dreamisle cms.</description>
  <inceptionYear>2009</inceptionYear>
  <organization>
    <name>Dreamisle</name>
    <url>http://www.dreamisle.net</url>
  </organization>

  <dependencies>

    <dependency>
      <groupId>dreamisle-cms</groupId>
      <artifactId>dreamisle-cms-entities</artifactId>
      <type>ejb</type>
      <version>${pom.version}</version>
    </dependency>
    <dependency>
      <groupId>dreamisle-cms</groupId>
      <artifactId>dreamisle-cms-services</artifactId>
      <type>ejb</type>
      <version>${pom.version}</version>
    </dependency>
    <dependency>
      <groupId>dreamisle-cms</groupId>
      <artifactId>dreamisle-cms-war</artifactId>
      <type>war</type>
      <version>${pom.version}</version>
    </dependency>

    <!-- Jboss Seam -->
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam</artifactId>
      <!--<type>ejb</type> !-->
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam-ui</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.jboss.el</groupId>
      <artifactId>jboss-el</artifactId>
      <scope>provided</scope>
    </dependency>

  <!-- [...] -->
  </dependencies>
</project>

Téléchargez le pom du projet EAR intégral.Téléchargez le pom du projet EAR intégral.
Il est important de respecter l'ordre d'appel des modules, mais si vous connaissez maven, vous devez déjà le savoir.

III-C. Le pom du projet Entities

Celui-ci est simple, il ne contient que les dépendances du projet.

 
Sélectionnez
 
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <parent>
    <groupId>dreamisle-cms</groupId>
    <artifactId>dreamisle-cms</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>dreamisle-cms</groupId>
  <artifactId>dreamisle-cms-entities</artifactId>

  <name>dreamisle-cms-entities</name>
  <description>All dreamisle ejb entities classes</description>
  <inceptionYear>2009</inceptionYear>
  <organization>
    <name>Dreamisle</name>
    <url>http://www.dreamisle.net/</url>
  </organization>

<dependencies>
    <!-- JBoss Seam -->
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam</artifactId>
      <scope>provided</scope>
      <!--  type>ejb</type -->
    </dependency>
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam-ui</artifactId>
      <scope>provided</scope>
    </dependency>

  <!-- [...] -->
  </dependencies>
</project>

Téléchargez le pom du projet Entities intégral.Téléchargez le pom du projet Entities intégral.

III-D. Le pom du projet Services

Petite subtilité : on commence par ajouter comme dépendance le projet entities, pour pouvoir utiliser les EJB entités qui y sont définis bien entendu.

 
Sélectionnez
 
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <parent>
    <groupId>dreamisle-cms</groupId>
    <artifactId>dreamisle-cms</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>dreamisle-cms</groupId>
  <artifactId>dreamisle-cms-services</artifactId>

  <name>dreamisle-cms-services</name>
  <description>All dreamisle CMS classes and EJB.</description>
  <inceptionYear>2008</inceptionYear>
  <organization>
    <name>Dreamisle</name>
    <url>http://www.dreamisle.net/</url>
  </organization>

  <dependencies>
    <dependency>
      <groupId>dreamisle-cms</groupId>
      <artifactId>dreamisle-cms-entities</artifactId>
      <type>ejb</type>
      <version>${pom.version}</version>
    </dependency>
    <!-- JBoss Seam -->
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam</artifactId>
      <scope>provided</scope>
      <exclusions>
        <exclusion>
          <groupId>javassist</groupId>
          <artifactId>javassist</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam-ui</artifactId>
      <scope>provided</scope>
   </dependency>
       <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam-remoting</artifactId>
      <scope>provided</scope>
    </dependency>
  <!-- [...] -->
  </dependencies>
</project>

Téléchargez le pom du projet Services intégral.Téléchargez le pom du projet Services intégral.

III-E. Le pom du projet War

Et enfin Le pom du war, ici on ajoute une partie build en précisant d'utiliser le plugin de génération de war de maven (ce n'est ni un jar ni un ear...).

 
Sélectionnez

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <parent>
    <groupId>dreamisle-cms</groupId>
    <artifactId>dreamisle-cms</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>dreamisle-cms</groupId>
  <artifactId>dreamisle-cms-war</artifactId>
  <packaging>war</packaging>

  <name>dreamisle-cms-war</name>
  <description>Web project for dreamisle-cms.</description>
  <inceptionYear>2009</inceptionYear>
  <organization>
    <name>Dreamisle</name>
    <url>http://www.dreamisle.net/</url>
  </organization>

  <dependencies>

    <!-- JBoss Seam -->
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam-ioc</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.jboss.seam</groupId>
          <artifactId>jboss-seam</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.jboss.el</groupId>
          <artifactId>jboss-el</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam-mail</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.jboss.seam</groupId>
          <artifactId>jboss-seam</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.jboss.el</groupId>
          <artifactId>jboss-el</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam-pdf</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.jboss.seam</groupId>
          <artifactId>jboss-seam</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.jboss.el</groupId>
          <artifactId>jboss-el</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam-remoting</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.jboss.seam</groupId>
          <artifactId>jboss-seam</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.jboss.el</groupId>
          <artifactId>jboss-el</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam-ui</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.jboss.seam</groupId>
          <artifactId>jboss-seam</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.jboss.el</groupId>
          <artifactId>jboss-el</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam</groupId>
      <artifactId>jboss-seam-debug</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.jboss.seam</groupId>
          <artifactId>jboss-seam</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.jboss.el</groupId>
          <artifactId>jboss-el</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
  <!-- [...] -->
</project>

Téléchargez le pom du projet War intégral.Téléchargez le pom du projet War intégral.

IV. Conclusion

Et voilà vous avez vos projets et vos poms, vous n'avez plus qu'à adapter à vos besoins !
Cette méthode a un autre avantage, vous pouvez n'inclure que ce qui est strictement nécessaire contrairement à un projet seam-gen classique qui inclus tout ce dont vous pourriez peut
être avoir besoin, et oui il faut bien que seam-gen soit adapté à tous les projets possibles.

De plus, si vous souhaitez utiliser une autre librairie que celles d'origines, c'est très simple, il n'y a qu'à ajouter la dépendance, et maven vous récupérera la librairie tout seul.

J'espère que cet article, et les poms à disposition vous auront été utiles.
Dernier conseil sinon, installez vous les JBoss Tools disponibles sur jboss.org dans download.
Ce plugin eclipse, est vraiment génial lorsqu'on utilise Seam.
Il permet d'intégrer les possibilités du seam gen (création de projet, création d'entity avec la liste la home et les pages de gestion crud de celles-ci, création d'ejb pré-annotés avec interface et classe de l'ejb, créations de composants seam) en quelques clics via des assistants (wizard) eclipse habituels.

Liste de mes articles sur Seam :
Architecture Maven d'un projet Seam 2
Annotations Seam : Datamodel, Factory et Unwrap.
Création d'un composant facelet personnalisé avec Facelets JSF et Richfaces.
Intégration d'Hibernate Search à une application Seam 2.
Présentation Globale de Seam.
  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2009 Mikael Robert. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.