Contenu EJB dans les modules WAR
Cette rubrique explique les conditions associées au contenu Enterprise JavaBeans (EJB) dans les modules WAR (web application archive).
Contenu EJB pris en charge
Mis à par pour les restrictions explicites, la fonction EJB prise en charge pour les beans regroupés dans les modules EJB Java™ archive (JAR) sont également pris en charge pour les beans regroupés dans les modules WAR. Un bean dans un module WAR peut avoir le même comportement qu'un bean dans un module JAR EJB.
Tous les types de beans EJB 3.x sont pris en charge dans les modules WAR et les beans session 2.x et 1.x. Pour des détails complets, consultez la spécification EJB 3.1.
Règles d'empaquetage
Les règles régissant l'empaquetage de contenu EJB dans un module WAR sont différentes de celles qui s'appliquent à l'empaquetage du même contenu dans un module JAR.
- A un niveau quelconque de l'arborescence commençant à WEB-INF/classes
- Dans un fichier JAR situé obligatoirement dans le répertoire WEB-INF/lib
Par exemple, si vous optez pour la première solution, le fichier de la classe de bean com.foo.MyBean peut être placé à l'endroit suivant du module WAR : WEB-INF/classes/com/foo/MyBean.class.
Si vous choisissez d'envelopper cette même classe de bean dans un fichier JAR appelé myJar.jar, celui-ci devra être placé à cet endroit et nulle part ailleurs : WEB-INF/lib/myJar.jar.
Le code des beans contenus dans un module WAR peut être en partie situé à un niveau quelconque de la structure WEB-INF/classes et en partie enveloppé dans des fichiers JAR qui doivent alors être placés directement dans WEB-INF/lib. Tout le code des beans d'un module WAR peut se trouver dans la structure de répertoire WEB-INF/classes sans aucune donnée dans le répertoire WEB-INF/lib ou tout le code des beans peut se trouver dans des fichiers JAR dans le répertoire WEB-INF/lib sans aucune donnée dans WEB-INF/classes.
Le répertoire WEB-INF/lib peut contenir plusieurs fichiers JAR, qui peuvent tous contenir du code de bean.
Si la même classe de bean est placée quelque part dans la structure WEB-INF/classes et dans un fichier JAR situé dans le répertoire WEB-INF/lib, c'est l'instance située dans WEB-INF/classes qui est chargée, l'autre instance placée dans le fichier JAR situé dans WEB-INF/lib étant alors ignorée.
Si la même classe de bean est enveloppée dans deux fichiers JAR différents, tous deux situés dans WEB-INF/lib, rien ne permet de savoir quelle instance sera chargée. A l'exécution, le serveur choisira l'une d'elles arbitrairement et la chargera ; l'autre instance sera simplement ignorée.
- WEB-INF/classes/META-INF/persistence.xml
- WEB-INF/lib/MyEntity.jar
IWAE0068W Le descripteur de déploiement EJB META-INF/ejb-jar.xml du fichier d'archive de bibliothèque foo.jar est ignoré. Le produit ne traite pas le descripteur de déploiement META-INF/ejb-jar.xml dans des archives de bibliothèque. Déplacez le descripteur de déploiement META-INF/ejb-jar.xml de l'archive de bibliothèque vers le répertoire WEB-INF du module WAR.
Un module WAR ne peut inclure du contenu EJB que s'il est au niveau de version 2.5 ou supérieur. Le contenu EJB sera ignoré s'il est placé dans un module WAR version 2.4 ou plus ancienne.

