Architecture Maven d'un projet Seam 2

Mikael Robert

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, voire 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ément 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écanismes 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.

- Titre : Architecture Maven d'un projet Seam 2

- Auteur : Mikael Robert

- Parution : 27 mars 2009

- Mise à jour : 17 février 2020

- Licence : 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.

Sommaire

- I. Introduction

- II. Structure des projets

- II-A. Les projets Ear et Entities

- II-B. Le projet Services

- II-C. Le projet War

- III. Création des fichiers pom.xml

- III-A. Le pom du projet parent

- III-B. Le pom du projet EAR

- III-C. Le pom du projet Entities

- III-D. Le pom du projet Services

- III-E. Le pom du projet War

- IV. Conclusion

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 EJB 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 n'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, quel que 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'à 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ément 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écanismes 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 quatre 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 projets vides, 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.

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

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

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.

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 bibliothèques 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 bibliothèque.

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 inclus 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'exclus parfois des bibliothèques lors d'inclusion : c'est simplement pour éviter les redondances de bibliothèques dans l'archive finale.
En effet, lorsqu'on inclut une bibliothèque via Maven, on appelle le pom de celle-ci, donc si vous incluez une bibliothèque qui inclut d'autres bibliothèques que vous avez déjà, vous allez vous retrouver avec des jars en double dans votre archive, autant dire que ce n’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 inclus par deux bibliothèques. Cela a résulté en un comportement anarchique et incompréhensible dans l'application.

Pom du projet parent

<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égral qui n'a pas été directement mis dans l'article par souci 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 à 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.

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

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

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.

<?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.

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…).

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

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 inclut 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 bibliothèque 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 bibliothèque 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 projets, création d'entities 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.