Différences techniques pour les EJB d'un fichier WAR
La liste suivante répertorie les différences entre les principales techniques qui existent entre des beans regroupés dans un module WAR et des beans groupés dans un module JAR EJB :
- Espace de noms partagé pour les composants
Tous les composants dans un module WAR partagent un même espace de noms. Cela implique que chaque composant EJB partage un seul espace de nom de composant avec tous les autres composants EJB dans le fichier WAR et les composants non-EJB, tels que les servlets. A l'inverse, un composant EJB empaqueté dans un module JAR d'EJB dispose de son propre espace de noms privé, qu'il ne partage avec aucun autre composant.
L'utilisation d'un espace de noms commun à tous les composants à d'importantes répercussions. Premier point important : un composant (EJB ou non) peut déclarer une référence et un autre composant peut rechercher cette référence dans l'espace de noms partagé. Second point important : les références déclarées par un composant peuvent être en conflit avec les références déclarées par un autre composant. A l'inverse, un EJB empaqueté dans un module JAR d'EJB ne peut pas rechercher, dans l'espace de noms, une référence déclarée par un autre composant, EJB ou non. De même, une référence déclarée par l'EJB ne peut jamais être en conflit avec une autre référence déclarée par un autre composant, même si les deux références portent le même nom.
Lorsque l'espace de noms partagé est utilisé, la même référence peut être déclarée plusieurs fois, à condition qu'il n'y ait pas de conflit entre les différentes déclarations de cette référence. Dès l'instant où cette condition est respectée, le serveur se comporte comme si la référence n'avait été déclarée qu'une seule fois.
S'il existe un conflit entre les déclarations de la référence, un message d'erreur est émis et l'application ne démarre pas. Un message d'avertissement est émis pour chaque référence en conflit. Le message d'avertissement indique le nom de la référence conflictuelle et les valeurs affectées à la référence. Une fois que tous les messages d'avertissement ont été émis, une exception est lancée.
- Emplacement des fichiers descripteurs d'EJB
Le fichier descripteur de déploiement ejb-jar.xml et n'importe quel autre fichier descripteur doivent être remplacés dans le répertoire WEB-INF du module WAR. Toute instance d'un descripteur d'EJB située ailleurs dans le fichier WAR, y compris dans le répertoire META-INF d'un fichier JAR placé lui-même dans le répertoire WEB-INF/lib, sera ignorée.
- Déterminer si les annotations sont examinées
Les règles déterminant s'il faut ou non rechercher et examiner des annotations sont différentes selon que l'EJB est dans son propre JAR d'EJB ou qu'il est contenu dans un module WAR. Pour connaître l'ensemble complet des règles, voir la rubrique intitulée Empaquetage des modules EJB 3.x - Vue d'ensemble.
- Chargement de classe et visibilité
Le modèle d'utilisation le plus courant pour les classes EJB regroupées dans un module WAR sont des appels de méthodes locaux à partir des composants Web regroupés dans le même module. Toutefois, ces classes EJB sont aussi accessibles par des appels de méthodes distantes ou par des clients dans d'autres modules. Dans ce cas, il est important de comprendre les règles de visibilité des classes EJB regroupées dans un module WAR. Les règles de visibilité sont différentes comparées aux classes EJB regroupées dans un modules JAR.
Dans le cas des appels de méthodes EJB distants, il n'existe pas de différences de visibilité générées par le regroupement des classes EJB dans un module WAR. Les beans EJB sont liés dans l'espace de nom global et peuvent être recherchés depuis ou injectés dans des composants dans d'autres modules. Le client distant doit effectuer des appels de méthode avec une classe de module de remplacement appropriée. La génération de classe de module de remplacement est décrite dans la rubrique sous la section relative à la génération de module de remplacement.
Dans le cas des appels de méthode EJB locaux à partir de composants dans d'autres modules, il existe des différences de visibilité, car les beans EJB sont regroupés dans un module WAR. Ces différences résultent des implications de chargeur de classe qui doivent être prises en compte.
Le contenu qui est regroupé dans tous les modules JAR EJB pour l'ensemble de l'application est chargé par une seule instance de charge de classe d'application.
A l'inverse, tout le contenu empaqueté dans un module WAR est chargé par une instance de chargeur de classe qui est spécifique à ce module WAR. L'instance de chargeur de classe d'application utilisée pour charger tout le contenu JAR EJB est le parent de chaque instance de chargeur de classe utilisée pour charger le contenu WAR.
La visibilité d'une classe est affectée par l'instance de chargeur de classe qui l'a chargée. Une instance de chargeur de classe peut voir les classes qu'elle a chargées elle-même ou qui ont été chargées par un chargeur de classe parent. En revanche, un chargeur de classe ne peut pas voir une classe qu'il n'a pas lui-même chargée et qui n'a pas non plus été chargée par son parent.
En conséquence, les classes chargées par le chargeur spécifique d'un module WAR peuvent voir les classes dans un module JAR d'EJB (puisqu'elles ont été chargées par l'unique instance de chargeur de l'application), mais elles ne peuvent pas voir les classes situées dans un autre module WAR. Les classes dans un module JAR d'EJB ne peuvent voir aucune des classes dans un module WAR quel qu'il soit. Par exemple, si du contenu EJB est regroupé dans le module JAR EJB ejb3.jar et que du contenu EIB se trouve également dans le fichier ejb1.jar et le fichier ejb2.jar :- Si les fichiers ejb1.jar et ejb2.jar sont tous deux installés comme modules JAR d'EJB, alors leur contenu, ainsi que celui du fichier ejb3.jar, est chargé par la même instance de chargeur de classe, qui est aussi utilisée pour charger tous les autres modules JAR d'EJB dans l'application. Dans ce cas, les classes dans les trois fichiers JAR se voient entre elles, car elles sont toutes chargées par la même instance de chargeur de classe.
- Si le fichier ejb1.jar et le fichier ejb2.jar se trouvent dans le répertoire WEB-INF/lib d'un fichier WAR, le contenu dans les fichiers ejb1.jar et ejb2.jar est chargé par une seule instance de chargeur de classe. Toutefois, ce chargeur n'est pas celui utilisé pour charger le contenu du fichier ejb3.jar et tout autre JAR EJB dans l'application. Dans ce cas, les classes dans les fichiers ejb1.jar et ejb2.jar se voient mutuellement et peuvent aussi voir les classes dans le fichier ejb3.jar. Les classes dans le fichier ejb3.jar ne peuvent pas voir les classes dans le fichier ejb1.jar ou ejb2.jar.
- Si le fichier ejb1.jar se trouve dans le répertoire WEB-INF/lib du fichier firstWar.war et que le fichier ejb2.jar se trouve dans le répertoire WEB-INF/lib du fichier secondWar.war,le contenu dans le fichier ejb1.jar est chargé dans une instance de chargeur de classe, le contenu dans le fichier ejb2.jar est chargé dans une seconde instance de chargeur de classe et le contenu dans le fichier ejb3.jar et tout autre JAR EJB dans l'application est chargé dans une troisième instance de chargeur de classe. Dans ce cas, les classes dans les fichiers ejb1.jar et ejb2.jar ne se voient pas entre elles, mais elles peuvent voir les classes dans le fichier ejb3.jar. Les classes dans le fichier ejb3.jar ne peuvent pas voir les classes dans ejb1.jar ni celles dans ejb2.jar.
Une stratégie pour éviter ces complications de chargeur de classe consiste à regrouper les classes d'interface EJB dans une bibliothèque partagée.Pratiques recommandées: Ne regroupez pas la même classe, un module JAR EJB et une module WAR, dans la même application. La présence de plusieurs exemplaires de la même classe en différents endroits de l'application est source de confusion, car il est difficile de savoir quelle instance de la classe sera chargée et utilisée à l'exécution. Cette distinction peut être importante si les deux fichiers .class représentent des versions différentes de la classe. Pour éviter cette situation, placez le fichier .class dans un seul endroit ou changez la structure de package de la classe pour que le nom qualifié complet de la classe dans le module WAR soit différent de celui qui figure dans le module JAR EJB.bprac
- Extension de profil d'application
L'extension de profil d'application n'est pas prise en charge pour les classes EJB regroupées dans des modules WAR.
Génération de modules de remplacement
L'accès distant aux méthodes d'EJB nécessite l'emploi, côté client, de classes dites de module de remplacement. Pour la plupart des environnements, l'environnement d'exécution du produit génère les classes de module de remplacement nécessaires. La seule exception est l'environnement client léger. Pour les clients légers, les classes de module de remplacement doivent être générées manuellement et regroupées avec le client.
Utilisez l'outil createEJBStubs pour générer des modules de remplacement lorsque le contenu EJB se trouve dans un module WAR, quelle que soit la version EJB.
Voir la rubrique relative à la commande de création de modules de remplacement pour plus d'informations.

Contenus EJB 2.x et 1.x dans un module WAR
Les contenus EJB 2.x et 1.x sont acceptés dans un module WAR, sauf s'il s'agit de beans entity.
Un module 2.x ou 1.x placé dans un fichier WAR nécessite un descripteur de déploiement ejb-jar.xml 2.x ou 1.x dans le répertoire WEB-INF du module WAR. Si les fichiers de liaisons et d'extension XMI existent, vous devez aussi les regrouper dans le répertoire WEB-INF d'un module WAR.
Les beans de session et de message (MDB) que vous implémentez selon les règles de codage 2.x ou 1.x peuvent être empaquetés dans un module WAR.
Les beans entity, qu'ils soient BMP ou CMP, ne sont pas admis dans un module WAR.
Le profilage d'application et les services de tentative d'accès ne sont pas pris en charge dans un module WAR. Les beans session dans un module WAR ne peuvent pas accéder aux tâches de profilage d'application.
Le contenu EJB que vous implémentez en fonction du type de codage 3.x et des types de codage 2.x et 1.x, peut être regroupé dans un seul module WAR. Toutefois, dans ce cas, vous devez déclarer les informations de liaisons et d'extensions avec la version XML des fichiers et non pas la version XMI.
Transférer le contenu existant de modules JAR d'EJB vers des modules WAR
Une méthode consiste à placer le fichier JAR EJB dans le répertoire WEB-INF/lib du fichier WAR. Ensuite, supprimez les fichiers descripteurs du répertoire META-INF du fichier JAR et placez-le dans le répertoire WEB-INF du fichier WAR.
Une seconde approche consiste à prendre les fichiers de classe directement dans le JAR d'EJB et à les placer au bon endroit, sous le répertoire WEB-INF/classes du module WAR. Ensuite, supprimez les fichiers descripteurs du répertoire META-INF du fichier JAR et placez-les dans le répertoire WEB-INF du fichier WAR.
Si vous transférez plusieurs modules JAR d'EJB dans un même module WAR, vous devez fusionner le contenu de leurs descripteurs respectifs, auparavant situés dans leurs répertoires META-INF respectifs, dans la seule et unique version de chaque type de descripteur à présent située dans le répertoire WEB-INF du module WAR. Exemples de fichiers descripteurs qui peuvent être fusionnés incluent, sans s'y limiter, ejb-jar.xml, ibm-ejb-jar-bnd.xml, ibm-ejb-jar-ext.xml, et ibm-ejb-jar-ext-pme.xml.
Pour garantir l'absence de conflits entre les divers composants du module WAR, qu'il s'agisse d'EJB ou non, vous devez inspecter les références qu'ils déclarent, car n'oubliez pas qu'ils partagent tous un seul et même espace de nom.
Vous devez modifier les fichiers XMI de liaisons et d'extensions transférés d'un module JAR EJB vers un module WAR dans plusieurs emplacements pour supprimer les références à META-INF/ejb-jar.xml et les remplacer par WEB-INF/ejb-jar.xml.
Fonction EJB prise en charge dans les modules JAR d'EJB, mais non dans les modules WAR
- Beans entity BMP et CMP
- Les beans de démarrage codés selon les règles antérieures à EJB 3.1Avertissement : Les beans de démarrage singleton définis par la spécification EJB 3.1 sont acceptés.
CWMDF0025E: Entity beans in EJB web application archive (WAR) modules are not allowed, per the EJB 3.1 specification.
WSVR0039E: Unable to start EJB JAR, foo.war: Entity beans in EJB web application archive (WAR) modules are not allowed, per the EJB 3.1 specification. Le bean foo du module foo.war doit être déplacé vers un module EJB autonome. Recherchez dans le journal la liste complète des beans entity non valides dans un module WAR.