Développement, déploiement et sécurisation d'applications JEE

Dimension: px
Commencer à balayer dès la page:

Download "Développement, déploiement et sécurisation d'applications JEE"

Transcription

1 JBoss Développement, déploiement et sécurisation d'applications JEE Franck SIMON Résumé Ce livre sur JBoss s'adresse aux développeurs Java quotidiennement confrontés au développement et au déploiement d'applications distribuées, que ce soient des applications Web, des reprises de projets en EJB 2 ou de nouveaux projets en EJB 3. JBoss est devenu un serveur d'applications incontournable dans le monde Java et ce livre présente de manière pratique le déploiement et la sécurisation des applications sous JBoss, en tenant compte des différentes versions des spécifications Sun : Servlet / JSP, EJB 2 pour les projets existants et EJB 3 pour les nouveaux projets. Le livre commence par un rappel sur l'architecture JEE, puis se poursuit sur l'installation de JBoss. Les services fondamentaux de JBoss utilisés par les applications distribuées y sont présentés et expliqués. L'auteur décrit l'architecture interne de JBoss et présente les principaux services : JMX, JNDI, JMS, JTA, JCA, JAAS. Les chapitres suivants décrivent les principes de fonctionnement et de codage des composants EJB2, EJB3, servlet/jsp. Le déploiement et l'empaquetage de ces composants sous JBoss sont commentés et illustrés par des exemples qui sont disponibles en téléchargement. La gestion des transactions et de la sécurité font l'objet de chapitres à part entière. Après le développement et le déploiement... l'administration de JBoss est présentée : la console JMX, l'instanciation de plusieurs instances, la mise en cluster, configuration avec Apache mod_jk. Le dernier chapitre présente l'intégration de JBoss à Eclipse et notamment comment intégrer dans Eclipse les exemples téléchargeables. Des exemples sont en téléchargement sur cette page. L'auteur Ingénieur conseil, Franck Simon exerce en tant qu'indépendant depuis Consultant et développeur sur les technologies Java/JEE, il intervient régulièrement sur des développements autour des technologies Java/JEE et la variété de ses missions dans ce domaine l'ont conduit à écrire un livre véritablement opérationnel sur JBoss. Ce livre numérique a été conçu et est diffusé dans le respect des droits d auteur. Toutes les marques citées ont été déposées par leur éditeur respectif. La loi du 11 Mars 1957 n autorisant aux termes des alinéas 2 et 3 de l article 41, d une part, que les copies ou reproductions strictement réservées à l usage privé du copiste et non destinées à une utilisation collective, et, d autre part, que les analyses et les courtes citations dans un but d exemple et d illustration, toute représentation ou reproduction intégrale, ou partielle, faite sans le consentement de l auteur ou de ses ayants droit ou ayant cause, est illicite (alinéa 1er de l article 40). Cette représentation ou reproduction, par quelque procédé que ce soit, constituerait donc une contrefaçon sanctionnée par les articles 425 et suivants du Code Pénal. Copyright Editions ENI ENI Editions - All rigths reserved - Kaiss Tag - 1 -

2 Les exemples cités tout au long de cet ouvrage sont téléchargeables à l'adresse suivante : Saisissez la référence ENI de l'ouvrage EI4JBOS dans la zone de recherche et validez. Cliquez sur le titre du livre puis sur le lien de téléchargement. Chapitre 1 Introduction 1. Introduction Architecture des applications distribuées L'invocation de méthodes distantes : RMI Rappels sur XML Rappels sur J2EE Rappels sur JEE Les annotations Injection par proxy Présentation du serveur d'applications JBoss...34 Chapitre 2 Installation de JBoss 1. Téléchargement Téléchargement de JBoss Installation de JBoss Structure des répertoires Structure du répertoire de type server Démarrer et arrêter le serveur Sous Windows Sous Ubuntu Suivi du démarrage Test de JBoss Arrêt de JBoss Arrêt et démarrage des autres configurations serveur Pour lancer le serveur minimal Pour lancer la configuration all...52

3 2 JBoss Déploiement et sécurisation d'applications JEE 5. Déploiement et repli des applications JEE Exemple de déploiement d'un EJB Exemple de déploiement d'une application Web Exemple de déploiement d'une application d'entreprise Retrait d'une application...59 Chapitre 3 Architecture de JBoss 1. Noyau du serveur Présentation de la spécification JMX La couche instrumentation : l'interface HelloMBean La couche instrumentation : implémentation du MBean La couche Agent La couche distribuée : jconsole Supervision : notification d'événement Implémentation de JMX dans JBoss Processus de démarrage de JBoss Le fichier jboss-service.xml Propriétés utilisables dans les fichiers de configuration JBoss Propriétés de démarrage Propriétés représentant des URLs ou des répertoires Propriétés de configuration Connexion au serveur JMX de JBoss Connexion par la console web : JMX Agent View Connexion par la console web : sécurisation Connexion par l'outil twiddle Connexion par RMI Service de nommage JNDI Présentation de JNDI Les noms Les noms atomiques Les associations Le contexte L'ENC (Environment Naming Context) Niveau de visibilité des contextes JNDI sous JBoss...88

4 Table des matières Console de visualisation JNDI Le service de nommage de JBoss : JBossNS Contexte de nommage standard Nommage JNDI des composants déployés sous JBoss Nommage JNDI par défaut Utilisation de jboss.xml Référencement de composants avec <ejb-ref> Référencement dans le fichier ejb-jar.xml Services de déploiement Conteneur Web Fichier de configuration jboss-service.xml Fichier de configuration server.xml Fichier de configuration web.xml Fichier de configuration context.xml Gestion des ressources statiques Service de messagerie JMS Mode point à point Mode publication/abonnement Spécification JMS Modèle de programmation JMS Les EJB orientés message Service de transaction JTA Service de connecteurs JCA Service de sécurité JAAS Autres services utiles Service de suivi des threads et de la mémoire Service Mail Service Log4j TimerService Service de planification Fichiers de configuration du serveur

5 4 JBoss Déploiement et sécurisation d'applications JEE Chapitre 4 Tiers de persistance 1. Persistance des objets Codage du pattern DAO Source de données et pool de connexion Autre modèles de conception de la couche de persistance Paramétrage des sources de données Principaux éléments du fichier de configuration Éléments de base Principaux éléments de configuration des sources de données Hibernate Chapitre 5 Déploiement d'applications Web 1. Introduction aux applications Web Protocole HTTP Architecture Web pour J2EE/JEE Configuration du conteneur Web Les servlets LesJSP Cycle de vie d'une JSP Les descripteurs de déploiement Descripteur de déploiement standard web.xml Descripteur de déploiement spécifique jboss-web.xml Nom de l'application Association de ressources Les hôtes virtuels...167

6 Table des matières 5 Chapitre 6 Déploiement des EJB 1. Configuration du conteneur d'ejb Déploiement des EJB Packaging Packaging en module EJB Packaging dans une application d'entreprise Déploiement Descripteurs de déploiements Descripteur de déploiement standard ejb-jar.xml Descripteur de déploiement spécifique jboss.xml Descripteur de déploiement application.xml Outils d'aide au codage des EJB EJB2 de session stateless statefull EJB2 entité CMP BMP EJB2 orienté message Déploiement des EJB Utilisation des annotations EJB3 de session stateless statefull EJB3 entité Mapping avec la base de données Unité de persistance Attachement et détachement au contexte de persistance Principe du chargement "paresseux" EJB3 orienté message Utilisation des EJB Utilisation par une application Web Utilisation par une application non Web

7 6 JBoss Déploiement et sécurisation d'applications JEE Chapitre 7 Gestion des transactions 1. Introduction Utilisation des transactions Modèles des transactions Gestion programmée des transactions Gestion programmée des transactions en EJB Gestion programmée des transactions en EJB Gestion déclarative des transactions Gestion déclarative des transactions en EJB Gestion déclarative des transactions en EJB Gestion des transactions initiées par le client Chapitre 8 Gestion de la sécurité 1. Introduction Introduction aux techniques de chiffrement Chiffrement symétrique Chiffrement asymétrique Le certificat Notion de clé de session Principe Introduction à JAAS Les concepts clés de JAAS Les classes de base de JAAS Les classes d'authentification des JAAS Exemple d'une implémentation d'authentification personnalisée Le gestionnaire de sécurité JBossSX LoginModule de JBoss Configuration du domaine de sécurité Sécurisation d'une application Web Mise en place de HTTPS Création du certificat numérique Configuration du fichier server.xml

8 Table des matières Définition de la méthode d'authentification Définition du domaine de sécurité Déclaration des contraintes Présentation de l'exemple de base Mise en place du domaine de sécurité de base Mise en place de la méthode d'authentification Mise en place des contraintes de sécurité Déclaration des rôles utilisés Authentification de type DIGEST Méthode d'authentification de type FORM Méthode de sécurisation par certification mutuelle Accès aux EJB Gestion des autorisations sur les EJB Gestion des autorisations sur les EJB Chapitre 9 Configuration en mode Cluster 1. Instancier plusieurs serveurs sur une même machine Fichier sample-bindings.xml Copie d'une configuration de base Changement des configurations serveurs Démarrage des serveurs Mise en cluster de plusieurs serveurs La répartition de charge Lancement du cluster Déploiement d'application Service HTTP Installation du module mod_jk Pré-requis : serveur HTTP Apache Téléchargement du module Configuration du module mod_jk Configuration des nœuds dans mod_jk Configuration de JBoss Test final...344

9 8 JBoss Déploiement et sécurisation d'applications JEE Chapitre 10 Produits supplémentaires 1. JBoss RichFaces Paramétrage et utilisation d'eclipse Paramétrage d'eclipse Déploiement d'un projet à partir d'eclipse Import de projet existant dans votre espace de travail Créer un nouveau projet Projet EJB Projet EJB Projet Web Projet d'entreprise Création d'une archive Résoudre quelques problèmes courants Erreurs suite à un import Certaines vues ne sont pas disponibles Index...385

10 Introduction Nous ferons dans certains chapitres, dont celui ci, un certain nombre de rappels sur les technologies J2EE et JEE pour : bien préciser quels impacts ont les spécifications de ces technologies sur le serveur JBoss ; présenter les choix possibles de codage et les déploiements qui en découlent ; comprendre quels types d erreurs peuvent arriver lors d un déploiement et comment les corriger. Mais le sujet de ce livre n est pas le codage des EJB, servlet et JSP. Il en présente les principes, et est illustré de nombreux exemples, mais ne va pas aider le lecteur dans ces choix d implémentation. Par contre, cet ouvrage présente les services les plus importants de JBoss, leur fonctionnement, leur configuration, pour que le lecteur puisse en tirer le meilleur parti. JBoss étant un serveur d application obéissant aux spécifications JEE, il faut évidemment comprendre les cycles de vie des objets qui seront pris en charge par les différents conteneurs. Nous avons été souvent confrontés à des développeurs qui ont des connaissances de base dans le langage Java et dans les technologies J2EE/JEE, mais qui étaient décontenancés devant les problèmes de déploiement, de maintenance et de reprise de projets sous les serveurs d application dont JBoss. Nous espérons que cet ouvrage satisfera leur curiosité et les poussera à aller plus loin. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

11 Architecture des applications distribuées Les applications informatiques ont pris une place centrale dans la plupart des entreprises. Les premières applications étaient monolithiques, d une seule pièce. Ce type d architecture se prête mal à la demande des entreprises. L entreprise va demander à l application informatique de lui fournir de nouveaux services en fonction de l évolution de son environnement. Il est complexe d ajouter de nouvelles fonctionnalités à une application monolithique, sans provoquer une régression de certaines parties du code. De plus, Internet a révolutionné le besoin de connectivité vis à vis de l entreprise. En quelques années, les équipes de conception logicielle ont dû revoir leur mode de travail : connectivité, modélisation objet, utilisation de frameworks, etc. L architecture des applications d entreprise a largement évolué car le mode d utilisation de ses applications a changé. De nombreux postes informatiques sont maintenant reliés en réseau, ce qui permet à plusieurs salariés de travailler sur la même application. Des succursales de l entreprise peuvent se connecter sur l application, via Internet, pour gérer des données techniques, suivre les statistiques de ventes, effectuer des saisies, etc. Les clients de l entreprise peuvent avoir accès, via son site web, à des données les concernant : factures, vérification de leurs cordonnées, changement de compte bancaire Ils peuvent aussi être prévenus par SMS ou mail du suivi de leur commande, état de leur compte Les concepteurs d applications doivent faire face à plusieurs défis : des types variés de moyens de saisie et d affichage de l information : clients lourds, navigateurs, téléphone mobile des fonctionnalités qui évoluent : de nouveaux traitements doivent être ajoutés, des modifications de règles législatives, de nouveaux services client des règles de sécurité différentes pour les salariés, les succursales, les clients finaux, les partenaires Internet qui a considérablement modifié l architecture avec l utilisation de serveurs web, un nombre de connexions difficile à prévoir, la gestion des montées en charges, les connexions aux bases de données La conception d une application amène à réfléchir sur : ce qui est du domaine du métier de l entreprise : gestion des clients, de la fabrication, des stocks ce qui est du domaine du support de l application : base de données, gestion de la sécurité, transactions, réseau Il faut remarquer que ces derniers points sont communs à toutes les applications. Une architecture en couche permet de mieux maîtriser l évolution de l application, que ce soit au niveau fonctionnel, ou au niveau logique. Le développeur n a pas à se soucier du codage des contextes de transactions ou de ceux de l authentification et sécurisation. Toutes ces fonctionnalités, présentes quelle que soit l application et transversales aux couches applicatives, sont mises à disposition par le serveur. Il peut se consacrer au développement métier en utilisant les services précédemment décrits. Sun, via la plate forme JEE (Java Enterprise Edition), a mis en place une standardisation de ses services et la manière de les utiliser. Le développeur pourra se consacrer au codage des couches de présentation et métier, grâce à des ENI Editions - All rigths reserved - Kaiss Tag - 1 -

12 composants pris en charge par le serveur d application. Ces composants sont principalement : Les servlets, qui décodent les en têtes des requêtes HTTP et codent les en têtes de réponses HTTP, gèrent les sessions HTTP, mettent à disposition du développeur des objets prenant en charge le cycle de vie de l application Web. Les servlets sont complétées par d autres composants et technologies : les JSP (Java Server Page), les balises personnalisées, l EL (Expression Language), les JSF (Java Server Face)... Ces composants sont pris en charge par le serveur Web. Les EJB (Enterprise Java Bean) qui sont des composants dont le cycle de vie est géré par le conteneur d EJBs. Le conteneur va, par ces composants, gérer les objets et services métier, la persistance, l envoi et la réception de messages, les transactions... Le développeur doit se préoccuper uniquement de la logique métier : comment calculer la facture gérer un panier d achat Le conteneur prend en charge les aspects comme la sécurité ou les transactions. l utilisateur a t il le droit de calculer la facture? le paiment n est pas validé sur le panier d achat si un problème réseau survient. Il existe deux grandes spécifications pour les EJB : celle des EJB 2 liée à J2EE, et celle des EJB 3 liée à JEE. La connaissance de ces deux spécifications est actuellement nécessaire car un certain nombre de projets ayant vu le jour avant les EJB 3, il faut donc continuer à les faire vivre, les déployer et les administrer. Les technologies incluses dans JEE permettent, entre autres : la communication entre objets ; la gestion des objets de réponses aux requêtes HTTP ; la gestion des transactions ; ENI Editions - All rigths reserved - Kaiss Tag

13 la persistance des objets avec les EJB entité ; la communication asynchrone par message avec les EJB orienté message ; la réalisation d interface graphique ; la gestion de la sécurité ; la gestion de la répartition de charge. Un serveur d application JEE peut être vu comme la réunion : d un conteneur Web qui gère le cycle de vie des servlets et JSP ; d un conteneur EJB qui gère le cycle de vie des objets métier ; d un ensemble de services : accès aux bases de données, gestion des transactions 1. L invocation de méthodes distantes : RMI Les objets des différentes couches sont susceptibles d être invoqués par des objets situés sur une autre machine virtuelle. L objet dont les méthodes peuvent être invoquées, est dit "objet serveur", l objet invoquant les méthodes de l objet serveur est dit "objet client". Il est évident que dans la réalité, les objets sont couramment serveur et client. L invocation directe d une méthode dans une même machine virtuelle est simple : il s agit d un appel en mémoire vers une adresse, les arguments de la méthode appelée et sa valeur de retour sont passés en tant que références. C est simple, efficace et rapide. MonCalendrier cal = new MonCalendrier(); Integer annee = new Integer(2008); Date paques = cal.getdatepaques(annee); L invocation d une méthode d un objet situé dans une machine virtuelle différente est plus complexe. Nous n avons comme lien entre les deux machines virtuelles que le réseau, sous protocole TCP/IP. Il faut donc : connaître l IP de la machine où se trouve l objet serveur ; que l objet serveur soit à l écoute des demandes sur un socket de type serveur ; ENI Editions - All rigths reserved - Kaiss Tag - 3 -

14 que l objet client initie une demande vers l objet serveur via un socket ; que les échanges soient effectués sur un protocole commun. Donc, nous sommes loin de l utilisation de l opérateur point (.) pour invoquer la méthode distante. Le développeur passera sûrement plus de temps à élaborer un protocole de communication entre objets, qu à se consacrer à l écriture de son application! Heureusement, nous pouvons utiliser la technologie RMI (Remote Method Invocation) qui va masquer, pour nous, l ensemble des opérations décrites ci dessus. Une interface expose les méthodes distantes. Elle est implémentée par l objet serveur et est utilisée par l objet client. RMI est construit sur trois couches. La première couche comprenant les stubs et skeletons est une couche proxy, ce qui permet au développeur de ne pas connaître les détails d implémentation de RMI et d utiliser l opérateur point (.) pour l invocation de la méthode distante. La classe stub, côté client, est créée par le compilateur rmic, présent dans le répertoire bin du JDK. Cette classe va sérialiser les paramètres passés à la méthode distante, et désérialiser la valeur de retour de la méthode distante. La classe skeleton, côté serveur, est chargée de désérialiser les paramètres reçus pour les transmettre à la méthode appelée, et de sérialiser la valeur de retour. Il faut donc que les classes des paramètres et de la valeur de retour soient sérialisables. Le passage des paramètres se fait alors par copie et non par référence. La seconde couche, RRL (Remote Reference Layer), est chargée de la localisation de l objet distant. Elle permet d obtenir une référence à l objet distant, à partir de la référence locale (le stub). Ce service est lié à un service de nommage, qui peut être un service JNDI (Java Naming and Directory Interface) ou un service de base appelé RMI registry, lancé avec la commande rmiregisty, situé dans le répertoire bin du JDK. La troisième couche de transport est basée sur TCP/IP. Cette couche utilise les classes Socket et SocketServer. La compréhension de RMI est primordiale pour aborder les applications distribuées en Java car RMI est utilisé pour la communication avec les EJB. Il faut noter qu il existe des différences notables entre l implémentation de RMI dans le JDK 1.1 et dans JDK 1.5. Les lecteurs intéressés pourront trouver plus de renseignements sur le site de Sun (http://java.sun.com). Le processus de développement d une application RMI est le suivant : définir l interface exposant les méthodes distantes ; implémenter les méthodes distantes ; développer le client ; compiler les classes ; générer les classes stub avec rmic ; lancerrmiregistry ; lancer l application serveur ; lancer l application cliente. L ensemble des sources peut être téléchargé sur le site ENI. L archive téléchargée est composée de plusieurs projets Eclipse qui vous permettront de tester les configurations proposées. Ces projets illustrent les différents points abordés dans cet ouvrage, et vous permettront de tester au fur et à mesure de la lecture les concepts abordés. Le projet comporte trois classes : ENI Editions - All rigths reserved - Kaiss Tag

15 ITime qui est l interface exposant la méthode qui peut être appelée par RMI : getdate() ; TimeServeur qui est l implémentation de ITime, et qui possède une méthode main() permettant de lancer le serveur ; TimeClient qui invoque la méthode distante. L ensemble de ces classes est volontairement simple et sans package, afin de faciliter l utilisation en ligne de commande. L interface ITime se présente ainsi : import java.rmi.*; import java.util.*; public interface ITime extends Remote public Date getdate() throws RemoteException; La méthode distante est susceptible de déclencher une RemoteException. L interface, qui expose nos méthodes métier, doit étendre l interface java.rmi.remote. La classe d implémentation TimeServeur se présente ainsi : import java.rmi.*; import java.rmi.server.*; import java.util.*; public class TimeServeur extends UnicastRemoteObject implements Itime public TimeServeur() throws RemoteException super(); public Date getdate() log(); return new Date(); public static void main(string[] args) System.out.println("SERVEUR DEMARRE"); try ITime time = new TimeServeur(); Naming.rebind("TimeServeur", time); catch (Exception e) System.out.println("ERREUR : " + e); private void log() try System.out.println("Connexion du client : " + getclienthost()); catch (Exception e) System.out.println("ERREUR : "+e); ENI Editions - All rigths reserved - Kaiss Tag - 5 -

16 La classe d implémentation doit étendre la classe java.rmi.server.unicastremoteobject qui permet l export du stub, qui communiquera avec l objet distant. La méthode main(...) de la classe permet l inscription de l instance de TimeServeur auprès du service de nommage, qui aura été lancé via rmiregistry. Cette inscription s effectue par l instruction Naming.rebind("TimeServeur", time), qui va lier l instance time à la chaîne de caractère "TimeServeur". Ainsi, le client pourra récupérer, auprès du service de nommage, une instance de type ITime par la clé "TimeServeur". L implémentation de la méthode getdate() ne fait que renvoyer la date système et appeler une méthode log(), qui affichera sur la console du serveur, les informations de connexion du client. La classe cliente TimeClient se présente ainsi : import java.rmi.*; import java.util.*; public class TimeClient public static void main ( String[] args ) try ITime service = (Itime) Naming.lookup("rmi://localhost/TimeServeur"); Date serverdate = service.getdate(); System.out.println("ServiceTime : " + serverdate); catch (Exception e) System.out.println("\nErreur\n" + e); Cette classe recherche, auprès du service de nommage, un stub du type ITime. Les méthodes main(...) des classes TimeServeur et TimeClient seront lancées dans des JVM différentes, donc, des consoles différentes. Le lancement d une console en ligne de commande s effectue, sous Windows, par le menu démarrer Exécuter, puis en entrant cmd. Ce lancement peut aussi s effectuer par démarrer Accessoires... Le lancement d une console, sous Ubuntu, s effectue par Application Accessoires Terminal. Ouvrez une première console pour la compilation et la génération du stub. Les classes sont compilées avec javac, puis le stub de la classe TimeServeur est généré avec rmic. L exécution de ses deux lignes est effectuée dans le même répertoire que les classes. Vérifiez que votre variable PATH contienne le répertoire bin du JDK installé sur votre machine. javac *.java rmic TimeServeur Un fichier TimeServeur_Stub.class a été créé par rmic. Vous trouverez ce fichier avec les autres classes générées par javac. Avant de lancer le serveur, il faut lancer le service de nommage. Pour cela, ouvrez une nouvelle console puis exécutez la commande rmiregistry. start remiregistry Dans une nouvelle console, vous pouvez maintenant lancer le serveur. java TimeServeur Le lancement du serveur permet d enregistrer la classe TimeServeur auprès du service de nommage, grâce à la méthode rebind( ) de la classe Naming. Il faut noter qu il existe aussi, une méthode bind( ) qui permet l enregistrement d un objet ; la méthode rebind( ) permettant, en plus, de remplacer l objet déjà existant. public static void main(string[] args) System.out.println("SERVEUR DEMARRE"); try ENI Editions - All rigths reserved - Kaiss Tag

17 ITime time = new TimeServeur(); Naming.rebind("TimeServeur", time); catch (Exception e) System.out.println("ERREUR : " + e); Dans une autre console, vous pouvez maintenant lancer l application cliente. java TimeClient Le client peut maintenant récupérer une référence vers l objet distant par un Naming.lookup() et l utiliser. public static void main ( String[] args ) try ITime service = (Itime) Naming.lookup("rmi://localhost/TimeServeur"); Date serverdate = service.getdate(); System.out.println("ServiceTime : " + serverdate); catch (Exception e) System.out.println("\nErreur\n" + e); La méthode lookup() attend une URL du type : rmi://<hote>[<:port>]/<nom_du_service> où <hote> identifie une machine sur le réseau par son nom ou son adresse IP, par défaut, le port est en Ici, localhost est utilisé car les tests sont effectués sur une même machine. Le schéma suivant résume les appels effectués. Il faut toujours avoir présent à l esprit qu un appel d une méthode par RMI est plus consommateur de ressources et moins optimisé qu un appel direct de la méthode au sein de la même machine virtuelle. Par RMI, les valeurs des paramètres envoyés à la méthode sont passées par copie, via la sérialisation. Il en est de même pour les valeurs de retour des méthodes. Lors d un appel direct, ces mêmes valeurs auraient été passées par valeur. De plus, un appel au sein de la mémoire de la machine virtuelle sera toujours plus rapide qu un appel via le réseau. Ce constat n est pas sans conséquence pour la technologie des EJB 2, comme nous pourrons le voir par la suite. ENI Editions - All rigths reserved - Kaiss Tag - 7 -

18 Rappels sur XML Nous allons utiliser XML dans tous les descripteurs de déploiement, aussi nous allons voir brièvement les caractéristiques de cette spécification. Pour plus de précisions, reportez vous aux spécifications XML gérées par le consortium W3C. XML (extensible Markup Language) est un langage à base de balises. Les balises XML décrivent des contenus. L objectif est de structurer le document, ce que ne fait pas HTML, qui décrit comment présenter le document dans un navigateur. Un élément XML est structuré de la manière suivante : <nom age="25"> Toto </nom> => balise ouvrante => corps => balise fermante une balise ouvrante : ici, la balise nom. Le nom de la balise est libre, il peut être fixé par un schéma. La balise ouvrante est encadrée des signes inférieur (<) et supérieur (>). des attributs et leur valeur : ici, nous n avons qu un attribut age. Le signe égal sépare l attribut et sa valeur, la valeur d un attribut doit être entre guillemets (") ou apostrophe ( ). Les attributs ne sont pas obligatoires. Ils n apparaissent que dans la balise d ouverture. le corps de l élément : ici, Toto. Le corps de l élément peut être vide, contenir un élément fils, du texte ou un élément fils et du texte. la balise fermante, qui reprend le nom de la balise ouvrante précédée par le signe barre oblique (/). Elle ne comporte pas d attributs. Elle est encadrée des signes inférieur (<) et supérieur (>). les noms de balises ne peuvent pas comporter d espace et commencer par un chiffre. Toute balise ouvrante doit être fermée. Un élément qui ne comporte pas de corps peut être fermé directement. <br></br> est équivalent à <br /> Tout document XML doit comporter un élément racine. Un document XML vide est un document dont l élément racine est vide, et non pas un fichier vide. <server> </server> XML est sensible à la casse, les différences minuscule/majuscule sont prises en compte. L exemple suivant est incorrect : <nom> </NOM> Pour éviter l analyse de certaines parties du document, le texte libre est mis dans des sections CDATA qui débutent par <![CDATA[ et finissent par ]]>. <description> <![CDATA[Chap 2 - Calculette EJB2 generated by eclipse wtp xdoclet extension.]]> </description> Les éléments ne peuvent pas se chevaucher. L exemple suivant est incorrect : <balise1> <balise2> </balise1> </balise2> Les commentaires XML commencent par <!-- et finissent par -->. <!-- commentaire valide --> ENI Editions - All rigths reserved - Kaiss Tag - 1 -

19 Les éléments peuvent être mis en commentaire. Dans l exemple suivant, l élément <session> n est plus pris en compte. <!-- --> <session> <ejb-name>calculette</ejb-name> <jndi-name>ejb2/calculette/remote</jndi-name> <local-jndi-name>ejb2/calculette/local</local-jndi-name> <method-attributes> </method-attributes> </session> Attention : les commentaires ne peuvent pas être imbriqués, ce qui peut arriver lorsque vous mettez en commentaire des parties de fichier de configuration. <!-- <session> <ejb-name>calculette</ejb-name> <jndi-name>ejb2/calculette/remote</jndi-name> <local-jndi-name>ejb2/calculette/local</local-jndi-name> <method-attributes> </method-attributes> </session> <!-- write a merge file jboss-webservices.ent for webservice-description --> </enterprise-beans> --> Si l ensemble de ces règles est observé, le document XML est dit "bien formé" (well formed). Les documents XML sont analysés par des outils appelés parseurs (parsers). Les spécifications Sun et JBoss imposent un vocabulaire pour les noms de balises et d attributs. Ces mêmes spécifications imposent aussi l ordre d apparition des balises, leur nombre, le caractère obligatoire ou non d un attribut... Ces spécifications sont appelées schéma. Il en existe deux types : les DTD (Document Type Description), les plus simples ; les XMLSchemas, plus complexes mais beaucoup plus riches. Vous retrouverez les schémas en en tête des fichiers XML. Mise en place d une DTD : <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd"> <jboss>... <enterprise-beans> </jboss> Mise en place d un XMLSchema : <?xml version="1.0" encoding="utf-8"?> <ejb-jar id="ejb-jar_1" xmlns="http://java.sun.com/xml/ns/j2ee" ENI Editions - All rigths reserved - Kaiss Tag

20 xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/j2ee version="2.1">... </ejb-jar> Les parseurs, à l aide des schémas, vont pouvoir analyser si votre fichier de configuration obéit bien aux spécifications. Un document bien formé et conforme à son schéma est dit valide. Il est important de vérifier dans les logs si le non fonctionnement d un EJB, ou d une application Web, n est pas dû à un fichier de configuration non valide. Le parseur de JBoss vérifie les fichiers XML avant de monter le module dans son conteneur. ENI Editions - All rigths reserved - Kaiss Tag - 3 -

21 Rappels sur J2EE 1.4 Avec la spécification J2EE 1.4, un EJB est un composant constitué, au minimum de (ou des) : une (ou deux) interface(s) de création ; une (ou deux) interface(s) d exposition des méthodes ; classes qui implémentent les interfaces ; un fichier de déploiement ejb jar.xml ; un (ou plusieurs) fichier(s) de configuration propre(s) au serveur d application. L objet qui est codé par le développeur contient l implémentation des méthodes métier. Cette classe doit implémenter une interface du typejavax.ejb.sessionbean ou javax.ejb.entitybean. La spécification EJB 2 demande ensuite deux types d interfaces pour l exposition : des méthodes de création ; des méthodes métier. N oubliez pas que le cycle de vie de l EJB est géré par le conteneur d EJB. Le client de l EJB ne l instancie pas directement, il passe par les méthodes de création (create(), findbyprimarykey(), etc) qui sont exposées via une interface, étendant l interfacejavax.ejb.ejbhome. De même, les appels vers les méthodes métier implémentées dans l EJB passeront par l interface, exposant les méthodes métier. Le développeur doit donc, déclarer les méthodes métier accessibles en les exposant dans une interface, étendant l interface javax.ejb.ejbobject. Les interfaces, qui étendent javax.ejb.ejbhome etjavax.ejb.ejbobject, sont dites des interfaces distantes car les appels sur les méthodes exposées par ces interfaces sont effectués via RMI. Or, de nombreux appels sont effectués entre objets qui sont déployés sur le même serveur, donc dans la même machine virtuelle. Par exemple, une servlet d une application Web qui utilise un EJB de session, ou un EJB de session qui utilise un EJB entité. Donc dans ce cas, l invocation des méthodes via RMI est très couteuse, car complètement inutile. Pour y remédier, la spécification EJB 2 ajoute deux interfaces qui permettent de déclarer les méthodes de création et les méthodes métier, qui seront accessibles localement, au sein de la même machine virtuelle : l interface javax.ejb.ejblocalhome pour les méthodes du cycle de vie ; l interface javax.ejb.ejblocalobject pour les méthodes métier. Le développeur doit donc : créer une classe d implémentation pour implémenter une interface javax.ejb.sessionbean ou javax.ejb.entitybean. exposer les méthodes du cycle de vie dans des interfaces qui permettront un accès : distant via RMI (remote) en étendant l interface javax.ejb.home ; au sein d une même machine virtuelle (local) en étendant l interface javx.ejb.localhome. exposer les méthodes métier dans des interfaces qui permettront un accès : distant en étendant l interface javax.ejb.ejbobject ; local en étendant une interface javax.ejb.ejblocalobject. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

22 écrire les descripteurs de déploiement de l EJB. Ce fichier au format XML décrit les propriétés des EJB, qui constitueront l archive. Ce fichier s appelle le fichier ejb jar.xml. écrire un fichier de déploiement spécifique au serveur, le fichier jboss.xml pour JBoss, qui décrit, entre autres, les noms JNDI des EJB. Nous pouvons voir que l écriture d un EJB peut paraître assez complexe, bien que le véritable travail ne concerne qu une seule classe : la classe d implémentation. Heureusement, il existe des outils pour automatiser la création du composant : soit en utilisant des scripts Ant soit en utilisant les XDoclets, comme c est le cas sous Éclipse Europa. Vous trouverez en annexe les paramétrages à effectuer pour l utilisation de XDoclet. Le développeur crée uniquement sa classe d implémentation, ensuite, l outil créera les interfaces et les fichiers XML nécessaires. Les objets clients n interagissent jamais avec la classe implémentant les interfaces. C est le serveur qui gère, par l intermédiaire de classes d interpositions, le cycle de vie et les invocations des méthodes de l EJB. Il est important de noter que les accès aux EJB peuvent se faire de deux façons : par RMI, si le client de l EJB est un objet déployé sur une machine virtuelle différente de celle de l EJB ; sans RMI, si le client de l EJB est dans la même machine virtuelle. Il faut donc, très tôt, se demander comment sera déployée l application. Si l application Web est déployée sur le même serveur que la couche métier, il faut privilégier les appels sans RMI. Un appel par RMI est toujours plus coûteux en terme de performance (passage des paramètres par copie, sérialisation) qu un appel direct en mémoire. Il faut noter que sous JBoss, si le client et l EJB sont dans la même machine virtuelle, même si le client appelle les méthodes via les interfaces distantes (donc par RMI), JBoss invoquera les méthodes via les interfaces locales, si elles existent ENI Editions - All rigths reserved - Kaiss Tag

23 Rappels sur JEE 5 Le codage des EJB a été largement simplifié avec la spécification EJB 3. Les mécanismes de base sont les mêmes : RMI, JNDI, pas d invocation directe des méthodes des EJB, cycle de vie de l EJB géré par le conteneur. Les EJB 3 sont basés sur de simples classes POJO (Plain Old Java Object, objet de base type JavaBean). L interface Home de création a disparu et le fichier XML ejb-jar.xml décrivant le composant n est plus obligatoire. Cette simplification est liée à l évolution du langage (apparition des annotations avec Java 5) et aux bénéfices issus des travaux sur les frameworks Spring, Hibernate... Les différents services d une application doivent pouvoir se localiser. Cette opération peut prendre de multiples formes : création d un objet et utilisation directe de celui ci ; recherche du service en utilisant JNDI ; emploi de fabrique pour créer le service ; implémentation des services comme singleton. Le code client du service peut, alors, devenir très vite significativement dépendant de l implémentation, ou vite peu lisible par le codage des recherches. Cette localisation est effectuée classiquement par l intermédiaire de JNDI sur les serveurs d application. Les dépendances peuvent être éliminées en confiant à un tiers le soin de mettre en relation les objets, c est l inversion de contrôle. Les composants sont, alors, reliés automatiquement avant leur utilisation. Pour bien comprendre comment les conteneurs JEE 5 gèrent le cycle de vie des composants, il est primordial de comprendre les implémentations possibles du pattern Inversion of Control (IoC), appelé aussi Dependency Injection. L inversion de contrôle (IoC Inversion of Control) n est en rien, une évolution du langage. C est un modèle de conception qui propose de séparer les problématiques techniques (aspects) des problématiques métier dans une application. C est une application tiers, le framework, qui mettra en liaison les objets. 1. Les annotations Le système des annotations est une des évolutions importantes apportées par Java 5, puis enrichies par Java 6. C est une véritable alternative aux fichiers de configuration XML et aux outils tiers tels que XDoclet. La maintenance est largement simplifiée car la prise en compte des changements dans le code source est, directement, sous la responsabilité des outils du langage, ou des conteneurs, sans avoir à synchroniser un fichier XML ou à réeffectuer une compilation avec XDoclet. Les annotations sont des métadonnées ajoutées au code. Le développeur ajoute les annotations au code source et elles peuvent se propager jusqu à l exécution. Il existe, dans la spécification des annotations, des "super annotations" : les méta annotations, qui permettent d annoter les annotations. Ces méta annotations sont situées dans le package java.lang.annotation. L ensemble des annotations (et méta annotations) utilisables avec le JDK 6 héritent de l interface java.lang.annotation.annotation. Les conteneurs, dont JBoss, ajoutent leur propre jeu d annotations. Objectif Indique à l outil javadoc qu il doit prendre en compte cette annotation. Permet l héritage Détermine la politique de propagation de l annotation. Détermine la cible de l Supprime les avertissements sur un élément. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

24 La méta permet de fixer le mode de propagation de l annotation. RetentionPolicy.SOURCE : les annotations ne seront pas enregistrées dans le fichier *.class. Elles sont utilisables par les outils manipulant les fichiers sources (compilateur, javadoc ). Exemple : l annotation RetentionPolicy.RUNTIME : les annotations sont enregistrées dans le fichier *.class et sont accessibles par la machine virtuelle, lors de l exécution. Ces annotations sont utilisées via l API de réflexion. Les annotations JBoss sont du type RetentionPolicy.RUNTIME. RetentionPolicy.CLASS : les annotations sont enregistrées dans le fichier *.class. Elles ne sont pas utilisées par la machine virtuelle, mais peuvent l être par les outils manipulant les fichiers *.class. L injection de dépendance utilise les annotations et la réflexion. Un exemple simple permet de mieux comprendre comment les conteneurs peuvent injecter dans les membres de nos classes les ressources voulues (EJB, source de données ). L ensemble des fichiers sources qui suivent sont téléchargeables sur le site ENI, sous le projet Annotations. Il nous faut d abord créer notre propre annotation : package fr.eni.editions.jboss.annotations; Message String value(); Le type de notre annotation Message Il possède une méthode value() qui représente un attribut de notre annotation. Nous pouvons, maintenant, utiliser notre annotation dans la classe TestMessage : package fr.eni.editions.jboss.annotations; public class world") private String monmessage; public void afficher() System.out.println("Valeur du message : "+monmessage); Il n y a qu une seule méthode dans notre annotation : value(). Nous pouvons donc éviter de préciser le nom de l attribut de Message. Si cela n avait pas été le cas, nous aurions dû avoir world") private String monmessage; L objectif de l utilisation de notre annotation est donc, d injecter la valeur de l attribut value de Message dans la propriété monmessage de TestMessage. Cette injection est effectuée par une application tiers, en général un framework. Dans notre exemple il s agira d une simple classe. Nous devons donc maintenant, coder l injection : package fr.eni.editions.jboss.annotations; import java.util.*; import java.lang.reflect.*; public class MessageProcess // code permettant l injection de dépendance public static void injecter(object obj) throws Exception for(field field : obj.getclass().getdeclaredfields()) ENI Editions - All rigths reserved - Kaiss Tag

25 if(field.isannotationpresent(message.class)) Message annotation = (Message)field.getAnnotation (Message.class); field.setaccessible(true); field.set(obj,annotation.value()); La méthode injecter(object obj) de la classe MessageProcess permet de réaliser cette injection. Pour chaque champ field de l instance obj, il y a vérification de la présence de l annotation. Si c est le cas, la valeur de l attribut value de l annotation est récupérée pour mettre à jour le champ. C est l application qui mettra en œuvre l injection : package fr.eni.editions.jboss.annotations; public class Main public static void main(string[] args) throws Exception TestMessage test = new TestMessage(); MessageProcess.injecter(test); test.afficher(); Cet exemple permet de mieux comprendre comment les conteneurs compatibles avec les spécifications JEE 5 peuvent automatiquement utiliser les annotations pour mettre des ressources dans un contexte JNDI, injecter des ressources du contexte JNDI vers les membres de nos classes. 2. Injection par proxy La journalisation, les messages de debug, les autorisations, les transactions sont des problématiques récurrentes en programmation. Si nous prenons l exemple d une journalisation, il nous faut une classe qui permette la journalisation, appelée ici Logger, et une qui utilise la journalisation, Service. Les méthodes ayant besoin de journaliser appelleront les méthodes de la classe Logger. Cela sera identique pour toute classe utilisant la journalisation. package fr.eni.editions.jboss.aop; public class Logger public void debutlog() System.out.println("début de journalisation"); public void finlog() System.out.println("fin de journalisation"); package fr.eni.editions.jboss.aop; public class Service Logger logger = new Logger(); public void executer() logger.debutlog(); System.out.println(">> Méthode executer() "); logger.finlog(); ENI Editions - All rigths reserved - Kaiss Tag - 3 -

26 Cette illustration peut être appliquée à l authentification, les transactions, etc. Nous voyons ainsi notre code émaillé d appels vers des méthodes de classes qui n ont rien à voir avec notre code métier. Ces appels peuvent nuire à la lisibilité de nos méthodes métier. Une dépendance est créée entre des classes qui a priori n ont rien à voir entre elles. Les services de journalisation, authentification... sont des services transversaux à notre application. Pour supprimer les dépendances entre ces classes, un des moyens est de déléguer à un framework l appel des méthodes. Nous illustrerons ceci par l exemple de la mise en place d un proxy, dont la méthode invoke() sera appelée avant la méthode executer() de notre classe Service. L ensemble des fichiers sources qui suivent sont téléchargeables sur le site ENI, sous le projet Exemple IoC. La classe Service ne contient plus d appels aux méthodes de la classe Logger : package fr.eni.editions.jboss.aop; public class Service implements Iservice public void executer() System.out.println(">> Méthode executer() "); La classe Service n est donc plus liée à la classe Logger, chargée de la journalisation. Pour que la classe Service utilise Logger, il nous faut un intermédiaire qui mettra en relation ces deux classes, en changeant le comportement de la méthode executer(). Les classes Main, ServiceFactory et LoggerProxyHandler jouent le rôle du framework en mettant en liaison, ou non, les classes Logger et Service, en fonction du paramètre passé à la méthode create() de ServiceFactory. La journalisation sera activée si le paramètre passé est true. package fr.eni.editions.jboss.aop; public class Main public static void main(string[] args) IService s = ServiceFactory.create(true); s.executer(); La méthode create() de ServiceFactory retourne une instance d un proxy sur Service si la demande de journalisation est activée par le paramètre booléen log. Si la demande de journalisation n est pas activée, la méthode renvoie une instance de Service ENI Editions - All rigths reserved - Kaiss Tag

27 package fr.eni.editions.jboss.aop; import java.lang.reflect.proxy; import java.lang.reflect.invocationhandler; public class ServiceFactory public static IService create(boolean log) IService service = new Service(); if (log) InvocationHandler handler = new LoggerProxyHandler(service); IService proxy = (IService) Proxy.newProxyInstance(IService.class.getClassLoader(), new Class[] IService.class, handler); return proxy; else return service; La classe LoggerProxyHandler doit mettre en relation une instance de classe quelconque avec la classe Logger. Le constructeur de LoggerProxyHandler reçoit l instance de la classe sur laquelle la journalisation doit être effectuée. La méthode invoke() de LoggerProxyHandler sera appelée à la place de la méthode executer() de la classe Service. Cette méthode mettra alors en place la journalisation avant d invoquer la méthode executer() de la classe Service. package fr.eni.editions.jboss.aop; import java.lang.reflect.invocationhandler; import java.lang.reflect.method; public class LoggerProxyHandler implements InvocationHandler Object subject; public LoggerProxyHandler(Object subject) this.subject = subject; public Object invoke(object proxy, Method method, Object[] args) throws Throwable Logger ctx = new Logger(); ctx.debutlog(); Object returnvalue = method.invoke(subject, args); ctx.finlog(); return returnvalue; Le diagramme de séquences suivant présente les échanges de messages entre les instances. ENI Editions - All rigths reserved - Kaiss Tag - 5 -

28 Dans le monde réel, les frameworks peuvent avoir des implémentations différentes, et souvent, la description des liaisons est effectuée par le biais d un fichier XML ou des annotations ENI Editions - All rigths reserved - Kaiss Tag

29 Présentation du serveur d applications JBoss JBoss est un serveur d application écrit en Java. Il peut être employé sur tout système équipé d une JVM (Java Virtual Machine). JBoss a été développé au sein de la société JBoss Inc., créée par Marc FLEURY, le concepteur de la première version de JBoss. JBoss a obtenu la certification en J2EE 1.4 en juillet Puis, Red Hat achète JBoss Inc. en avril 2006 et JBoss Enterprise devient une division de Red Hat JBoss peut être obtenu sous licence LGPL auprès de Jboss.org, qui regroupe les projets JBoss et la communauté des développeurs JBoss. Dans ce cas, il n y a pas d autre support que celui offert par la communauté. Il peut aussi être obtenu de manière commerciale auprès de JBoss Enterprise. Il est, alors, possible de bénéficier d une ligne de produits et de différents services : support technique, programmes de formation, etc. La communauté JBoss gère plusieurs projets ou sous projets : projets serveurs : le serveur JBoss, JBoss pour le web, micro conteneur de JBoss... projets d intégration : messageries, web services, transaction... outils : outils de développement, de profilage, de test ; ENI Editions - All rigths reserved - Kaiss Tag - 1 -

30 interfaces web : bibliothèques pour Ajax, JSF ; frameworks : Seams, EJB 3, AOP, Hibernate ; portlets, applications qui peuvent être incluses dans un portail Web : forum, wiki, blog ; sécurité ENI Editions - All rigths reserved - Kaiss Tag

31 Téléchargement Il est nécessaire de vous assurer que vous avez, au moins, la version 5 de la JRE de Sun d installée pour tester les EJB 3. Si vous utilisez Eclipse pour développer et contrôler JBoss, il vous faudra un JDK, et non un JRE. Pour connaître la version de la JVM installée, exécutez dans une console : $ java -version Nous verrons comment installer et configurer JBoss sous les systèmes d exploitation Windows et Ubuntu (distribution Linux). Seules certaines manipulations liées au système d exploitation sont différentes : gestion des arborescences de fichier, utilisation d éditeurs de texte. Les contenus des répertoires de JBoss, les fichiers de configuration de JBoss sont identiques. À titre indicatif, les machines qui ont été utilisées lors de l écriture de ce document sont les suivantes : un portable sous Windows XP, microprocesseur Intel T2400 à 1,83 GHz, 1 Go de RAM, JDK 6, Eclipse 3.2 ; une station fixe sous Ubuntu, microprocesseur Intel Dual Core 6320 à 1,86 GHzGHz, 2 Go de RAM, JDK 6, Eclipse Téléchargement de JBoss Le téléchargement du serveur JBoss s effectue sur le site de sourceforge, via le site communautaire de JBoss labs.jboss.com (cette adresse est aussi accessible par Lorsque vous accédez à la page principale de labs.jboss.com, sélectionnez le lien Resources. Vous arrivez alors sur la page décrivant les téléchargements possibles, sélectionnez le lien JBoss Application Server. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

32 Maintenant, vous devez choisir la version de JBoss à installer. Sur cette page, vous pourrez télécharger des versions antérieures qui peuvent s avérer nécessaires si votre application JEE est en production depuis un certain temps. Les versions bêta vous permettront de vérifier le bon fonctionnement de vos applications en cas d évolution du serveur et de profiter de ses nouveaux services. Les versions bêta sont évidemment à proscrire pour le serveur en production. Elles sont aussi à éviter lors du développement d application car il n est pas nécessaire de cumuler les difficultés liées au développement et aux instabilités de certains services du serveur. Nous choisirons ici la dernière version stable à l heure où nous écrivons ces lignes, soit la version GA. Sélectionnez maintenant le lien Download. Vous arrivez maintenant sur la page de téléchargement de JBoss, sur sourceforge. Sélectionnez les liens jboss GA.zip puis jboss GA.zip.MD5. Le fichier MD5 vous permettra de vérifier que l archive zip récupérée n est pas corrompue. Vérification MD5 sous Windows À l aide d un utilitaire type md5sum, vous pouvez vérifier si la signature de votre archive zip correspond à la signature contenue dans la fichier MD5. Dans une console DOS, exécutez la commande qui génère la somme de contrôle. md5 <chemin du fichier>jboss ga.zip La valeur de la signature générée et celle contenu dans le fichier MD5 doivent être identiques. Vérification MD5 sous Ubuntu Le principe est le même que sous Windows, avec les commandes md5sum et cat ENI Editions - All rigths reserved - Kaiss Tag

33 ENI Editions - All rigths reserved - Kaiss Tag - 3 -

34 Installation de JBoss Une fois la vérification de la signature MD5 effectuée, vous pouvez décompresser le fichier jboss GA.zip vers un répertoire cible. Ici, la décompression a été effectuée dans le répertoire C:\SERVEURS pour Windows et /home/franck/serveurs sous Ubuntu. Sous les deux systèmes d exploitation, il y a création d un répertoire jboss GA dans le répertoire cible, qui contient la même arborescence de répertoires. Utilisation de l installateur JEMS Installer Il existe une aide à l installation pour JBoss : jems-installer. Nous ne l avons pas utilisée ici, car la dernière version stable de JBoss n y est pas incluse. Le fichier jems-installer ga.jar contient la version GA. Si vous souhaitez utiliser ce fichier jar, vous devez le lancer avec la commande : java -jar jems-installer gar.jar Un assistant graphique va alors vous aider à installer JBoss. Restez sur les choix par défaut de cet assistant, nous verrons plus tard, comment changer le type de serveur. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

35 Lors du choix du serveur par défaut, ne sélectionnez pas all, surtout dans le cas de l installation sur plusieurs machines en réseau. En effet, un cluster de serveurs serait installé. Nous verrons plus tard comment gérer les fermes de serveur ENI Editions - All rigths reserved - Kaiss Tag

36 Structure des répertoires Le répertoire jboss GA contient les répertoires suivants : bin : ce répertoire contient différents utilitaires (comme twiddle), ainsi que les scripts de démarrage et d arrêt du serveur, pour Windows (extension bat) et LINUX (extension sh). client : ce répertoire contient les bibliothèques nécessaires à une application cliente pour se connecter au serveur JBoss. Il peut s agir d une application cliente type client lourd (IHM en swing, par exemple) ou un autre conteneur JEE. docs : ce répertoire contient l ensemble des DTD et XML Schema utilisés par les fichiers XML de configuration et de déploiement. lib : ce répertoire contient l ensemble des archives java utilisées par le serveur JBoss. server : ce répertoire contient des sous répertoires, correspondant à différents types de serveurs pouvant être démarrés. Par défaut, il contient trois configurations de serveurs : all, default, minimal. Chacun de ces répertoires contient les bibliothèques, fichiers de configuration, services nécessaires au bon fonctionnement d un type de serveur. 1. Structure du répertoire de type server Chaque sous répertoire du répertoire server correspond à un type de serveur. Le nom du serveur correspond au nom du répertoire. Le serveur default est celui qui est lancé par défaut, lors du démarrage de JBoss. Un type de serveur se différencie d un autre par les services qui sont exécutés par JBoss. Tous les serveurs ont une arborescence commune. Les répertoires contenus dans un répertoire de type server sont les suivants : conf : répertoire contenant les fichiers de configuration du serveur, sous forme de fichiers XML ou properties. Il contient notamment le fichier jboss service.xml décrivant les services à activer. data : répertoire utilisé par les services. deploy : répertoire de déploiement à chaud des applications JEE (extensions ear, war ou jar) et des services (extension sar). lib : répertoire contenant les bibliothèques qui seront accessibles dans le classpath du serveur. Des bibliothèques externes peuvent y être ajoutées. log : répertoire où sont enregistrés les journaux des événements. tmp : répertoire utilisé par JBoss lors des déploiements, et lors des sérialisations d objets. work : répertoire utilisé par Tomcat (conteneur web de JBoss) pour compiler les pages JSP. Certains répertoires peuvent ne pas être présents juste après la décompression de l archive. Ils seront créés par JBoss en fonction des besoins des applications déployées. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

37 Le répertoire deploy qui est le répertoire de déploiement des applications contient déjà un certain nombre de fichiers. Les fichiers présents peuvent dépendre de la configuration de votre serveur. Par exemple, le répertoire deploy de la configuration minimale est vide. Voici quelques fichiers de ce répertoire deploy : bsh deployer.xml : fichier de configuration du service de déploiement des scripts shell comme service JBoss ; client deployer service.xml : service de déploiement des applications clientes ; ear deployer.xml : service de déploiement des fichiers EAR (Enterprise ARchive) ; ejb deployer.xml : service de déploiement des modules EJB ; hsqldb ds.xml : fichier de configuration de la base de données embarquée dans JBoss : Hypersonic ; http invoker.sar : service de support du protocole RMI sur HTTP ; jboss aop jdk50.deployer : service de configuration et déploiement des applications JBoss AOP ; jboss bean.deployer : permet le déploiement de classes POJO contenues dans des fichiers.beans ; jmx console.war : application web de gestion du serveur de MBean ENI Editions - All rigths reserved - Kaiss Tag

38 Démarrer et arrêter le serveur Avant de lancer JBoss, assurez vous que la variable d environnement JAVA_HOME est bien positionnée sur votre JDK. Si ce n est pas le cas, vous pouvez la positionner en mode console, avant le lancement de JBoss. Faites attention à bien positionner la variable JAVA_HOME dans la même console qui lancera JBoss. Sous Windows : set JAVA_HOME=<répertoire d installation du JDK> Sous Ubuntu : export JAVA_HOME=<répertoire d installation du JDK> D autres variables d environnements peuvent être, éventuellement, utilisées par JBoss. JAVA_OPTS : options supplémentaires passées à la machine virtuelle, comme la taille du tas Xmx512M. JBOSS_CLASSPATH : entrées de classpath supplémentaires. MAX_FD : sous LINUX, nombre maximum de descripteurs de fichiers, utilisés par JBoss. JAVA : nom du binaire java, java par défaut. 1. Sous Windows Dans une console, positionnez vous dans le répertoire bin du répertoire d installation de JBoss, puis exécutez la commande run. 2. Sous Ubuntu Dans une console, positionnez vous dans le répertoire bin du répertoire d installation de JBoss, puis exécutez la commande./run.sh. 3. Suivi du démarrage Quel que soit votre système d exploitation, vous pouvez observer le démarrage de JBoss dans la console. Vous pourrez y vérifier la prise en compte de la bonne machine virtuelle. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

39 Quand le temps de démarrage du serveur s affiche, il est réellement actif. Vous remarquerez que le service HTTP est en écoute sur le port Par défaut, les services JBoss écoutent l adresse IP , soit l adresse locale. Vous pouvez le vérifier dans la console de démarrage. Ce qui explique que sur votre réseau, vous pouvez visualiser la page d accueil de JBoss sur la machine sur laquelle s exécute JBoss, à l URL mais que vous ne pouvez pas voir cette même page sur une autre machine. L option de la ligne de commande-b ou --host permet de spécifier une autre adresse d écoute. run -b ou ENI Editions - All rigths reserved - Kaiss Tag

40 run --host= Si l adresse IP est précisée, les services JBoss écouteront sur toutes les adresses. D autres options peuvent être précisées sur la ligne de commande : h help page d aide. V version affichage de la version. D<name>[=<value>] d bootdir=<dir> p patchdir=<dir> ajout d une propriété système. répertoire de prise en compte des patches de démarrage. répertoire de prise en compte des patches. n netboot=<url> démarrage réseau. c configuration=<name> nom de la configuration serveur à lancer, par défaut default. B bootlib=<filename> ajout d une librairie au classpath de démarrage du serveur. L library=<filename> ajout d une librairie au classpath. C classpath=<url> ajout d une URL au classpath. p properties=<url> lecture de propriétés système à partir d une URL. b host=<host ou IP> adresse d écoute pour les services JBoss, par défaut g partition=<name> nom du service HA (highly available), par défaut DefaultDomain. u udp=<ip> adresse multicast UDP. La forme simplifiée d une option commence par un tiret, sa forme complète par deux tirets. Les options s utilisent soit : avec leur forme simplifiée : -b , et alors un espace sépare l option et sa valeur ; soit avec leur forme complète : --host= , et alors un signe égal sépare l option et sa valeur. 4. Test de JBoss Pour tester le bon fonctionnement de cette installation, vous pouvez, dans un navigateur, taper l url La page d accueil de JBoss s affiche : le serveur est démarré correctement. ENI Editions - All rigths reserved - Kaiss Tag - 3 -

41 5. Arrêt de JBoss Sous Windows ou Ubuntu, vous pouvez arrêter le serveur avec la combinaison de touches [Ctrl] C dans la console où le serveur est démarré. Depuis le répertoire bin de JBoss, vous pouvez aussi lancer le script d arrêt du serveur : shutdown. Attention, pour que le script fonctionne, il faut que la variable d environnement JAVA_HOME soit positionnée sur le JDK. Sous Windows : C:\SERVEURS\jboss GA\bin> shutdown -S Sous Ubuntu : $./shutdown.sh -S 6. Arrêt et démarrage des autres configurations serveur Lors du test de démarrage précédent, effectué avec la commande run, la configuration par défaut a été exécutée. Cette configuration par défaut correspond au répertoire <dossier installation JBoss>/server/default. Ce serveur par défaut correspond à un serveur aux spécifications JEE, sans le support du clustering. Il existe deux autres configurations installées : minimal et all. La première correspond à un serveur minimum, qui lance uniquement JNDI (Java Naming and Directory Interface) comme service de base. Ce serveur ne correspond pas aux spécifications JEE. La deuxième all est un serveur complet JEE, avec le support du clustering. Le lancement d un serveur autre que celui par défaut, s effectue avec la commande run, en précisant la configuration à lancer ENI Editions - All rigths reserved - Kaiss Tag

42 a. Pour lancer le serveur minimal Sous Windows : C:\SERVEURS\jboss GA\bin> run -c minimal ou C:\SERVEURS\jboss GA\bin> run --configuration=minimal Sous Ubuntu : $./run -c minimal ou $./run --configuration=minimal Le temps de démarrage du serveur est très bref. Le dernier message de la console indique ce temps. Attention : dans cette configuration minimum, vous ne pouvez pas vous connecter sur l url car le serveur web n est pas lancé. De même, vous ne pourrez pas arrêter le serveur avec la commande shutdown, car le port d écoute d arrêt du serveur n est pas activé. Pour arrêter ce serveur, il faut effectuer un [Ctrl] C dans la console où s exécute le serveur. b. Pour lancer la configuration all Sous Windows : C:\SERVEURS\jboss GA\bin> run -c all ou C:\SERVEURS\jboss GA\bin> run --configuration=all Sous Ubuntu : $./run -c all ou $./run --configuration=all Remarquez le temps de lancement de ce serveur. ENI Editions - All rigths reserved - Kaiss Tag - 5 -

43 Ce serveur peut être testé avec l url et arrêté avec la commande shutdown. Les manipulations et commandes étant les mêmes, quel que soit le système d exploitation, les exemples ne seront plus répétés pour Windows et Ubuntu (ou tout autre système LINUX) ENI Editions - All rigths reserved - Kaiss Tag

44 Déploiement et repli des applications JEE Dans cet ouvrage, nous étudierons les applications J2EE et JEE 5, qui correspondent aux EJB 2 et EJB 3. Les nouveaux projets démarrent avec les EJB 3, mais il est important de comprendre comment sont déployées les anciennes applications EJB 2, car il faut en assurer la maintenance et l évolution. Vous trouverez en téléchargement sur le site de ENI les exemples cités dans cet ouvrage. L accent sera particulièrement mis sur les descripteurs de déploiement, et sur le code Java qui est pertinent par rapport aux options de déploiement. Comme rappelé dans le chapitre Introduction, les applications déployées sur le même serveur sont dans la même machine virtuelle. Il faut donc utiliser les interfaces locales. L appel des interfaces distances (remote) met en jeu tout le processus RMI, avec la sérialisation des arguments et de valeurs de retour, donc un passage par copie. Lors de l appel par les interfaces locales, seules les références des arguments et valeur de retour sont passées. Le déploiement des applications est habituellement fait sous forme d un fichier ear qui regroupe les applications web, les composants ejb et les bibliothèques java communes. Mais lors d un développement ou lors des tests, il est courant de déployer module par module, sans passer par une archive ear. Nous allons donc présenter ces différents types de déploiement. Nous reviendrons sur ce sujet lorsque nous aborderons le chapitre sur JNDI. Dans tous les cas le déploiement s effectue dans le répertoire deploy de la configuration serveur, soit : <dossier installation jboss>/server/default/deploy si JBoss a été lancé avec le serveur par défaut. Les déploiements peuvent être effectués par copie des archives dans le répertoire deploy, ou par l intermédiaire de l outil Eclipse. Vous trouverez au chapitre Produits supplémentaires quelques manipulations de base à connaître pour configurer JBoss, importer les projets et les déployer. 1. Exemple de déploiement d un EJB Un EJB est archivé dans un fichier dont l extension est jar. La structure de ce fichier est la suivante : les fichiers de classes qui composent l EJB, avec la structure du package ; un répertoire META INF qui comporte les fichiers de déploiement ejb jar.xml et jboss.xml. Si nous ouvrons l archive, nous trouvons les répertoires suivants : ENI Editions - All rigths reserved - Kaiss Tag - 1 -

45 Nous y retrouvons le package fr.eni.editions.jboss.ejb2.calculette et le répertoire META INF qui contient les fichiers de déploiement ejb jar.xml et jboss.xml. Ce dernier fichier contient le nom JNDI, sous lequel sera enregistré le composant. <?xml version= 1.0 encoding= UTF-8?> <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.2//EN" "http://www.jboss.org/j2ee/dtd/jboss_4_2.dtd"> <jboss> <enterprise-beans> <session> <ejb-name>calculette</ejb-name> <jndi-name>ejb2/calculette/remote</jndi-name> <local-jndi-name> ejb2/calculette/local </local-jndi-name> </session> </enterprise-beans> </jboss> La balise <ejb-name> reprend le nom de l EJB déclaré dans le fichier ejb jar. Les balises <jndi-name> et <local-jndiname> sont les noms JNDI, sous lesquels les interfaces local et remote seront enregistrées. Le déploiement du fichier jar est automatique, il suffit de le copier dans le répertoire deploy. La console permettra de suivre la prise en compte de l EJB. De plus, vous pouvez contrôler les noms JNDI dans la console d administration. Saisissez l url dans un navigateur et suivez le lien JMX Console. Vous vous trouvez en présence de la page qui recense les services de JBoss. Nous présenterons plus en détail les services JMX (Java management extension) de JBoss. Recherchez dans cette page, l entrée qui correspond au service d affichage des noms JNDI : service=jndiview. Cliquez sur ce lien. Dans la vue suivante, recherchez l opération list et cliquez sur le bouton Invoke ENI Editions - All rigths reserved - Kaiss Tag

46 La page affiche maintenant l arborescence des noms JNDI. À la fin de la page, dans la rubrique Global JNDI Namespace, vous retrouverez les noms JNDI de votre EJB. +- ejb2 (class: org.jnp.interfaces.namingcontext) +- calculette (class: org.jnp.interfaces.namingcontext) +- local (proxy: $Proxy58 implements interface fr.eni.editions.jboss.ejb2.calculette.calculettelocalhome) +- remote (proxy: $Proxy60 implements interface fr.eni.editions.jboss.ejb2.calculette.calculettehome,interface javax.ejb.handle) Le déploiement s est bien passé. 2. Exemple de déploiement d une application Web L application web est archivée dans un fichier dont l extension est war. De la même manière que pour l EJB, il suffit de copier ce fichier dans le répertoire deploy pour que l application soit déployée sur le serveur JBoss. La structure d un fichier war est la suivante : Le descripteur de déploiement jboss web.xml permet de fixer l url d appel de l application Web. Ainsi dans notre cas l application web sera accessible à l adresse : <jboss-web> <context-root>cwc</context-root> ENI Editions - All rigths reserved - Kaiss Tag - 3 -

47 </jboss-web> Dans la console, vous pouvez suivre le déploiement de l application Web. 10:29:45,375 INFO [TomcatDeployer] deploy, ctxpath=/cwc, warurl=.../tmp/deploy/tmp60456chap 2 - Client web calculette EJB2-exp.war/ 10:29:55,781 INFO [EjbModule] Deploying Calculette 10:29:55,890 INFO [BaseLocalProxyFactory] Bound EJB LocalHome Calculette to jndi ejb2/calculette/local 10:29:55,890 INFO [ProxyFactory] Bound EJB Home Calculette to jndi ejb2/calculette/remote 10:29:55,890 INFO [EJBDeployer] Deployed: file:/c:/serveurs/ jboss ga/server/default/deploy/chap 2 - Calculette EJB2.jar Si l EJB a été précédemment déployé, vous pouvez tester l application Web et vous devriez obtenir l écran suivant. 3. Exemple de déploiement d une application d entreprise Les applications d entreprise regroupent plusieurs modules EJB, Web, bibliothèques... au sein d une archive dont l extension est ear ENI Editions - All rigths reserved - Kaiss Tag

48 Il suffit de copier ce fichier dans le répertoire deploy pour que les différents modules soient pris en compte par le serveur JBoss. 4. Retrait d une application Pour supprimer une application, il suffit d enlever du répertoire deploy le fichier archive. La console vous permettra de suivre le retrait de l application ou de l EJB qui est en cours de suppression. ENI Editions - All rigths reserved - Kaiss Tag - 5 -

49 Noyau du serveur Afin de permettre un développement modulaire, JBoss est composé de services qui s ajoutent à un noyau, comme des plugins. Cette modularité est basée sur la spécification JMX (Java Management extension). Après une présentation de la spécification JMX, nous verrons comment celle ci est implémentée sous JBoss, et comment nous pouvons gérer les services JBoss et ajouter nos propres services. 1. Présentation de la spécification JMX La spécification JMX fournit un standard pour gérer et superviser des ressources matérielles et logicielles, y compris la machine virtuelle. Cette spécification fait partie de la plate forme standard (JSE) depuis la version 5. L instrumentation des ressources s effectue au moyen de composants spécifiques appelés MBean (Managed Bean). L architecture JMX comporte 3 niveaux : un niveau "Instrumentation" avec les MBeans, où le MBean peut être perçu comme une "sonde" permettant de gérer une ressource. Le MBean instrumentalise la ressource à superviser ; un niveau "Agent" avec le conteneur de MBeans (ou serveur de MBeans) qui gère les MBeans et peut exécuter des opérations sur ces MBeans ; un niveau "Distribution" constitué des mécanismes de communication entre les applications de supervision et le niveau "Agent". La plate forme Java inclut une console de supervision des MBeans : jconsole qui se trouve dans le sous répertoire bin du répertoire d installation du JDK. Le MBean doit suivre un modèle de conception qui consiste à avoir : des attributs en lecture et ou écriture ; des opérations ; une description. La spécification définit 5 types de MBeans : standard, dynamique, ouvert, modèle et MXBean. Nous ne présenterons ici que le MBean standard, l objectif étant de comprendre la prise en compte et la gestion des services par JBoss. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

50 Un MBean standard est composé : d une interface nommée QuelqueChoseMBean : les attributs sont exposés par des getters/setters. les opérations sont des méthodes publiques. d une classe nommée QuelqueChose qui implémente l interface QuelqueChoseMBean. Les exemples suivants sont extraits du package fr.editions.eni.jboss.mbeans du projet "Chap 3 MBean" de l archive téléchargée. Cet exemple est trivial mais utile pour illustrer les mécanismes de base de JMX. a. La couche instrumentation : l interface HelloMBean Elle possède : deux attributs : Name en lecture seule, et Couleur en lecture et écriture. deux opérations sayhello() et additionner( ) ENI Editions - All rigths reserved - Kaiss Tag

51 package fr.editions.eni.jboss.mbeans; public interface HelloMBean // attributs public String getname(); public void setcouleur(string couleur); public String getcouleur(); // opérations public void sayhello(); public double additionner(double a, double b); b. La couche instrumentation : implémentation du MBean Cette implémentation est triviale et n appelle pas de commentaires. package fr.editions.eni.jboss.mbeans; public class Hello implements HelloMBean private String couleur = "vert"; private String name = "ENI"; public double additionner(double a, double b) return a+b; public String getcouleur() return couleur; public String getname() return name; public void sayhello() System.out.println("Bonjour tout le monde"); public void setcouleur(string couleur) this.couleur = couleur; c. La couche Agent JSE fournit un conteneur de MBean que nous pouvons utiliser pour y enregistrer notre MBean. public class AgentHelloMBean public static void main(string[] args) throws Exception // Récupération d un MBean Serveur MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // Tout MBean doit être associé à un ObjectName ObjectName on = new ObjectName("fr.editions.eni.jboss.mbeans:type=Hello"); // Instansiation de Hello, puis enregistrement dans le serveur Hello hello = new Hello(); mbs.registermbean(hello, on); // Attente System.out.println("Serveur démarré..."); Thread.sleep(Long.MAX_VALUE); ENI Editions - All rigths reserved - Kaiss Tag - 3 -

52 d. La couche distribuée : jconsole Pour tester cet exemple, exécutez la classe AgentHelloMBean. Puis, démarrez jconsole, qui est un exécutable qui se trouve dans le répertoire bin de votre JDK (avec java, javac ). Nous utilisons ici le JSE 6. Si l agent est bien démarré, vous devez le voir apparaître dans la fenêtre de connexion. Sélectionnez fr.editions.eni.jboss.mbeans.agenthellombean et cliquez sur le bouton Connect. Puis sélectionnez l onglet MBeans. Vous retrouvez les deux attributs Couleur et Name, notez que ces attributs commencent par une majuscule. Vous pouvez changer la valeur de Couleur, mais pas celle de Name ENI Editions - All rigths reserved - Kaiss Tag

53 En sélectionnant l opération additionner, vous pouvez entrer les paramètres p1 et p2, puis cliquer sur le bouton additionner. Le résultat apparaît dans une fenêtre popup. Pour l opération sayhello, le résultat apparaît dans la fenêtre d exécution de la classe AgentHelloMBean. e. Supervision : notification d événement JMX définit un mécanisme de notification, qui permet d être à l écoute d un changement d état, d une anomalie qui ENI Editions - All rigths reserved - Kaiss Tag - 5 -

54 survient Le MBean doit implémenter l interface NotificationEmitter, ou étendre la classe NotificationBroadcastSupport. Dans notre exemple, nous allons réagir à un changement de l attribut Couleur. Un client pourra alors s inscrire auprès du MBean, via un listener, pour être notifié, lors du changement de la valeur de l attribut. Les extraits suivants de code sont situés dans le package fr.editions.eni.jboss.mbeans.notification du projet "Chap 3 MBean". La classe Hello hérite maintenant de NotificationBroadcastSupport. L implémentation de la méthode setcouleur de la classe Hello a changé. Une notification est instanciée puis elle est ensuite envoyée. Si un client est à l écoute de cette notification, il pourra réagir au changement d état. Avant de poursuivre, veillez à arrêter la classe AgentHelloMBean précédente. public synchronized void setcouleur(string couleur) String oldcouleur = this.couleur; this.couleur = couleur; System.out.println("=> Changement de couleur. Passage de "+oldcouleur+" à "+this.couleur); Notification n = new AttributeChangeNotification(this,sequenceNumber++, System.currentTimeMillis(), "CHANGEMENT DE COULEUR", "couleur","string",oldcouleur,this.couleur); sendnotification(n); Comme précédemment, exécutez la classe AgentHelloMBean et connectez la console jconsole sur cet agent. Cliquez sur l onglet MBeans, dans le navigateur de MBeans, vous devriez maintenant voir un nouvel item Notifications. Cliquez sur cet item, dans la partie droite de la fenêtre, l historique des notifications s affiche avec les boutons : Subscribe pour s inscrire auprès du MBean pour être à l écoute d une notification ; Unsubscribe pour se désinscrire ; Clear pour effacer l historique des notifications reçues. Cliquez sur Subscribe et changez la valeur de l attribut Couleur ENI Editions - All rigths reserved - Kaiss Tag

55 La notification du changement de la valeur de l attribut a bien été prise en compte. 2. Implémentation de JMX dans JBoss JBoss utilise la spécification JMX comme un "bus logiciel", ce qui permet d ajouter des composants JMX. Ceux ci sont les services JBoss. JBoss utilise JMX comme micro noyau. 3. Processus de démarrage de JBoss Lors du démarrage de JBoss, par la commande run, une instance de serveur de MBeans est créée. Cette instance joue le rôle de micro noyau. Ce micro noyau ne fournit aucune fonctionnalité à JBoss, si ce n est celle d ajouter des services sous forme de MBeans. L ensemble du processus de démarrage s affiche dans la console dans laquelle le script de démarrage est exécuté. Les grandes étapes du démarrage du serveur sont : création d un MBeanserver ; enregistrement des MBeans ServerImpl et ServerConfigImpl ; initialisation du chargeur de classes (class loader) ; création du MBean org.jboss.system.servicecontroller qui contrôle le cycle de vie des MBeans de JBoss ; démarrage des services de gestion de déploiement ; ENI Editions - All rigths reserved - Kaiss Tag - 7 -

56 chargement des services décrits dans le fichier jboss service.xml. 4. Le fichier jboss service.xml Avant toute manipulation de ce fichier, créez une copie du fichier original. Lors du démarrage du micro noyau, le fichier jboss service.xml est lu pour activer les services de base. Les services décrits dans ce fichier de configuration ont la durée de vie de l exécution du serveur. Ce fichier de configuration est situé dans le répertoire conf de la configuration serveur : minimal, all, ou default. Dans les répertoires de serveur all et default, il y a un fichier jboss minimal.xml, de plus, non utilisé, qui indique la configuration minimum pour que JBoss puisse démarrer. Il faut noter que cette configuration minimum n est pas compatible avec les spécifications JEE. Ce fichier est le fichier de configuration principal des MBeans du serveur JBoss. Chaque MBean possède son propre fichier de configuration jboss service.xml. La structure du fichier jboss service.xml est très simple. Vous pouvez ouvrir le fichier de configuration de la configuration serveur par défaut : <répertoire JBoss>/server/default/conf/jboss service.xml. <server> <classpath /> <mbean > <attribute > </attribute> </mbean </server> La valeur des attributs des éléments du fichier de configuration n est pas nécessairement codée en dur. Les attributs peuvent aussi prendre la valeur des propriétés système sous la forme $nom_propriété. <server> Racine du fichier XML. Cet élément contient les éléments <classpath> et <mbean>. <classpath> Cet élément spécifie les fichiers JAR qui doivent être déployés avec les Mbeans. L attribut codebase de l élément <classpath> indique quel répertoire est utilisé. Il contient ici la valeur $jboss.server.lib.url:lib. Celle ci est une propriété utilisée par la classe org.jboss.system.server.serverconfig qui pointe, par défaut, vers le répertoire lib de la configuration serveur. L attribut archives peut spécifier les fichiers JAR à charger. Un astérisque "*" indique que tous les fichiers JAR seront chargés. <mbean> Cet élément spécifie le service MBean qui sera chargé. L attribut code indique le nom complètement qualifié, qui contient le nom de la classe et son paquetage, de la classe d implémentation du Mbean. L attribut name spécifie le nom JMX du Mbean. L éventuel attribut xmbean-dd spécifie le répertoire des ressources utilisées par le service MBean, si celui ci utilise le descripteur de XMbean de JBoss. L élément <mbean> contient lui même d autres éléments XML : <attribute>, <depends>. <attribute> Chaque élément attribut spécifie une paire name/valeur d un attribut du Mbean ENI Editions - All rigths reserved - Kaiss Tag

57 L attribut name de l élément correspond au nom de l attribut du Mbean. La valeur du corps de l élément correspondra à la valeur de l attribut. Le corps de l élément <attribute> peut aussi être constitué d autres balises filles. Ces balises filles correspondent à des attributs du MBean qui doivent être de type org.w3c.dom.element. <depends> Cet élément spécifie une dépendance par rapport à un autre Mbean. L attribut optionnel optional-attribute-name spécifie le nom de l attribut du MBean qui recevra, par injection, une référence à l instance de type javax.management.objectname du MBean, spécifié dans le corps de l élément <depends>. Le corps de l élément contient le nom JMX du MBean. Dans le fichier de configuration du serveur par défaut, nous retrouvons un MBean qui correspond à la spécification JSR77. Cette spécification définit un modèle d information pour administrer le serveur par des outils tiers partie. Le serveur doit exposer ce modèle d information. Le modèle reprend les types d objets faisant partie d un serveur d application JEE. Ces objets sont appelés objets administrés et sont des abstractions d une ressource comme le service Mail par exemple. JSR77 repose sur le standard JMX. Nous trouvons dans ce fichier de configuration, le service qui s occupe du déploiement à chaud. En fin du fichier, vous trouverez l élément lié à ce MBean. <mbean code="org.jboss.deployment.scanner.urldeploymentscanner" name="jboss.deployment:type=deploymentscanner,flavor=url"> Ce MBean servira lors de la présentation de la spécification JMX pour vous montrer les différentes manières de le gérer. Nous allons voir ici quelques attributs de ce MBean, et leur effet sur le déploiement à chaud. <attribute name="scanenabled">true</attribute> Si ScanEnabled est mis à false, le déploiement à chaud n est plus effectif. Cela peut être intéressant dans une configuration en production, pour des raisons de sécurité. <attribute name="scanperiod">5000</attribute> ScanPeriod représente le temps entre deux explorations des répertoires de déploiement à chaud, en millisecondes. Ce temps peut être raccourci lorsque le serveur est sur une machine de développement, pour que le développeur ne s impatiente pas lors des redéploiements. <attribute name="urls"> deploy/ </attribute> URLs représente la liste des URLs participant au déploiement à chaud. Ce sont ces URLs qui seront explorées pour charger les composants. La virgule "," est le séparateur d URLs. Si l URL finit par un slash "/", elle est considérée comme un répertoire et donc contient une collection de composants pouvant être déployés. Un URL comme deploy/ indique qu il s agit d un répertoire, situé relativement au répertoire du serveur démarré (serveur par défaut dans notre exemple) : <repertoire_jboss>/server/default/deploy/. Les URL absolues doivent être préfixées par file:// s il s agit d un système de fichier, ou s il s agit d un déploiement à chaud distant. Pour ajouter un répertoire situé sur la même machine que le serveur, mais en dehors du répertoire de la configuration serveur de démarrage, la syntaxe sera la suivante : <attribute name="urls"> deploy/,c:/deploiements/jboss/ </attribute> Nous pouvons aussi indiquer si l exploration des répertoires de déploiement doit être effectuée de manière récursive. <attribute name="recursivesearch">true</attribute> ENI Editions - All rigths reserved - Kaiss Tag - 9 -

58 Si l attribut RecursiveSearch est mis à true, alors les sous répertoires des répertoires de déploiement seront aussi pris en compte. 5. Propriétés utilisables dans les fichiers de configuration JBoss Vous pouvez utiliser un certain nombre de propriétés comme valeur d attribut des fichiers XML de JBoss. L utilisation de ces propriétés permet de ne pas être tributaire du répertoire d installation de JBoss. La syntaxe est alors la suivante : <balise attribut="$propriété"...> La propriété sera évaluée comme une chaîne de caractères, vous pouvez concaténer vos propres chaînes de la manière suivante : <balise attribut="$propriétéma_chaine"...> Par exemple : keystorefile="$jboss.server.home.dir/conf/eni.keystore" Les propriétés sont classées par type. a. Propriétés de démarrage jboss.boot.library.list : liste des archives utilisées lors du démarrage du serveur, par défaut : log4j boot.jar,jbosscommon.jar,jboss system.jar. jboss.server.type : nom du serveur actif, par défaut : default. jboss.server.root.deployment.filename : fichier à déployer à la fin du processus de démarrage, par défaut : jbossservice.xml. b. Propriétés représentant des URLs ou des répertoires jboss.home.dir : répertoire d installation de la distribution JBoss, par défaut la variable d environnement $JBOSS_HOME. jboss.home.url : URL d installation de JBoss, par défaut, la variable d environnement $JBOSS_HOME. jboss.lib.url : archives du noyau, par défaut : $jboss.home.url/lib. jboss.server.name : nom du serveur actif, par défaut : default. jboss.server.base.dir : répertoire où se trouve les configurations serveur, par défaut : $jboss.home.dir/server. jboss.server.base.url : URL où se trouve les configurations serveur, par défaut : $jboss.home.dir/server. jboss.server.home.dir : répertoire de la configuration courante, par défaut : $jboss.server.base.dir/ $jboss.server.name. jboss.server.home.url : URL de la configuration courante, par défaut : $jboss.server.base.url/$jboss.server.name. jboss.server.temp.dir : répertoire des fichiers temporaires, par défaut : $jboss.server.home.dir/tmp. jboss.server.data.dir : répertoire des fichiers de données, par défaut : $jboss.server.home.dir/data. jboss.server.config.url : URL des fichiers de configuration, par défaut : jboss.server.home.url/conf. jboss.server.lib.url : URL du répertoire des librairies du serveur, par défaut : $jboss.server.home.url/lib. jboss.server.log.dir : répertoire des fichiers de log, par défaut : $jboss.server.home.dir/log. c. Propriétés de configuration jboss.bind.address : nom de l hôte, ou adresse IP d écoute du serveur, par défaut : = "ANY" NIC (à partir de v4.2.*) = localhost seulement. La liste complète des propriétés peut être trouvée sur : ENI Editions - All rigths reserved - Kaiss Tag

59 6. Connexion au serveur JMX de JBoss La connexion au serveur JMX s effectue via des adaptateurs. JBoss fournit des adaptateurs pour des connexions HTTP, RMI et EJB. a. Connexion par la console web : JMX Agent View Dans un navigateur, lancez une connexion sur l URL console. La vue principale correspond à la vue "agent". Elle liste tous les MBeans enregistrés sur le serveur et triés par domaines auxquels ils appartiennent. La sélection d un lien ouvre la vue sur le MBean. Par exemple, recherchez le MBean DeploymentScanner, correspondant à la liste des objets référencés dans l annuaire JNDI du serveur. Dans le domaine jboss.deployement, recherchez le lien sur le DeploymentScanner, puis cliquez dessus. Une nouvelle page affiche les caractéristiques du MBean : les attributs du MBean et les opérations disponibles. Le MBean que nous utilisons dans cet exemple est celui qui gère les répertoires de déploiement. Nous allons ajouter un nouveau répertoire de déploiement dynamiquement, sans passer par le fichier jboss service.xml. ENI Editions - All rigths reserved - Kaiss Tag

60 Sur cet écran, nous retrouvons le nom des attributs (qui correspondent aux noms des méthodes set/get du MBean), leur type, leur accès en ecriture (W) et/ou lecture (R) (présence du setter et/ou getter), leur valeur, ainsi qu une description. Les attributs en écriture peuvent être modifiés directement dans le formulaire, si leur type est compatible avec une saisie, les modifications étant prises en compte après un clic sur le bouton Apply Changes. L attribut URLList présente toutes les URLs susceptibles de servir de répertoire de déploiement. Pour l instant, vous ne devriez avoir qu un répertoire de déploiement dans cette liste, du type file:/<répertoire JBoss>/server/default/deploy. Avant d ajouter le nouveau répertoire de déploiement, il faut d abord le créer. Dans l exemple suivant, ce répertoire s appelle test et est créé dans :/<répertoire JBoss>/server/default. La saisie directe dans le formulaire n est pas ici possible car l attribut est de type List, incompatible avec un mode de saisie directe. Nous allons l ajouter par le biais d une opération. La liste des opérations disponibles est située sous la liste des attributs du MBean. Recherchez l opération addurl(). Cet écran nous donne : le nom de l opération, ici addurl() ; le type de retour de l opération, ici void, donc sans retour ; la liste des paramètres avec leur type, une zone de saisie et une éventuelle description, ici un seul paramètre p1, de type String ; un bouton Invoke permettant d invoquer l opération. Dans la zone de saisie, ajoutez votre répertoire en respectant les conventions vues précédemment, puis cliquez sur le bouton Invoke. Si le répertoire a été correctement ajouté. vous devriez avoir un écran tel que celui ci : Si l opération nous avait retourné une valeur, cette valeur serait affichée. Si une erreur est survenue, la page affiche ENI Editions - All rigths reserved - Kaiss Tag

61 alors la trace de l exception qui a été levée. Vous pouvez contrôler maintenant que le répertoire a été ajouté en cliquant sur le lien Back to MBean View et en vérifiant la valeur de l attribut URLList. Celui ci doit maintenant contenir deux répertoires. b. Connexion par la console web : sécurisation Étant donné l importance du rôle de cette console HTML, l accès peut en être sécurisé. Le site web de la console correspond au répertoire <répertoire JBoss>/server/default/deploy/jmx console.war. Les arborescences classiques d une application JEE de type web s y retrouvent. Les contraintes de sécurité sont en commentaire dans les fichiers web.xml et jboss web.xml. Il suffit de décommenter les éléments <security-constraint> du fichier web.xml, et <security-domain> du fichier jbossweb.xml. Les fichiers des profils (jmx console roles.properties) et des utilisateurs (jmx console users.properties) se trouvent dans le répertoire <répertoire JBoss>/server/default/conf/props, l utilisateur par défaut est admin avec le mot de passe admin. Redémarrez le serveur si nécessaire. Une fenêtre de saisie de l utilisateur et de son mot de passe doit s afficher : Ce chapitre ne détaille pas les mécanismes mis en œuvre et comment les modifier. Les spécifications des applications web seront vues au chapitre Déploiement d application Web et la sécurisation des applications web sera détaillée dans le chapitre Gestion de la sécurité. c. Connexion par l outil twiddle Dans le sous répertoire bin du répertoire d installation de JBoss, vous trouverez un outil nommé twiddle. Cet outil permet de se connecter au serveur JMX de JBoss en ligne de commande. C est un script livré aux formats Unix (twiddle.sh) et Windows (twiddle.bat). Le format général de l utilisation de twiddle est : twiddle [option] <command> [arguments de la commande] Pour obtenir une aide générale, tapez twiddle -h : A JMX client to twiddle with a remote JBoss server. usage: twiddle [options] <command> [command_arguments] options: -h, --help Show this help message --help-commands Show a list of commands -H=<command> Show command specific help -c=command.properties Specify the command.properties file to use -D<name>[=<value>] Set a system property -- Stop processing options -s, --server=<url> The JNDI URL of the remote server -a, --adapter=<name> The JNDI name of the RMI adapter to use -u, --user=<name> Specify the username for authentication -p, --password=<name> Specify the password for authentication -q, --quiet Be somewhat more quiet Pour obtenir la liste des commandes, tapez twiddle -help-commands : ENI Editions - All rigths reserved - Kaiss Tag

62 twiddle commands: jsr77 xmbean info get invoke create setattrs unregister query set serverinfo Print out JSR77 related information Print out mbean metadata as an xmbean descriptor Get the metadata for an Mbean Get the values of one or more MBean attributes Invoke an operation on an Mbean Create an Mbean Set the values of one or more MBean attributes Unregister one or more Mbeans Query the server for a list of matching Mbeans Set the value of one MBean attribute Get information about the MBean server Pour obtenir l aide sur une commande particulière, la commande invoke par exemple, tapez : twiddle -H=invoke Help for command: invoke Invoke an operation on an Mbean usage: invoke [options] <query> <operation> (<arg>)* options: -q, --query-type[=<type>] Treat object name as a query -- Stop processing options query type: f[irst] a[ll] Only invoke on the first matching name [default] Invoke on all matching names Par twiddle, nous pouvons obtenir l état d un attribut d un MBean. Par exemple pour obtenir la liste des URLs de déploiement : twiddle get "jboss.deployment:flavor=url,type=deploymentscanner" URLList Sous Ubuntu, les caractères guillemets " doivent être remplacés par des apostrophes. C:\SERVEURS\jboss GA\bin>twiddle get "jboss.deployment:flavor=url, type=deploymentscanner" URLList URLList=[file:/C:/SERVEURS/jboss GA/server/default/deploy/] C:\SERVEURS\jboss GA\bin> Par la commande invoke nous pouvons ajouter un répertoire de déploiement. twiddle invoke "jboss.deployment:flavor=url,type=deploymentscanner" addurl "file:/c:/serveurs/jboss ga/server/default/test/" Cette commande ne renvoie pas de résultat, aussi un retour null apparaît sur la console. Vous pouvez maintenant lancer une commande get pour vérifier que l URL a été prise en compte. C:\SERVEURS\jboss GA\bin>twiddle invoke "jboss.deployment:flavor=url, type=deploymentscanner" addurl "file:/c:/serv EURS/jboss GA/server/default/test" null C:\SERVEURS\jboss GA\bin>twiddle get "jboss.deployment:flavor=url, type=deploymentscanner" URLList URLList=[file:/C:/SERVEURS/jboss GA/server/default/deploy/, file:/c:/serveurs/jboss ga/server/default/test, file:/c:/serveurs/jboss ga/server/default/test] L utilitaire twiddle se connecte par défaut en localhost ( ). Pour préciser une machine distante, il faut lancer la commande avec l option s : twiddle -s serverinfo -c De même si plusieurs instances de JBoss sont exécutées sur une même machine, il faut préciser le port de connexion (qui est 1099 par défaut) : ENI Editions - All rigths reserved - Kaiss Tag

63 twiddle -s :1199 serverinfo -c d. Connexion par RMI Une application java peut se connecter au serveur JMX de JBoss via l interface org.jboss.jmx.adaptor.rmi.rmiadaptor, qui est liée dans le système de nommage JNDI au nom jmx/invoker/rmiadaptor. La section suivante détaillera les aspects JNDI. Les codes présentés sont extraits de la classe URLDeploymentClient du projet "Chap 3 Client JMX JBoss". InitialContext ic = new InitialContext(); RMIAdaptor server =(RMIAdaptor)ic.lookup("jmx/invoker/RMIAdaptor"); ObjectName name = new ObjectName("jboss.deployment:flavor=URL,type=DeploymentScanner"); Les deux premières lignes de code permettent de récupérer auprès de JNDI, un RMIAdaptor, vers le serveur de MBean. Il faut veiller à avoir un fichier jndi.properties adéquat dans votre classpath (cf. section suivante). La ligne suivante permet de construire un ObjectName sur le domaine et les clés du MBean. Le MBean est aussi enregistré dans le serveur de MBeans. System.out.println("\nListe des URLS avant modification "); List<URL> urls = (List<URL>)server.getAttribute(name, "URLList"); for(url url : urls) System.out.println(">> "+url); L attribut URLList nous renvoie une liste d objets de type URL. L instruction server.getattribute(name, "URLList") permet de récupérer cette liste en fournissant au serveur le ObjectName du MBean et le nom de l attribut. L invocation des méthodes est un peu plus complexe, car il faut renseigner : le nom de la méthode ; les types de paramètres attendus sous forme de tableau de chaînes de caractères. Attention, les classes doivent être complètement qualifiées pour pouvoir être utilisées. les valeurs des paramètres, sous forme de tableau d Object. String newurl = "test/"; String[] signature = "java.lang.string"; Object[] parametres = newurl; server.invoke(name, "addurl", parametres, signature); La variable newurl correspond au répertoire que nous avons créé précédemment. L invocation de l opération se fait via le serveur, en précisant le nom du MBean, le nom de l opération, le tableau des paramètres ainsi que celui des types des paramètres. Il suffit de réafficher la valeur de l attribut URLList pour vérifier la prise en compte des changements. À l exécution de la méthode main( ) de la classe URLDeploymentClient, l affichage suivant est produit : Liste des URLS avant modification >> file:/c:/serveurs/jboss ga/server/default/deploy/ Liste des URLS après modification >> file:/c:/serveurs/jboss ga/server/default/deploy/ >> file:/c:/serveurs/jboss ga/server/default/test/ ENI Editions - All rigths reserved - Kaiss Tag

64 Service de nommage JNDI 1. Présentation de JNDI Dans une architecture distribuée, les ressources doivent être retrouvées avant d être utilisées. Il faut donc un service qui centralise la localisation des ressources et associe à chacune d entre elles une identification unique. Il existe de nombreuses utilisations de ce type d association : une ressource de type fichier est associé à son nom au sein du système de fichiers (FS, pour File System) ; sur Internet les noms de machines (www.eni.fr) sont associées à des adresses IP ( par exemple) par les DNS (Domain Name Service) ; des objets sont associés à une chaîne de caractères pour être utilisés par RMI. JNDI (Java Naming and Directory Interface) permet d associer une ressource avec un nom, c est un annuaire de nommage. JNDI est une API contenant un ensemble d interfaces qui permet d utiliser tout type d annuaire : LDAP, RMI, DNS, CORBA, système de fichiers Une liste de fournisseurs de services JNDI est maintenue par Sun et disponible à l URL Pour bien comprendre les concepts des systèmes de nommage, il est nécessaire de distinguer les notions de nom (name), association (binding) et contexte. a. Les noms La notion de nom est fondamentale dans JNDI. La syntaxe du nom est déterminée par le système de nommage utilisé, c est une convention de nommage. Par exemple, dans un système de fichier Unix, le nom de chaque fichier est décrit par une liste de répertoires séparés par le caractère "/". Par exemple, /usr/jboss/readme.txt correspond au fichier readme.txt situé le répertoire jboss du répertoire usr, situé sous la racine du système de fichiers. Pour un DNS, un nom est composé de chaînes de caractères, séparées par des points "." : par exemple. b. Les noms atomiques C est une partie indivisible du nom. Par exemple www, eni, editions, fr sont des noms atomiques par rapport à c. Les associations Un objet est associé à un nom. En fonction du système de nommage, c est directement l objet qui est associé, ou bien une référence vers cet objet. Dans un contexte de serveur d applications, les références des objets sont associées aux noms, bien que pour simplifier nous parlerons d objet. Dans JNDI, une association est représentée par l interface Binding. d. Le contexte ENI Editions - All rigths reserved - Kaiss Tag - 1 -

65 Le contexte est un objet contenant des associations objet nom. L utilisation de JNDI commence par la récupération d un contexte de système de nommage. L interface javax.naming.context est implémentée par la classe javax.naming.initialcontext, qui est le point d entrée de l utilisation de JNDI. Un contexte initial est créé à partir : des propriétés du paramètre d environnement passé au constructeur ; d un fichier jndi.properties visible dans le classpath. Une erreur fréquente est d utiliser un fichier jndi.properties par défaut ou inapproprié. Dans ce cas, une exception de type javax.naming.noinitialcontextexception est levée. package fr.eni.editions.exemples.jndi; import javax.naming.*; import java.util.*; public class TestJndiFs public static void main(string[] args) throws Exception Hashtable<String,String> env = new Hashtable<String,String>(); // Mise en place des propriétés // pour le contexte initial env.put("java.naming.factory.initial", "com.sun.jndi.fscontext.reffscontextfactory"); env.put("java.naming.provider.url", "file:/c://serveurs"); Context ctx = new InitialContext(env); NamingEnumeration<NameClassPair> liste= ctx.list("//jboss ga"); while(liste.hasmore()) System.out.println(liste.next().getName()); Cet exemple permet l affichage des ressources situées sous le répertoire C:\SERVEURS. Il faudra adapter la propriété java.naming.provider.url à votre machine. Le système de fichiers (FS) est ici vu comme un système de nommage et utilisé via JNDI. Les principales méthodes de la classe Context sont : bind Ajoute une entrée nom objet dans l arborescence du service de nommage. rebind Modifie une entrée du service de nommage, ou l ajoute si elle n existe pas. listbindings Retourne les objets de l arborescence sous forme de NamingEnumeration, avec les objets attachés. list Retourne une énumération des objets sous forme de NameClassPair, sans les objets attachés ENI Editions - All rigths reserved - Kaiss Tag

66 lookup Méthode de recherche d un objet en fonction de son nom, dans le service de nommage. Les librairies java nécessaires sont disponibles dans le répertoire librairies de l archive téléchargeable des exemples. Ces librairies, sous forme de fichiers jar, doivent être accessibles à l exécution. Il faut les associer avec la variable système classpath. Ces librairies sont bien sûr téléchargeables sur le site de Sun, via l URL : puis, sur le lien : Download JNDI & More. et enfin, sur le lien : File System Service Provider, 1.2 Beta 3. Chaque composant EJB est référencé par le serveur d application dans le service de nommage. Une application cliente qui veut utiliser ce composant doit d abord se connecter au service de nommage par JNDI, puis récupérer le composant en indiquant son nom : InitialContext ctx = new InitialContext(); calculette=(calculetteremote)ctx.lookup("ejb3/calculette/remote"); La prise en compte du contexte initial est différente suivant la position de l objet client : dans le serveur d application JBoss, ou dans une application type client lourd. Par exemple, si le client Web de l EJB est déployé dans le même serveur d application que le composant EJB, il n est pas nécessaire de donner un environnement particulier au constructeur de InitialContext. Il suffit d utiliser le constructeur par défaut. S il s agit d un client lourd, déployé en dehors du serveur d application, il faut utiliser le constructeur par défaut, de la classe InitialContext et un fichier jndi.properties approprié, tel que celui ci : ### JBossNS properties java.naming.factory.initial=org.jnp.interfaces.namingcontextfactory java.naming.provider.url=jnp://localhost:1099 java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces Dans ce fichier, les lignes commençant par un caractère dièse (#) sont des lignes de commentaires. java.naming.provider.url est l adresse du port d écoute du service de nommage. Dans cet exemple, le service de nommage est sur la même machine que l application cliente, et écoute sur le port Dans le chapitre Déploiement des EJB, nous verrons comment inclure les librairies du service dans notre application distante. Vous remarquerez que les classes utilisées sont spécifiques à JBoss. Chaque serveur d application utilise sa propre implémentation de service de nommage. Il est donc préférable de mettre les propriétés du service de nommage dans un fichier, plutôt que dans un javax.util.hashtable passé au constructeur de InitialContext. Parfois, il est nécessaire de travailler via HTTP pour passer à travers les proxy et firewall. Il existe des propriétés permettant à un client distant de réaliser cet accès vers JNDI, via HTTP. Les propriétés du fichier jndi.properties deviennent alors : java.naming.factory.initial=org.jboss.naming.httpnamingcontextfactory java.naming.provider.url=jnp://localhost:8080/invoker/jndifactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces Le code du client distant reste le même. Le client distant doit avoir dans son classpath les classes JBoss nécessaires. L ensemble des packages se trouve dans le sous répertoire client du répertoire d installation de JBoss. En général, l utilisation du package jbossall-client.jar est suffisant. 2. L ENC (Environment Naming Context) Une application distribuée est basée sur l assemblage de composants EJB. JNDI va permettre la recherche par leur nom, des composants, et des ressources, comme les sources de données, au sein du serveur. Les applications se réfèrent à leur propre contexte de nommage, l ENC (Environment Naming Context). Ce contexte est accessible sous le nom java:comp/env. Context initctx = new InitialContext(); Context ctx = (Context) initctx.lookup("java:comp/env"); ENI Editions - All rigths reserved - Kaiss Tag - 3 -

67 Nous verrons ultérieurement que les descripteurs de déploiement du composant permettent de paramètrer les entrées ENC. a. Niveau de visibilité des contextes JNDI sous JBoss Selon le contexte utilisé, la ressource sera accessible seulement au sein de l application, du serveur, ou en dehors du serveur. L ordre de présentation des contextes est l inverse de celui de la visualisation par la console JNDI View, qui sera utilisé dans la suite de ce chapitre. Global JNDI Namespace contexte accessible en dehors de la machine virtuelle du serveur. Les ressources qui sont liées à ce contexte, peuvent être utilisées par des applications ne partageant pas la même machine virtuelle que JBoss, un client lourd par exemple. Cela peut être, par exemple, les ressources de type message (queue et topic), ou les références aux EJB déployées, qui doivent pouvoir être utilisées en dehors de JBoss. java: contexte accessible uniquement au sein de la machine virtuelle du serveur, où se retrouvent les ressources de type sources de données, services de sécurité JAAS. Ce sont des services qui seront liés à des contextes d application Web ou EJB déployés sur le serveur. java:comp contexte JNDI utilisable au sein d une application Web ou EJB. Lorsqu un EJB ou une application Web est déployée par JBoss, un contexte de nommage propre est créé, accessible uniquement dans l application. Au sein de ce contexte, des liens sont créés pour référencer des contextes de plus haut niveau. b. Console de visualisation JNDI Vous pouvez retrouver l ensemble des entrées JNDI sur JBoss par l appel de la console de visualisation JNDI. Nous allons décrire comment accéder et utiliser la vue JNDI. Dans la suite de cet ouvrage, lorsque nous nous réfèrerons à la vue JNDI, c est à cet ensemble d opérations que nous réfèrerons. Déployez à l aide d Eclipse, le composant EAR fourni dans l archive téléchargée. Il s agit du projet Chap 3 EAR. Vérifiez que le serveur JBoss est démarré. Attendez le démarrage complet du serveur. Dans un navigateur, saisissez l url : console. Vous obtenez la page qui visualise la liste des services JMX chargés. Recherchez le service JNDIView. Cliquez sur le lien service=jndiview. Vous obtenez la liste des opérations disponibles pour ce MBean ENI Editions - All rigths reserved - Kaiss Tag

68 Retrouvez l opération list() et cliquez sur le bouton Invoke pour appeler l opération. Vous avez maintenant l ensemble des entrées JNDI de JBoss. Vous devriez retrouver : le contexte de nommage de l application Web : java:comp namespace of the Chap 3 - Client web.war application: +- UserTransaction[link -> UserTransaction] (class: javax.naming.linkref) +- env (class: org.jnp.interfaces.namingcontext) +- service[link -> ejb2/service-calculette/remote] (class: javax.naming. LinkRef) +- security (class: org.jnp.interfaces.namingcontext) +- realmmapping[link -> java:/jaas/other] (class: javax.naming. LinkRef) +- subject[link -> java:/jaas/other/subject] (class: javax.naming. LinkRef) +- securitymgr[link -> java:/jaas/other] (class: javax.naming. LinkRef) +- security-domain[link -> java:/jaas/other] (class: javax.naming. LinkRef) Puis, les contextes de nommage des deux EJB : Ejb Module: Chap 3 - EJB.jar java:comp namespace of the Calculette bean: +- env (class: org.jnp.interfaces.namingcontext) java:comp namespace of the ServiceCalculette bean: +- env (class: org.jnp.interfaces.namingcontext) +- calcul[link -> ejb2/calculette/local] (class: javax.naming.linkref) +- tva (class: java.lang.double) Et enfin, en bas de la page HTML, nous trouvons le contexte de nommage global, qui est accessible en dehors du serveur. Les associations entre les EJBs et leur nom JNDI sont effectuées ici. +- HiLoKeyGeneratorFactory (class: org.jboss.ejb.plugins.keygenerator.hilo. HiLoKeyGeneratorFactory) +- UILConnectionFactory[link -> ConnectionFactory] (class: javax.naming. ENI Editions - All rigths reserved - Kaiss Tag - 5 -

69 LinkRef) +- ejb2 (class: org.jnp.interfaces.namingcontext) +- service-calculette (class: org.jnp.interfaces.namingcontext) +- remote (proxy: $Proxy62 implements interface fr.editions.eni. jboss.chap3.ejb2.servicecalculettehome,interface javax.ejb.handle) +- calculette (class: org.jnp.interfaces.namingcontext) +- local (proxy: $Proxy60 implements interface fr.editions.eni. jboss.chap3.ejb2.calculettelocalhome) +- QueueConnectionFactory (class: org.jboss.naming.linkrefpair) +- UUIDKeyGeneratorFactory (class: org.jboss.ejb.plugins.keygenerator. uuid.uuidkeygeneratorfactory) JBoss crée donc : un contexte de nommage JNDI global, directement utilisable avec InitialContext, qui contient les noms JNDI des EJB, des services de transaction, des services de gestion des messages un contexte java: contenant les noms des services d authentification, de mails plusieurs contextes java:comp/env, un par application, EJB, contenant par défaut des liens à des nommages de plus haut niveau mis en place par JBoss, des liens vers d autres ENC et des entrées d environnement décrits dans les fichiers de configuration jboss.xml et jboss web.xml. Il est important, au sein d une application Web ou d un composant EJB, d utiliser l ENC local. En effet, le contexte de déploiement des EJB peut être différent d un serveur à l autre. Nous allons donc voir comment lier les nommages globaux aux contextes de nommage locaux des applications. Ceci permet de limiter l impact du changement aux seuls fichiers de déploiement. 3. Le service de nommage de JBoss : JBossNS JBossNS est l implémentation de javax.naming.context basé, sur une couche socket/rmi. Cette implémentation est optimisée afin, que les appels JNDI effectués dans la même JVM que celle qui exécute le service JBossNS ne passe pas par les sockets ENI Editions - All rigths reserved - Kaiss Tag

70 Le service de nommage démarre avec le MBean NamingService qui fournira le service de nommage JNDI et créera le contexte java:comp. a. Contexte de nommage standard Les propritétés de ce contexte peuvent être fournies sous forme de fichier jndi.properties, ou associées dans une Hashtable. Elles sont les suivantes : java.naming.factory.initial : nom complet de la classe qui créera le contexte initial, soit org.jnp.interfaces.namingcontextfactory pour JBoss. java.naming.provider.url : url du service JNDI auquel le NamingContextFactory doit se connecter, jnp://nom_machine:1099 pour JBoss, où nom_machine est l ordinateur sur lequel est exécuté le service JNDI. java.naming.factory.url.pkgs : est la liste des packages permettant de localiser les contextes JNDI jnp: et java:, les packages sont séparés par ":". Pour JBoss il s agit de org.jboss.naming et org.jnp.interfaces. java.naming.security.principal : est l identité de sécurité (nom de l utilisateur) pour l authentification auprès du service JNDI, si nécessaire. java.naming.security.credential : est l attribut de sécurité (mot de passe, certificat) pour l authentification auprès du service JNDI, si nécessaire. Il faut noter que ces propriétés sont aussi accessibles via des champs statiques de l interface Context. Par exemple, Context.PROVIDER_URL correspond à java.naming.provider.url. 4. Nommage JNDI des composants déployés sous JBoss L ensemble des extraits de code présentés ici, repose sur les quatre projets présents dans l archive téléchargeable : Chap 3 EJB contient deux EJB, Calculette et ServiceCalculette. ServiceCalculette utilise Calculette. Chap 3 client web contient l interface web (accessible par permettant d interroger l EJB ServiceCalculette. Chap 3 EAR est le fichier de déploiement EAR de l application. Chap 3 client lourd EJB permet de tester l EJB ServiceCalculette en dehors de la machine virtuelle de JBoss. Vous pouvez modifier ces projets pour tester les différents nommages JNDI, et donc les recherches dans le contexte approprié, en fonction des types de déploiement. Cet exemple est basé sur les EJB 2. Nous aurons l occasion de revenir sur le déploiement des EJB 3 et EJB 2. Il ne s agit ici que de mettre en avant quelques types de déploiements pour voir leur impact sur le nommage des composants dans JNDI. a. Nommage JNDI par défaut Pour ce test de déploiement, le fichier jar contenant les EJB (projet Chap 3 EJB) n a pas de fichier de déploiement propre au serveur, jboss.xml. Le serveur va donc utiliser des noms JNDI par défaut pour le déploiement des EJB. Chaque serveur a une stratégie de nommage différente. Il faut donc éviter d utiliser les nommages par défaut, car l application ne serait pas portable aisément d un serveur à l autre. Notez lors du déploiement des EJB, les noms JNDI utilisés. Vous pouvez retrouver ces noms dans la console où JBoss est exécuté (comme ici) ou par la vue JNDI. 16:42:14,187 INFO [BaseLocalProxyFactory] Bound EJB LocalHome Calculette to jndi 16:42:14,234 INFO [ProxyFactory] Bound EJB Home ENI Editions - All rigths reserved - Kaiss Tag - 7 -

71 ServiceCalculette to jndi ServiceCalculette Notez l utilisation d un espace de nommage local/ pour les interfaces de création locales. Les noms des interfaces d exposition des méthodes métiers sont utlisées comme nom JNDI par défaut. L application Web utilise une servlet pour invoquer les méthodes de l EJB ServiceCalculette. Afin de ne pas coder directement dans la servlet le nom JNDI, nous utilisons ici une balise <param-value> dans le web.xml. <servlet> <description></description> <display-name>calculerservlet</display-name> <servlet-name>calculerservlet</servlet-name> <servlet-class> fr.eni.editions.jboss.chap3.web.servlets.calculerservlet </servlet-class> <init-param> <description>nom JNDI de l ejb</description> <param-name>calculettejndi</param-name> <param-value>servicecalculette</param-value> </init-param> </servlet> La servlet utilise cette valeur pour retrouver l interface Home de l EJB. protected void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException String nomjndi = this.getinitparameter("calculettejndi"); String operation = request.getparameter("operation"); double nb1 = Double.parseDouble(request.getParameter("nb1")); double nb2 = Double.parseDouble(request.getParameter("nb2")); String message = ""; try double resultat = 0; InitialContext context = new InitialContext(); ServiceCalculetteHome home = (ServiceCalculetteHome)context.lookup(nomJndi); ServiceCalculette bean = home.create(); resultat = bean.calculer(operation, nb1, nb2); message += resultat; L instruction String nomjndi = this.getinitparameter("calculettejndi"); permet de récupérer le nom JNDI de l EJB dans le fichier web.xml. Les instructions InitialContext context = new InitialContext(); ServiceCalculetteHome home = (ServiceCalculetteHome)context.lookup(nomJndi); permettent de récupérer l interface Home de l EJB pour l utiliser par la suite. b. Utilisation de jboss.xml L utilisation du fichier de déploiement spécifique permet d imposer un nommage JNDI. Ceci améliore considérablement la portabilité et la maintenance, car le code n est plus affecté. Le fichier jboss.xml, sur lequel nous reviendrons plus en détail dans les chapitres suivants, se positionne dans le répertoire META INF de l archive jar de l EJB, avec le fichier ejb jar.xml ENI Editions - All rigths reserved - Kaiss Tag

72 <enterprise-beans> <session> <ejb-name>calculette</ejb-name> <local-jndi-name>ejb2/calculette/local</local-jndi-name> </session> <session> <ejb-name>servicecalculette</ejb-name> <jndi-name>ejb2/service-calculette/remote</jndi-name> </session> </enterprise-beans> L EJB Calculette ne possède pas d accès distant, aussi la balise <local-jndi-name> permet de préciser le nom JNDI de l interface de création locale. L EJB ServiceCalculette possède seulement une interface de création distante, le nom JNDI est positionné par la balise <jndi-name>. Un EJB possédant des interfaces de création locale et distante utilise les deux balises. Le suivi de ce nouveau déploiement nous montre les noms JNDI utilisés. 17:40:23,265 INFO [BaseLocalProxyFactory] Bound EJB LocalHome Calculette to jndi ejb2/calculette/local 17:40:23,281 INFO [ProxyFactory] Bound EJB Home ServiceCalculette to jndi ejb2/service-calculette/remote Il est ainsi possible d organiser les noms en fonction du type d application, du type de composant afin de mieux respecter les conventions ENC. Le fichier web.xml de l application Web est lui aussi modifié : <init-param> <description>nom JNDI de l ejb</description> <param-name>calculettejndi</param-name> <param-value>ejb2/service-calculette/remote</param-value> </init-param> Le code de la servlet n évolue pas. c. Référencement de composants avec <ejb ref> Nous pouvons maintenant choisir les noms JNDI de nos composants, mais l accès à ces composants par notre application Web est effectuée directement par le nom JNDI global de l EJB. Ceci n est pas conforme avec les spécifications ENC qui veulent qu une application utilise son propre contexte de nommage. Ce n est pas, non plus, portable d un serveur à l autre. Il nous faut donc le contexte de nommage global de l EJB avec le contexte de l application Web. La servlet doit utiliser son contexte ENC java:comp/env. Pour cela, nous allons commencer par référencer dans le fichier web.xml l EJB qui sera utlllisé. <ejb-ref> <ejb-ref-name>service</ejb-ref-name> <ejb-ref-type>session</ejb-ref-type> <home> fr.editions.eni.jboss.chap3.ejb2.servicecalculettehome </home> <remote> fr.editions.eni.jboss.chap3.ejb2.servicecalculette </remote> <ejb-link>chap_3_-_ejb#calculette</ejb-link> </ejb-ref> <ejb-ref> </ejb-ref> encapsule les balises référençant l EJB utilisé. Si les interfaces locales sont utilisées, dans le cas où le composant client de l EJB est dans la même machine virtuelle que l EJB lui même, il existe une balise <ejblocal-ref> </ejb-local-ref>. Dans notre exemple, bien que l application Web soit dans la même machine virtuelle ENI Editions - All rigths reserved - Kaiss Tag - 9 -

73 que l EJB, nous utilisons les interfaces distantes. <ejb-ref-name>service</ejb-ref-name>représente le nom JNDI dans le contexte java:comp/env. C est ce nom qui sera utilisé lors de la recherche de l EJB par la servlet. <ejb-ref-type>session</ejb-ref-type>représente le type d EJB, Session ou Entity. <home> </home> correspond au nom pleinement qualifié de l interface de création distante (de type EJBHome). Pour une interface de création locale (de type EJBLocalHome), nous utiliserions <local-home> </local-home>. <remote> </remote>correspond au nom pleinement qualifié de l interface distante d exposition des méthodes métiers (de type EJBObject), une balise <local> </local> est utilisée pour l interface distante (de type EJBLocalObject). <ejb-link> </ejb-link>permet de lier le composant en cours de description avec le <ejb-name> du fichier ejbjar.xml. Si l EJB n est pas dans le même fichier archive que le client de l EJB, alors il faut préfixer le nom de l EJB par le nom de l archive jar, avec le caractère dièse (#) comme séparateur. Avec ces indications, la servlet peut utiliser l EJB. Elle connaît : le type de l EJB ; les classes à utiliser ; le nom JNDI de l EJB dans son ENC. Il faut maintenant que le conteneur web puisse faire le lien entre l EJB déclaré dans le fichier web.xml et l EJB déployé. Le fichier jboss web.xmlpermet de faire ce lien. <jboss-web> <context-root>cwc</context-root> <ejb-ref> <ejb-ref-name>service</ejb-ref-name> <jndi-name>ejb2/service-calculette/remote</jndi-name> </ejb-ref> </jboss-web> Ce fichier complémentaire permet au conteneur de déployer l application. <jboss-web> </jboss-web> est la racine du document jboss web.xml. <context-root> </context-root>correspond au nom de l application Web. L url de l application sera ici <ejb-ref> </ejb-ref>contient les balises décrivant la liaison. Il existe aussi un <ejb-local-ref> pour l utilisation des interfaces locales. <ejb-ref-name> </ejb-ref-name>contient le nom JNDI utilisé dans le contexte de l application Web. Il doit correspondre à la balise du même nom, utilisée dans le fichier web.xml. <jndi-name> </jndi-name>contient le nom JNDI de l EJB dans le serveur JBoss. Dans notre exemple, ce nom JNDI est déclaré dans le fichier jboss.xml de l EJB (cf. précédemment). d. Référencement dans le fichier ejb jar.xml Le projet Chap 3 EJB contient deux EJB. L EJB ServiceCalculette qui utilise Calculette. Pour les mêmes raisons de portabilité, de respect des spécifications ENC et de maintenance, le référencement des EJB entre eux doit être privilégié. De même, nous allons pouvoir ajouter des entrées JNDI dans le contexte d un EJB. <enterprise-beans> <session> <ejb-name>calculette</ejb-name> </session> <session> <ejb-name>servicecalculette</ejb-name> ENI Editions - All rigths reserved - Kaiss Tag

74 <env-entry> <description>taux de TVA</description> <env-entry-name>tva</env-entry-name> <env-entry-type>java.lang.double</env-entry-type> <env-entry-value>19.6</env-entry-value> </env-entry> <ejb-local-ref> <ejb-ref-name>calcul</ejb-ref-name> <ejb-ref-type>session</ejb-ref-type> <local-home> fr.editions.eni.jboss.chap3.ejb2.calculettelocalhome </local-home> <local> fr.editions.eni.jboss.chap3.ejb2.calculettelocal </local> <ejb-link>calculette</ejb-link> </ejb-local-ref> </session> </enterprise-beans> ENI Editions - All rigths reserved - Kaiss Tag

75 Services de déploiement En standard, le répertoire deploy de la configuration serveur active est le répertoire de déploiement des composants. Il suffit donc de copier dans ce répertoire un fichier qui est conforme aux spécifications propre, au composant déployé pour que le composant soit pris en compte par le serveur. Si vous utilisez la configuration par défaut, c est à dire lancée par : run -c default le répertoire de déploiement sera <répertoire installation JBoss>server/default/deploy. Comme nous avons pu le voir précédemment, ce répertoire de déploiement peut être modifié, en modifiant le service par la console de gestion des services (http://localhost:8080/jmx console/) ou dans le fichier conf/jboss service.xml. Chaque type de fichier est pris, géré par un service de déploiement adapté. Vous retrouvez tous ces services dans la console JMX. Les principaux services de déploiement disponibles, en fonction des configurations du serveur, sont les suivants : service EARDeployer : gère le déploiement des applications d entreprise, fichiers en.ear. Le fichier de configuration de ce service est deploy/ear deployer.xml. service EJBDeployer : gère le déploiement des EJB2, fichiers en.jar. Le fichier de configuration de ce service est deploy/ejb deployer.xml. service SARDeployer : gère le déploiement des services JBoss, les MBeans, fichiers en * service.xml ou en.sar. Le fichier de configuration de ce service est conf/xmdesc/org.jboss.deployement.sardeployer xmbean.xml. service RARDeployer : gère le déploiement des connecteurs JCA, fichiers en.rar. Le fichier de configuration de ce service est deploy/jbossjca service.xml. service ConnectionFactoryDeployer : gère le déploiement des sources de données, fichiers en.* ds.xml. Ce service est un complément du service RARDeployment. Le fichier de configuration de ce service est deploy/jbossjca service.xml. service EJB3Deployer : gère le déploiement des connecteurs EJB3, fichiers en.jar. Le fichier de configuration de ce service est deploy/ejb3 interceptors asp.xml et deploy/ejb3.deployer/meta INF/jboss service.xml. ENI Editions - All rigths reserved - Bozahi Ali - 1 -

76 Conteneur Web Le rôle de conteneur Web de JBoss est assuré par un service basé sur Tomcat, projet du groupe Apache (http://tomcat.apache.org). Jusqu à la version 4.2 de JBoss, la version de Tomcat était clairement nommée dans le service, il s agissait du service jbossweb-tomcat-55.sar, qui utilisait la version 5.5 de Tomcat. À partir de la version 4.2 de JBoss, l identification de la version de Tomcat est moins aisée, car le service est assuré par jboss-web.deployer. L analyse des informations de démarrage de JBoss montre que le service est identifié par JBossWeb/2.0.1.GA. 09:08:39,640 INFO [StandardEngine] Starting Servlet Engine: JBossWeb/2.0.1.GA Le service JMX se retrouve dans la console JMX, sous Catalina. Catalina est le nom du conteneur de Servlets. JBossWeb repose sur Apache Tomcat. La version utilisée peut être identifiée en analysant les trames HTTP. À une requête sur le serveur renverra une réponse commençant par l en tête suivante : HTTP/1.x 200 OK Server: Apache-Coyote/1.1 X-Powered-By: Servlet 2.4; JBoss GA (build: SVNTag=JBoss_4_2_2_GA date= )/tomcat-5.5 Connaître la version de Tomcat peut s avérer important pour savoir avec quelles spécifications de Servlet et JSP nous pouvons travailler. Version Apache Tomcat Spécification Servlet Spécification JSP Une des grandes différences entre les versions 6 et 5.5 de Tomcat est que seule la version 6 supporte l injection de ressource par annotation. Avec Tomcat 5.5, vous ne pouvez pas utiliser private DataSource datasource; Mais vous devez alors effectuer une recherche JNDI : String nomsource = "java:comp/env/jdbc/bovoyagedsn"; try Context contextejndi = new InitialContext(); DataSource datasource = (DataSource) contextejndi.lookup(nomsource); Par défaut, le port d écoute HTTP est le port Fichier de configuration jboss service.xml ENI Editions - All rigths reserved - Kaiss Tag - 1 -

77 Le fichier de configuration du service Tomcat est jboss service.xml qui se trouve dans le répertoire <repertoire_serveur>/deploy/jboss web.deployer/meta INF, où <repertoire_serveur> est le répertoire où se trouve le serveur actif. Le fichier jboss service.xml contient la définition des alias pour les hôtes virtuels, la liaison vers le domaine de sécurité et permet le contrôle de Tomcat. Les attributs de configuration du MBean sont positionnés dans des éléments XML <attribute> de la forme <attribute name="nom_attribut">valeur attribut</attribute>. Les principaux attributs sont les suivants : DefaultSecurityDomain : domaine de sécurité JAAS (Java Authentification and Authorization Service) utilisé en l absence d une configuration explicite dans le fichier jboss web.xml du fichier WAR. UseJBossWebClassLoader : indique si Tomcat doit utiliser le chargeur de classes de JBoss, par défaut positionné à vrai (true). Ceci implique que les classes dans des répertoires WEB INF/classes et WEB INF/lib seront incorporées dans l espace de stockage commun des classes chargées, cela permet aux classes et aux ressources d être partagées entre les applications Web. LenientEjbLink : positionné à vrai par défaut, les erreurs sur ejb-link seront ignorées pour favoriser la prise en compte du jndi-name du fichier jboss web.xml. SnapshotMode : utilisé en mode cluster, admet les valeurs instant ou interval. Dans le mode instant, les changements dans les sessions sont propagés aux autres conteneurs du cluster. Dans le mode interval, cette mise à jour est effectuée à intervalles réguliers, cet intervalle est précisé par l attribut SnapshotInterval. SnapshotInterval : intervalle de mise à jour des sessions des conteneurs d un cluster en mode interval. Cet intervalle est exprimé en millisecondes, par défaut sa valeur est ms, soit 1 seconde. 2. Fichier de configuration server.xml Le fichier de configuration du serveur Tomcat lui même est server.xml qui se trouve sous <repertoire_serveur>/deploy/jboss web.deployer. Ce fichier contrôle le fonctionnement de Tomcat. Ainsi, c est dans ce fichier que sont définis les ports d écoute de Tomcat. La directive <Connector port="8080" > permet l écoute sur le port C est ici que nous définirons le port d écoute pour la mise en place du protocole HTTPS. La racine du fichier est l élément <Server> dans lequel il est possible de retrouver des éléments de déclaration des classes listeners et un élément <Service>. L élément <Service> contient d autres éléments dont : Elément <Connector> : un connecteur permet de configurer une couche de transport qui permet au client d envoyer les requêtes et de recevoir les réponses. Elément <Host> : représente une configuration d hôte virtuel. C est un conteneur d applications Web pour un nom DNS particulier. 3. Fichier de configuration web.xml Le fichier de configuration par défaut des sites web déployés est web.xml situé dans le répertoire <repertoire_serveur>/deploy/jboss web.deployer/conf. Ce fichier permet la déclaration des servlets propres à Tomcat, et la déclaration des types MIME. Chaque application Web possède son propre fichier web.xml. 4. Fichier de configuration context.xml Ce fichier de configuration contient le comportement par défaut, pour l élément Context. <Context cookies="true" crosscontext="true"> ENI Editions - All rigths reserved - Kaiss Tag

78 Il permet de mettre en place le suivi des sessions par les cookies et l accès au contexte d application entre les applications web par la méthode ServletContext.getContext(String path). 5. Gestion des ressources statiques JBoss utilise une application par défaut qui contient les ressources pour l application racine (root). Cette application par défaut est l application ROOT.war située sous le répertoire <repertoire_serveur>/deploy/jboss web.deployer. Vous pouvez y ajouter vos propres ressources statiques qui peuvent être ainsi partagées par plusieurs applications Web. Vous pouvez ainsi créer un répertoire images et y placer des images. L accès aux images se fera alors par l URL Le déploiement des applications Web sera détaillé au chapitre Déploiement d application Web, et la sécurisation des applications Web le sera au chapitre Gestion de la sécurité. ENI Editions - All rigths reserved - Kaiss Tag - 3 -

79 Service de messagerie JMS Dans les architectures distribuées hétérogènes, composées d applications différentes implémentées dans des langages pouvant être différents, la communication entre applications peut être un problème. Parmi les nombreuses solutions à cette problématique, deux grands axes se dessinent. L invocation de procédures distantes (RPC Remote Procedure Call), qui peut être effectuée avec des standards tels que RMI pour Java, DCOM pour Microsoft, ou CORBA. Le principe reste le même : invoquer un service sur une machine distante et traiter la réponse. L échange de messages entre applications. Ces messages sont véhiculés par une infrastructure particulière, appelée MOM(Middleware Oriented Messaging). Ces messages sont beaucoup plus génériques que l invocation de services distants et peuvent représentés tout type de contenu, objet sérialisé ou texte. L invocation de procédures à distance impose un couplage fort entre les applications car les deux applications doivent être actives en même temps, pour pouvoir communiquer. Les MOM permettent de casser ce couplage car les applications ne communiquent plus directement entre elles. Il existe de nombreuses solutions, commerciales ou non, de service MOM : IBM. MQSeries, BEA MessageQ, Microsoft MSMQ, L API JMS permet de spécifier un standard pour l utilisation des brokers MOM. Il existe deux modes de fonctionnement : le mode point à point (point to point) ; le mode publication/abonnement (publish/subscribe). L application qui envoie un message est un producteur, celle qui le récupère est un producteur. 1. Mode point à point Les messages sont échangés par l intermédiaire d une file d attente (message queuing). L application émettrice du message dépose celui ci dans la file. Ce message reste dans la file, jusqu à ce que l application destinataire le récupère. Le producteur ne spécifie pas l application cible, mais le nom de la file d attente. Plusieurs producteurs peuvent mettre des messages dans la file, par contre un message n est récupéré que par un seul consommateur. Entre le moment où le message est déposé et celui où il est consommé, le broker en assure la persistance. ENI Editions - All rigths reserved - Bozahi Ali - 1 -

80 Ce type de middleware est caractérisé principalement par : la persistance des messages les messages sont stockés jusqu à leur consommation ; la qualité de service garantie de livraison de message, gestion de priorités, durée de vie des messages. 2. Mode publication/abonnement C est un mode de communication point à multipoints. Chaque message est associé à un sujet (topic). Le consommateur qui veut recevoir un message va s abonner (subscribe) à un sujet. Le MOM envoie une copie du message à tous les abonnés. Le producteur du message ne connaît pas les consommateurs. C est le MOM qui gère la liste des abonnés. Ce type de middleware est caractérisé principalement par : la rapidité d échange des messages utilisation de protocoles dédiés comme IP multicast. 3. Spécification JMS Comme pour JDBC vis à vis des bases de données, l API JMS permet de normaliser l accès aux différents MOM. Les interfaces principales de cette API sont : QueueConnection ou TopicConnection : interface de connexion à la structure MOM, la classe d implémentation est créée via un Factory ; QueueSession ou TopicSession : session qui permet de créer les producteurs (QueueSender ou ENI Editions - All rigths reserved - Bozahi Ali

81 TopicPublisher) et les consommateurs (QueueReceiver ou TopicSubscripter) de messages ; Queue : la file de messages ; Topic : un sujet. 4. Modèle de programmation JMS Le modèle de programmation JMS est toujours sensiblement le même. 1. Localisation du driver JMS. Ce driver est accessible auprès de JNDI sous le nom "ConnectionFactory". 2. Création d une connexion JMS par l intermédiaire d un factory. Pour une connexion point à point, il faudra utiliser une QueueConnectionFactory, et pour une connexion publication/abonnement un TopicConnectionFactory. 3. Obtention de la session JMS auprès de la connexion. Il s agira d une QueueSession pour du point à point, ou d un TopicSession pour du publication/abonnement. 4. Recherche auprès du service JNDI de la destination JMS, par exemple "queue/testqueue" ou "topic/testtopic". 5. Création du producteur ou du consommateur. Le producteur enverra le message. Le consommateur sera averti de l arrivée d un message via l implémentation d un javax.jms.messagelistener. 6. Phase d émission ou de réception du message. 5. Les EJB orientés message Dans l architecture JEE, les EJB MD (Message Driven), MED pour Message Driven Bean, sont des composants permettant la réception des messages JMS qu ils soient point à point ou de type publication/abonnement. L utilisation et le déploiement des EJB MD seront détaillés dans le chapitre Déploiement des EJB. ENI Editions - All rigths reserved - Bozahi Ali - 3 -

82 Service de transaction JTA Plusieurs tâches unitaires peuvent concourir à l obtention d un résultat global. L ensemble des tâches unitaires sont regroupées au sein d une transaction. Ainsi, cela peut être : plusieurs écrans de saisies d informations pour l enregistrement d un nouveau client dans une application d entreprise ; ou, un ensemble de tâches permettant le débit d un compte client pour créditer un compte fournisseur. Le résultat de ces tâches unitaires doit être cohérent pour valider l écriture en base de données. Si toutes les tâches unitaires se sont correctement déroulées, l opération globale sera validée (le commit), sinon, les données utilisées par les tâches unitaires doivent revenir dans leur état initial (le rollback). Les contraintes que doit vérifier une transaction sont résumées par l acronyme ACID : Atomicité : la transaction effectue une mise à jour, ou aucune ; Cohérence : la cohérence des données doit toujours être assurée, que la transaction soit réussie ou non ; Isolation : les résultats d une transaction ne sont visibles qu une fois que cette transaction est validée ; Durabilité : une fois la transaction validée le système est dans un état stable durable. La gestion des transactions est facilitée au moyen d un ensemble d interfaces standardisées au sein de JTA (Java Transaction API). Le gestionnaire de transaction défini dans JTA repose sur une interface de base : javax.transaction.transactionmanager. JBoss met à disposition un gestionnaire de transaction au travers d un nommage JNDI : java:/transactionmanager. Les transactions peuvent devenir complexes en fonction du nombre de ressources et de serveurs impliqués : transaction locale dans laquelle sont impliqués une ressource et un serveur ; transaction distribuée sur un seul serveur mais impliquant plusieurs ressources ; transaction distribuée impliquant plusieurs serveurs et une seule ressource ; transaction distribuée impliquant plusieurs serveurs et plusieurs ressources. La gestion des transactions sera détaillée dans le chapitre Gestion des transactions. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

83 Service de connecteurs JCA L intégration d application d entreprise (EAI Enterprise Application Integration) est une architecture qui permet à des applications hétérogènes de gérer les échanges inter applications. Les échanges entre applications requièrent les éléments suivants : des connecteurs qui jouent le rôle d interface entre l architecture EAI et les applications. Ils sont à l écoute des évènements des applications et transmettent et/ou transfèrent des données depuis/vers les applications ; des couches d associations (mapping) permettant l échange des données, objets métiers, entre les différentes applications, via les connecteurs ; une couche de transport qui permet l acheminement des données entre les applications. La spécification JCA (Java Connector Architecture), à l instar de JDBC par exemple, au développeur de bénéficier d une API standard quel que soit le fournisseur de l application. Les connecteurs peuvent être vus comme des contrats système entre des applications d entreprise et le serveur d applications. L objectif est donc d assurer une collaboration entre ces éléments hétérogènes pour que les mécanismes de transaction, de sécurité et de gestion des connexions soient transparent vis à vis des applications hébergées sur le serveur. Le framework JBossCx implémente l architecture nécessaire pour l utilisation de JCA. ENI Editions - All rigths reserved - Bozahi Ali - 1 -

84 Service de sécurité JAAS JAAS (prononcez "Jazz"), pour Java Authentification and Autorisation Service, est un framework de sécurité qui a pour but d authentifier et gérer les autorisations d un utilisateur. Il faut prendre ici l utilisateur au sens large : humain, machine, objet. Des modules d authentification peuvent être chaînés les uns aux autres, utilisation d un lecteur de cartes à puce couplé à une demande de mot de passe, par exemple. L utilisateur qui passe les modules acquiert une identité virtuelle à laquelle seront associés des droits. La gestion de la sécurité sera détaillée au chapitre Gestion de la sécurité. ENI Editions - All rigths reserved - Bozahi Ali - 1 -

85 Autres services utiles 1. Service de suivi des threads et de la mémoire Ce service, géré par le MBeanjboss.system:type=ServerInfo permet de suivre l usage de la mémoire et des threads de l instance de JBoss. Vérifiez dans la console JMX les attributs du MBean et les opérations disponibles. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

86 Cliquez sur les boutons correspondant aux opérations suivantes pour visualiser l occupation mémoire de votre machine, ainsi que l état des threads. listmemorypools : affiche la taille et l utilisation des pools de mémoire dans la JVM ; listthreaddump : affiche les threads ; listthreadcpuutilization : affiche le temps CPU de chaque thread. 2. Service Mail Le MBean enregistré sous le nom jboss:service=mail permet d utiliser des sessions JavaMail au sein de JBoss. Le fichier de configuration du service est situé sous deploy/mail service.xml. <server> <mbean code="org.jboss.mail.mailservice" name="jboss:service=mail"> <attribute name="jndiname">java:/mail</attribute> ENI Editions - All rigths reserved - Kaiss Tag

87 <attribute name="user">nobody</attribute> <attribute name="password">password</attribute> <attribute name="configuration"> <!-- A test configuration --> <configuration> <!-- Change to your mail server protocol --> <property name="mail.store.protocol" value="pop3"/> <property name="mail.transport.protocol" value="smtp"/> <!-- Change to the user who will receive mail --> <property name="mail.user" value="nobody"/> <!-- Change to the mail server --> <property name="mail.pop3.host" value="pop3.nosuchhost.nosuchdomain.com"/> <!-- Change to the SMTP gateway server --> <property name="mail.smtp.host" value="smtp.nosuchhost.nosuchdomain.com"/> <!-- The mail server port --> <property name="mail.smtp.port" value="25"/> <!-- Change to the address mail will be from --> <property name="mail.from" <!-- Enable debugging output from the javamail classes --> <property name="mail.debug" value="false"/> </configuration> </attribute> <depends>jboss:service=naming</depends> </mbean> </server> Ce fichier doit être configuré avec vos paramètres pour pouvoir utiliserjavamail correctement et pouvoir se connecter aux serveurs SMTP et POP. Les noms des propriétés sont assez explicites. Vous y retrouvez de manière classique toute la configuration nécessaire pour aller déposer des e mails et les récupérer. Par exemple : <property name="mail.pop3.host" value="pop3.nosuchhost.nosuchdomain.com"/> Cette propriété vous permet de préciser, dans l attribut value, le serveur POP. Pour le provider Orange cette valeur pourrait être : pop.orange.fr. Ce qui donnerait : <property name="mail.pop3.host" value="pop.orange.fr"/> L API JavaMail étant une API d assez bas niveau, très proche du protocole, il peut être intéressant d utiliser des bibliothèques tierces, comme la librairie commons- du groupe Apache que vous pouvez télécharger à l adresse Le codage d un envoi de mail devient alors très simple Simple mail = new Simple (); mail.setmailsessionfromjndi("java:/mail"); mail.setsubject("test MailService"); mail.setmsg("bonjour - cela fonctionne"); mail.send(); 3. Service Log4j Le MBean Log4jService permet la configuration du système de journalisation Log4j (projet du groupe Apache). Log4j ENI Editions - All rigths reserved - Kaiss Tag - 3 -

88 est utilisé par JBoss comme système de journalisation. Les attributs suivants peuvent être configurés : ConfigurationURL : URL du fichier de configuration de Log4j, par défaut resource:log4j.xml qui correspond au fichier conf/log4j.xml ; RefreshPeriod : délai de prise en compte des changements de configuration de Log4j, 60 secondes par défaut ; CatchSystemErr : booléen indiquant si le flux System.err doit être redirigé vers la catégorie Log4j STDERR, par défaut, mis à vrai ; CatchSystemOut : booléen indiquant si le flux System.out doit être redirigé vers la catégorie Log4j STDOUT, par défaut, mis à vrai ; Log4jQuietMode : doit être mis à vrai, se reporter au bug Log4j numéro Vous pouvez configurer le service pour avoir plus ou moins d informations. Par exemple, lors du débogage des EJB CMP, il peut être intéressant de suivre l envoi des requêtes vers la base de données. Vous pouvez ajouter l appender suivant : <appender name="cmp" class="org.apache.log4j.consoleappender"> <errorhandler class="org.jboss.logging.util.onlyonceerrorhandler"/> <param name="target" value="system.out"/> <layout class="org.apache.log4j.patternlayout"> <param name="conversionpattern" value="%dabsolute %-5p [%c1] %m%n"/> </layout> </appender> 4. TimerService La spécification JMX définie un MBean timer qui peut envoyer des événements temporels à d autres objets. JBoss fournit un service de configuration du MBean timer. Ce TimerService permet d aider à la configuration des propriétés suivantes : NotificationType : type de la notification qui doit être générée. En effet, un Timer peut être configuré par plusieurs TimerService, le type de notification pourra alors servir de filtre ; NotificationMessage : message pouvant être associé à la notification ; TimerPeriod : période entre les notifications, exprimée en millisecondes, secondes, minutes et heures ; Repeatitions : nombre de notifications que le timer doit effectuer, par défaut, zéro pour l infini ; TimerBean : nom du timer que le service TimerService doit configurer. Il existe aussi un écouteur qui peut être utilisé pour journaliser des messages sur un timer, il s agit de la classeorg.jboss.monitor.services.notificationlistener. Nous allons créer un service de timer. Pour ce faire, nous allons d abord créer un fichier timer service.xml qui comprend les lignes suivantes : <server> <mbean code="javax.management.timer.timer" name="jboss.monitor:name=chronos,type=timer" /> </server> Vérifiez que JBoss est bien démarré, et copiez ce fichier dans le répertoire deploy de votre configuration serveur ENI Editions - All rigths reserved - Kaiss Tag

89 Vérifiez qu il n y a pas d erreur dans la console. Ouvrez la console d affichage des nommages JNDI. Vous devez trouver le service déployé. Vous pouvez cliquer sur le lien pour voir les attributs et les opérations disponibles sur le MBean. Voici une nouvelle manière de déployer un MBean, par un fichier XML contenant une configuration serveur. Nous allons maintenant configurer notre MBean avec un service TimerService. Pour cela, nous allons ajouter dans notre fichier timer service.xml les lignes suivantes : <mbean code="org.jboss.monitor.services.timerservice" name="jboss.monitor:name=chronos,type=timerservice"> <attribute name="notificationtype"> jboss.monitor. Chronos </attribute> <attribute name="notificationmessage"> Bonjour tout le monde!!! </attribute> <attribute name="timerperiod">10sec</attribute> <depends optional-attribute-name="timermbean"> jboss.monitor:name=chronos,type=timer </depends> </mbean> Nous configurons ici l envoi d un message "Bonjour tout le monde!!!" toutes les 10 secondes. Pour que notre message soit affiché, nous allons mettre en place un écouteur. Toujours dans le fichier timer service.xml, ajoutons les lignes suivantes : <mbean code="org.jboss.monitor.services.notificationlistener" name="jboss.monitor:service=notificationlistener"> <attribute name="subscriptionlist"> <subscription-list> <mbean name="jboss.monitor:name=chronos,type=timer" /> </subscription-list> </attribute> </mbean> Après chaque modification du fichier, supprimez celui qui est dans le répertoire deploy pour y mettre la nouvelle version à la place. Si vous regardez la console JNDI, vous devez avoir les trois services déployés : Dans la console de JBoss, vous devez avoir l affichage des messages : ENI Editions - All rigths reserved - Kaiss Tag - 5 -

90 17:35:05,484 INFO [NotificationListener] Got notification (#1): javax.management.timer.timernotification[source=jboss.monitor:name= Chronos,type=Timer][type=jboss.monitor.chronos][message=Bonjour tout le monde!!!], handback: null Le fichier complet timer service.xml est le suivant : <server> <mbean code="javax.management.timer.timer" name="jboss.monitor:name=chronos,type=timer" /> <mbean code="org.jboss.monitor.services.timerservice" name="jboss.monitor:name=chronos,type=timerservice"> <attribute name="notificationtype">jboss.monitor.chronos</attribute> <attribute name="notificationmessage">bonjour tout le monde!!!</attribute> <attribute name="timerperiod">10sec</attribute> <depends optional-attribute-name="timermbean"> jboss.monitor:name=chronos,type=timer </depends> </mbean> <mbean code="org.jboss.monitor.services.notificationlistener" name="jboss.monitor:service=notificationlistener"> <attribute name="subscriptionlist"> <subscription-list> <mbean name="jboss.monitor:name=chronos,type=timer" /> </subscription-list> </attribute> </mbean> </server> Tout MBean peut implémenter un écouteur pour être invoqué par le TimerService. 5. Service de planification À la différence du TimerService, leschedulerservice peut directement invoquer des méthodes callback sur des instances de classes quelconques, ou une opération d un MBean. Les attributs suivants sont utilisés pour configurer le MBean : InitialStartDate : date de départ de la planification. Peut être NOW qui correspond à la date courante plus une seconde, la valeur en millisecondes depuis le 01/01/1970 ou une chaîne du type "M/d/yy h:m a". Si la date est antérieure à la date de démarrage du serveur, une nouvelle date est calculée, qui respecte le délai entre les répétitions, défini dans SchedulePeriod ; InitialRepetition : nombre de fois où le service invoquera la méthode callback, 1 si l infini ; StartAtStartup : booléen indiquant si la planification démarre avec le service ; SchedulePeriod : délai en millisecondes entre deux appels de la méthode callback ; SchedulableClass : nom complet de la classe qui implémente l interface org.jboss.varia.scheduler.schedulable ; SchedulableArguments : liste des arguments, séparés par une virgule, pour le constructeur de la classe d implémentation ; SchedulableArgumentTypes : liste des types des arguments, séparés par une virgule ; SchedulableMBean : nom complet du MBean cible, qui peut être invoqué ; ENI Editions - All rigths reserved - Kaiss Tag

91 SchedulableMBeanMethod : nom de la méthode invoquée, sur le MBean cible. Voici une classe de test triviale qui implémente l interface org.jboss.varia.scheduler.schedulable. Elle se trouve dans la librairie scheduler plugin.jar. Seule une méthode perform(date,long) est présente dans cette interface. Cette méthode reçoit en paramètres, la date de l appel et le délai de répétition. package fr.editions.eni.jboss.service; import java.util.date; import org.jboss.varia.scheduler.schedulable; public class TestSchedulable implements Schedulable private String nom; private long numero; public TestSchedulable(String nom, long numero) this.nom = nom; this.numero = public void perform(date arg0, long arg1) System.out.println(">>> Bonjour de la part de "+nom); Cette classe a été mise dans une archive jar, qui a été copiée dans le répertoire lib de la configuration serveur. Voici le fichier test scheduler service.xml qui permettra de lancer le service : <server> <mbean code="org.jboss.varia.scheduler.scheduler" name="jboss.eni:service=scheduler"> <attribute name="startatstartup">true</attribute> <attribute name="schedulableclass"> fr.editions.eni.jboss.service.testschedulable </attribute> <attribute name="schedulablearguments"> TEST, </attribute> <attribute name="schedulableargumenttypes"> java.lang.string,long </attribute> <attribute name="initialstartdate">now</attribute> <attribute name="scheduleperiod">60000</attribute> <attribute name="initialrepetitions">-1</attribute> </mbean> </server> Les attributs correspondant au passage des paramètres pour le constructeur de la classe de test s y retrouvent. <attribute name="schedulablearguments"> TEST, </attribute> <attribute name="schedulableargumenttypes"> java.lang.string,long </attribute> Le fichier test scheduler service.xml doit être placé dans le répertoire deploy. Il ne doit pas y avoir d erreur dans la console du serveur. Si le déploiement a été correctement effectué, les messages doivent s afficher dans la console, toutes les 60 secondes. 19:34:15,328 INFO [STDOUT] >>> Bonjour de la part de TEST 19:35:15,328 INFO [STDOUT] >>> Bonjour de la part de TEST ENI Editions - All rigths reserved - Kaiss Tag - 7 -

92 19:36:15,328 INFO [STDOUT] >>> Bonjour de la part de TEST ENI Editions - All rigths reserved - Kaiss Tag

93 Fichiers de configuration du serveur Les fichiers de configuration suivants sont relatifs à la configuration de serveur par défaut, <répertoire installation JBoss>/server/default. conf/jbossjta properties.xml : fichiers de configuration des propriétés du service de transaction ; conf/jboss log4j.xml : fichier de configuration pour le service de journalisation Log4j ; conf/jboss minimal.xml : exemple d un fichier de configuration minimal, cette configuration correspond à celle utilisée dans le fichier jboss service.xml dans la configuration serveur minimal ; conf/jboss service.xml : décrit les services de base de la configuration serveur default ; conf/jndi.properties : paramètres par défaut du contexte JNDI InitialContext lorsque celui ci est instancié sans paramètres ; conf/login config.xml : fichier de configuration pour les authentifications ; conf/standardjboss.xml : configuration par défaut du conteneur d EJB 2 ; conf/standardjbosscmp jdbc.xml : configuration par défaut pour le mapping objet relationnel, des EJB 2 entités de type CMP ; deploy/jboss web.deployer/server.xml : configuration par défaut du conteneur Web (Tomcat). ENI Editions - All rigths reserved - Kaiss Tag - 1 -

94 Persistance des objets Dans l architecture en couches des applications distribuées, la couche de persistance permet de faire le lien avec la sauvegarde physique des données. Nous avons des objets qui représentent des entités avec des états : une personne avec son nom, son âge, sa date de naissance... ; un compte bancaire avec son numéro, son solde... ; une adresse ; etc. Ces objets ont des états en mémoire et si l application est arrêtée, cet état n est pas sauvegardé. Le développeur doit donc se soucier du maintien de l état dans une base de données : la persistance. Le nec plus ultra pour le développeur serait qu il n ait pas à se soucier des mécanismes sous jacents qui permettent aux objets d être "persistés". Ceci arrivera peut être un jour... Cette sauvegarde est principalement effectuée dans une base de données, en général, relationnelle : Oracle, MySql, PosgreSQL, HSQLDB. Elle peut aussi être effectuée par sérialisation utilisation de fichiers, de XML, etc. Cette couche va encapsuler les mécanismes qui auront la responsabilité de sauvegarder, modifier ou restaurer l état de certains des objets métiers de l application. Il ne doit pas y avoir de requêtes SQL, ou autres, qui parsèment l ensemble du code des autres couches applicatives. Idéalement, le développeur ne devrait pas avoir à se soucier des mécanismes sous jacents utilisés pour permettre la persistance de ses objets. Cette couche doit aussi permettre de garder une certaine indépendance vis à vis de l architecture de la base de données utilisée. Les couches de persistance s appuient sur l API JDBC. De très nombreuses implémentations de cette couche peuvent être envisagées : codage de la couche par le développeur en utilisant l API JDBC ; utilisation du framework Hibernate qui est inclus dans la distribution JBoss ; utilisation des EJB entités ; utilisation d autres frameworks Codage du pattern DAO Si le codage de la couche est effectué par le développeur, celui ci mettra certainement en pratique le design pattern DAO (Data Acces Object). Ce design pattern de conception montre comment encapsuler tous les accès aux sources de données. En général, à chaque objet métier est associé un objet DAO qui contient le code SQL nécessaire à la sauvegarde, modification, suppression en base de données. Les sources présentés ici, sont issues du projet "Chap4 JDBC". Par exemple, une classe métier Ville est associée à une classe VilleDAO qui contiendra les méthodes permettant l ajout, les recherches en base de données, etc. Les méthodes de cette classe DAO renvoient un objet, ou des collections d objets, de type Ville. Les classes de type Ville sont des classes en général, très simples, constituées par des méthodes de type setter/getter, appelées aussi POJO (Plain Old Java Object). Le codage de ces classes DAO n est pas complexe, mais s avère très vite fastidieux, voire ennuyeux car répétitif. En général, des méthodes nommées getquelquechosebyautrechose( ) encapsulent des requêtes SQL du type "SELECT quelquechose FROM table WHERE colonne=autrechose;". La classe Ville : public class Ville implements Serializable private String codepostal; private String nom; ENI Editions - All rigths reserved - Kaiss Tag - 1 -

95 public Ville() public Ville(String nom, String cp) this.nom = nom; this.codepostal = cp; public String getcodepostal() return codepostal; public void setcodepostal(string codepostal) this.codepostal = codepostal; public String getnom() return nom; public void setnom(string nom) this.nom = nom; public String tostring() return this.nom + " - " + this.codepostal; Voici quelques extraits de la classe VilleDAO : public class VilleDAO private DAO dao = null; public VilleDAO(DAO dao) this.dao = dao; public Collection<Ville> getvillesbycodepostal(string cp) throws ApplicationDAOException Collection<Ville> villes = new ArrayList<Ville>(); String sql = "SELECT * FROM codes_postaux WHERE cp=?"; Connection con = null; try con = dao.getconnection(); PreparedStatement st = con.preparestatement(sql); st.setstring(1, cp); ResultSet rs = st.executequery(); while (rs.next()) villes.add(this.construireville(rs)); catch (SQLException e) throw new ApplicationDAOException(e); ENI Editions - All rigths reserved - Kaiss Tag

96 finally try dao.releaseconnection(con); catch (SQLException e) return villes;... Vous remarquerez que cette classe est construite sur une classe DAO, que nous présenterons dans la section suivante. Remarquez aussi que les exceptions levées sont d un type propre à l application ce qui permet de ne pas "polluer" les autres couches de l application par des Exceptions trop spécifiques qui exposent les APIs utilisées. En effet, la couche DAO gère la persistance, si une exception d une API de bas niveau remonte vers la couche métier ou la couche de présentation, on supprime le couplage faible qui doit exister entre les couches de l application. La classe ApplicationDAOException vient encapsuler le type réel de l exception. Cette classe est très simple et permet de changer la couche DAO, qui peut générer d autres types d exceptions, sans impacter les couches utilisatrices. public class ApplicationDAOException extends Exception private static final long serialversionuid = 1L; public ApplicationDAOException() public ApplicationDAOException(String cause) super(cause); public ApplicationDAOException(Exception e) super(e); public ApplicationDAOException(String cause,exception e) super(cause,e); Le modèle général de codage utilisant JDBC est le suivant : obtention d une connexion au serveur de base de données ; création d une requête SQL ; exécution de la requête SQL ; traitement du jeu de résultat ; fermeture de la connexion. Le codage des classes DAO est toujours basé sur le même schéma, symbolisé par l acronyme CRUD (Create, Read, Update and Delete) pour la création, la lecture, la mise à jour et la suppression des enregistrements en base. 2. Source de données et pool de connexion ENI Editions - All rigths reserved - Kaiss Tag - 3 -

97 Si le codage lui même n est pas complexe, il se pose malgré tout, très vite, dans les environnements distribués, un problème important : comment gérer les connexions et déconnexions à la base de données. De manière classique, la connexion et la déconnexion sont effectuées via la classe java.sql.drivermanager de JDBC. connexion = DriverManager.getConnection(url,user,pswd) C est donc le développeur qui gère les connexions. Mais, par exemple pour un site web, les cycles de connexion/déconnexion peuvent être très fréquents et le nombre de connexions nécessaires à un instant donné, très important. Ce mode de fonctionnement est donc inadapté. Pour pallier à ce problème, les serveurs d applications fournissent un service de source de données qui utilise un mécanisme de pool de connexion. Le développeur n utilise plus le DriverManager, mais une classe javax.sql.datasource qui est fournie par le serveur. Attention, cette classe n est utilisable que dans un environnement qui peut la fournir, elle ne l est pas dans une application autonome. Ce n est plus l application qui gère les connexions, c est le serveur. Le serveur maintient un certain nombre de connexions qui sont physiquement connectées à la base de données, et qui sont distribuées au fur et à mesure des besoins de l application. L appel de la méthode getconnection() permet de récupérer une connexion dans le pool. Une connexion est remise dans le pool après un appel à la méthode close(), ou après un timeout. Les sources de données sont montées dans le nommage JNDI par le serveur. Pour utiliser une source de données, il faut donc : effectuer une recherche JNDI ; demander une connexion. Une classe spécifique peut gérer les connexions et déconnexions à la base. C est ici, la classe appelée DAO qui permet d encapsuler le type réel utilisé pour l accès aux objets java.sql.connection. En effet, une application non distribuée utilisera le DriverManager, tandis qu une application exécutée au sein d un conteneur utilisera de préférence une DataSource. public class DAO String driver; String url; String user; String pswd; DataSource datasource=null; public DAO(String driver, String url, String user, String pswd) throws ClassNotFoundException this.driver = driver; this.url = url; this.user = user; this.pswd = pswd; Class.forName(driver); public DAO(DataSource datasource) this.datasource = datasource; public Connection getconnection() throws SQLException Connection connexion = null; if(this.datasource!=null) connexion = this.datasource.getconnection(); else connexion = DriverManager.getConnection(url,user,pswd); ENI Editions - All rigths reserved - Kaiss Tag

98 return connexion; public void releaseconnection(connection con) throws SQLException con.close(); Les classes du modèle de VilleDAO vont demander à la classe DAO une connexion à la base. La classe DAO, en fonction de son mode de construction, par une DataSource, ou par les paramètres de connexion, renverra la connexion adéquate. 3. Autre modèles de conception de la couche de persistance Lors du codage des couches DAO, il est très vite visible que le code est très répétitif et pourrait presque être généré automatiquement. L objectif des solutions présentées ici est donc d éviter le codage des requêtes SQL avec l utilisation de JDBC. D autres solutions sont envisageables : la sérialisation des instances ; utilisation des EJB (EJB 2 ou EJB 3) dont le déploiement est détaillé dans cet ouvrage ; utilisation de JDO (Java Data Object) qui va enrichir le pseudo code de la classe à persister ; utilisation de framework de mapping entre les classes et leur représentation en base, comme Hibernate (abordé plus loin), ou ibatis. ENI Editions - All rigths reserved - Kaiss Tag - 5 -

99 Paramétrage des sources de données JBoss fournit un moyen très simple et très souple de configurer une source de données. La description de la configuration de connexion à la base de données se trouve dans un fichier qui doit être nommé yyy ds.xml où yyy est le nom (arbitraire) de la configuration de votre source de données et ds pour data source. Ainsi, une configuration pour une base de données MySql pourrait être contacts ds.xml. Ce fichier est simplement mis dans un répertoire de déploiement pour être pris en compte par JBoss. La prise en compte de cette configuration est effectuée par le service JCA de JBoss. Le modèle de nommage du fichier est nécessaire pour qu il soit pris en compte par la classe XSLSubDeployer. Plusieurs sources de données peuvent être configurées dans un même fichier, mais une bonne habitude est de mettre en place un fichier par source de données, ou par base de données. Le fichier <installation_jboss>/docs/dtd/jbossds_1_5.dtd décrit la DTD complète de la structure de ce fichier de configuration. Nous allons décrire ici les principaux éléments. 1. Principaux éléments du fichier de configuration a. Éléments de base <datasources> : élément racine du fichier de configuration yyy ds.xml. <!ELEMENT datasources (mbean local-tx-datasource xa-datasource no-tx-datasource ha-local-tx-datasource ha-xa-datasource)*> <mbean> : des MBeans peuvent être spécifiés pour qu ils puissent être configurés avant leur utilisation par la source de données ; <no-tx-datasource> : utilisé pour des sources de données sans le support de gestion des transactions ; <local-tx-datasource>, <xa-datasource> : sources de données avec support transactionnel. Lorsqu une connexion doit être utilisée, ou qu une transaction démarre, un contrôle de l existence d une connexion déjà engagée dans la transaction est effectué, si cette connexion existe, elle est utilisée. <xa-datasource> permet la gestion des transactions distribuées ; <ha-local-tx-datasource>, <ha-xa-datasource> : éléments identiques à <local-tx-datasource> et <xadatasource> avec ajout d un module expérimental de gestion de pannes sur un cluster de bases de données. Ce module ne doit donc pas être utilisé sur un serveur en production. b. Principaux éléments de configuration des sources de données Les éléments suivants doivent être mis dans un des cinq éléments précédents qui définissent une source de données. <jndi-name> : nom JNDI dans le contexte avec lequel la source de données sera liée. Le nom JNDI est créé par défaut dans le contexte java: qui n est pas partagé en dehors de la machine virtuelle du serveur. <user-java-context> : si cet élément contient false, alors la source de données est liée au contexte global JNDI, donc accessible en dehors du serveur. Si cet élément est absent, il est par défaut positionné à true. <user-name> : identifiant de connexion à la base de données. <password> : mot de passe de connexion à la base de données. Cet élément, comme l élément <user-name>, peut être redéfini par l application lors de l invocation de getconnection( ), ou par un contexte sécurité JAAS. <min-pool-size> : minimum de connexions que doit contenir le pool de connexions. <max-pool-size> : nombre maximum de connexions dans le pool de connexions. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

100 <blocking-timeout-millis> : délai d attente (en millisecondes) d une connexion avant le déclenchement d une exception, par défaut : 500 ms. <idle-timeout-minutes> : délai maximum (en minutes) avant qu une connexion inutilisée soit fermée. <new-connection-sql> : ordre SQL devant être exécuté lorsqu une connexion est créée. <exception-sorter-class> : nom complet de la classe implémentant l interface org.jboss.resource.adapter.jdbc.exceptionsorter, qui permet l encapsulation des exceptions de connexion. Les éléments suivants sont communs aux sources de données locale <no-tx-datasource> et <local-txdatasource>. <connection-url> : URL de connexion au driver JDBC, de la forme jdbc:mysql://localhost:3306/contacts. <driver-class> : nom complet de la classe driver JDBC utilisée, par exemple : com.mysql.jdbc.driver. Le répertoire <installation_jboss>/docs/examples/jca contient des fichiers type de configuration vers différentes sources de données. Exemple de fichier de base pour une connexion vers le serveur MySql : <datasources> <local-tx-datasource> <jndi-name>mysqlcontacts</jndi-name> <driver-class>com.mysql.jdbc.driver</driver-class> <connection-url>jdbc:mysql:///contacts</connection-url> <user-name>eni</user-name> <password>password</password> <min-pool-size>5</min-pool-size> <max-pool-size>20</max-pool-size> </local-tx-datasource> </datasources> Attention, bien que le déploiement des sources de données par le ficher yyy ds.xml fonctionne, il arrive que des changements sur le fichier déployé ne soient pas pris en compte. Redémarrez JBoss, si cela persiste, c est certainement dû au fait que votre fichier est mal renseigné. Vérifiez la console du serveur pour y voir d éventuels problèmes. Vérifiez bien que votre fichier suive le modèle yyy ds.xml ENI Editions - All rigths reserved - Kaiss Tag

101 Hibernate Hibernate est un framework de persistance d objets java. C est un ORM (Object Relationnal Mapping), c est à dire qu il prend en charge le mapping entre un objet java de type JavaBean et la base de données. JBoss intègre Hibernate depuis la version 4.0. Pour éviter les confusions entre les JavaBeans et les EJB, le terme POJO (Plain Old Java Object) est utilisé pour désigner les classes java très simples. Ces classes obéissent aux spécifications de base des JavaBean. Elles sont sérialisables, possèdent un constructeur par défaut et des getters/setters pour accéder aux propriétés. Le schéma précédent montre une vue très simplifiée du framework. L architecture d Hibernate est très flexible et peut gérer les transactions, les sessions, etc. Nous allons illustrer ici la manière de configurer Hibernate en tant que service JBoss, nous ne présenterons pas le framework Hibernate et son utilisation. Le lecteur intéressé pourra consulter le site de référence d Hibernate : où il pourra trouver une documentation très fournie, claire... et en français. Hibernate utilise une base de données et des propriétés de configuration, pour fournir un service de persistance d objets. Les fichiers XML de configuration d Hibernate (fichiers HBM) vont associer les propriétés des objets avec les champs des tables de la base de données. Nous utiliserons des objets de type POJO qui vont traverser toutes les couches applicatives, ce sont les TO, pour Transfer Object. Le fichier d association Hibernate assure la liaison entre l objet et la base de données. L exemple présenté dans ce chapitre reprend les projets "Chap 4 Hibernate" et "Chap 4 Web", ces deux projets devant être déployés sous JBoss. Dans cet exemple, nous afficherons une liste de destinations de voyage accessible par un site web, à l adresse : La classe POJO qui nous sert d objet de transfert est la suivante : public class DestinationTO implements Serializable private long id; private String pays; private String description; public DestinationTO() public long getid() return id; public void setid(long id) this.id = id; ENI Editions - All rigths reserved - Kaiss Tag - 1 -

102 public String getpays() return pays; public void setpays(string pays) this.pays = pays; public String getdescription() return description; public void setdescription(string description) this.description = description; public String tostring() return this.pays+" : "+this.description; Cette classe possède trois propriétés : id : est le reflet de l identifiant unique en base de données. Cet identifiant est indispensable pour que Hibernate puisse mapper l objet avec l enregistrement en base de données, et le synchroniser, si nécessaire. pays : correspond au pays de la destination. description : correspond à une description de la destination. Pour chacune de ces propriétés, nous avons une méthode getter et une méthode setter. Le fichier XML qui associe la classe aux champs en base de données est le fichier Destination.hbm.xml : <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="fr.editions.eni.chap4.to"> <class name="destinationto" table="destinations" > <id name="id" column="kp_destination"> <generator class="native" /> </id> <property name="pays" /> <property name="description"/> </class> </hibernate-mapping> Nous retrouvons ici les éléments suivants : <hibernate-mapping> : définit les associations entre les propriétés des classes et la base de données. L attribut package définit le package dans lequel se trouvent les classes, décrites dans les associations. <class> : définit quelle classe est associée à quelle table, au travers des attributs name et table. Le package n est pas précisé car il a été défini dans l attribut package de l élément parent. <id> : décrit l association sur l identifiant unique. Le nom de l identifiant dans la classe est précisé par l attribut name, l attribut column définissant le nom de la colonne dans la table ENI Editions - All rigths reserved - Kaiss Tag

103 <generator> définit dans l attribut class, la stratégie de génération de l identifiant unique en base, qui correspond ici, à une génération par la base de données. Les stratégies peuvent être : increment : généré par Hibernate (attention au mode cluster) ; native : généré par la base de données ; assigned : assigné, car il s agit d une clé primaire naturelle. <property> définit l association entre une propriété de la classe dans l attribut name, et une colonne, en base de données, dans l attribut column. Si l attribut column n est pas présent, Hibernate considère que le nom de la colonne est le même que celui de la propriété. Nous devons ensuite créer le servie Hibernate. Pour cela, nous allons créer une MBean dont le fichier de configuration jboss service.xml est le suivant : <mbean code="org.jboss.hibernate.jmx.hibernate" name="jboss.har:service=hibernate"> <attribute name="datasourcename"> java:/jdbc/bovoyageds </attribute> <attribute name="dialect"> org.hibernate.dialect.mysqldialect </attribute> <attribute name="sessionfactoryname"> java:/hibernate/sessionfactory </attribute> <attribute name="showsqlenabled">true</attribute> <attribute name="cacheproviderclass"> org.hibernate.cache.hashtablecacheprovider </attribute> </mbean> Il comprend les éléments suivants : <mbean> : spécifie le nom du service et la classe d implémentation ; <attribute name="datasourcename"> : reprend la valeur d une source de données liée au contexte JNDI, comme nous l avons vu dans la section Paramétrage des sources de données de ce chapitre ; <attribute name="dialect"> : permet de préciser quel type de SQL est utilisé. Ici, nous utilisons le SQL de MySQL ; <attribute name="sessionfactoryname"> : définit le nom JNDI de la classe de fabrication des sessions Hibernate. Cette classe sera utilisée par notre application pour récupérer une session Hibernate ; <attribute name="cacheproviderclass"> : définit la classe qui implémente la stratégie de cache, utilisée par JBoss ; <attribute name="showsqlenabled"> : permet de visualiser le code SQL généré par Hibernate dans la console de JBoss, ou dans les fichiers log. Le projet "Chap 4 Hibernate" doit être déployé sous forme d un fichier HAR dans le serveur JBoss. Sauf plugin spécifique, ou définition d une tâche Ant, Eclipse ne gère pas les archives Hibernate. Une archive HAR est constituée des classes et fichiers de mapping, ainsi que le fichier de configuration du service qui se trouve dans le META INF de l archive. Nous allons donc voir comment déployer notre projet. Une fois le projet importé sous Eclipse, ouvrez le, puis sélectionnez le, et effectuez un clic droit dessus. Choisissez l option Export du menu contextuel. Un assistant d exportation s ouvre alors. ENI Editions - All rigths reserved - Kaiss Tag - 3 -

104 Dans le menu General, choisissez l item Archive File, puis cliquez sur le bouton Next ENI Editions - All rigths reserved - Kaiss Tag

105 Ouvrez le projet Chap 4 Hibernate situé dans la partie gauche. Désélectionnez la case à cocher du projet et sélectionnez les cases à cocher situées en face de "META INF" et "fr" (début du package) dans le répertoire bin. Sélectionnez le répertoire de déploiement sur le serveur et donnez un nom à votre archive, en prenant garde de bien lui donner l extension har. Vérifiez que l option Create only selected directories est cochée, puis cliquez sur le bouton Finish. Vous devez suivre dans la console le déploiement du service Hibernate. 13:59:18,390 INFO [SettingsFactory] Default batch fetch size: 1 13:59:18,390 INFO [SettingsFactory] Generate SQL with comments: disabled 13:59:18,390 INFO [SettingsFactory] Order SQL updates by primary key: disabled 13:59:18,390 INFO [SettingsFactory] Order SQL inserts for batching: disabled 13:59:18,390 INFO [SettingsFactory] Query translator: org.hibernate.hql.ast. ASTQueryTranslatorFactory 13:59:18,390 INFO [ASTQueryTranslatorFactory] Using ASTQueryTranslator Factory 13:59:18,390 INFO [SettingsFactory] Query language substitutions: 13:59:18,390 INFO [SettingsFactory] JPA-QL strict compliance: disabled 13:59:18,390 INFO [SettingsFactory] Second-level cache: enabled 13:59:18,390 INFO [SettingsFactory] Query cache: disabled 13:59:18,390 INFO [SettingsFactory] Cache provider: org.hibernate.cache. HashtableCacheProvider 13:59:18,390 INFO [SettingsFactory] Optimize cache for minimal puts: disabled 13:59:18,390 INFO [SettingsFactory] Structured second-level cache entries: ENI Editions - All rigths reserved - Kaiss Tag - 5 -

106 disabled 13:59:18,406 INFO [SettingsFactory] Echoing all SQL to stdout 13:59:18,406 INFO [SettingsFactory] Statistics: disabled 13:59:18,406 INFO [SettingsFactory] Deleted entity synthetic identifier rollback: disabled 13:59:18,406 INFO [SettingsFactory] Default entity-mode: pojo 13:59:18,406 INFO [SettingsFactory] Named query checking : enabled 13:59:18,437 INFO [SessionFactoryImpl] building session factory 13:59:18,687 INFO [SessionFactoryObjectFactory] Not binding factory to JNDI, no JNDI name configured 13:59:18,687 INFO [NamingHelper] JNDI InitialContext properties: 13:59:18,687 INFO [Hibernate] SessionFactory successfully built and bound into JNDI [java:/hibernate/sessionfactory] Dans la vue des noms JNDI déployés sous JBoss, vous devez aussi retrouver le fabricant de session, sous le contexte java:. +- hibernate (class: org.jnp.interfaces.namingcontext) +- SessionFactory (class: org.hibernate.impl.sessionfactoryimpl) +- timedcachefactory (class: javax.naming.context) La partie client est constituée d une application Web "Chap 4 Web" qui affiche les destinations disponibles. La recherche de la session Hibernate est encapsulée dans une classe de localisation ServiceLocator. public class ServiceLocator private static final String HIBERNATE_SESSION_FACTORY = "java:/hibernate/sessionfactory"; public static SessionFactory gethibernatesessionfactory() SessionFactory sessionfactory = null; try Context ctx = new InitialContext(); sessionfactory = (SessionFactory) ctx.lookup(hibernate_session_factory); catch (Exception e) e.printstacktrace(); return sessionfactory; public static Session gethibernatesession() Session session = null; session = gethibernatesessionfactory().opensession(); return session; Le nommage JNDI utilisé ici est le nommage global. Nous aurions pu utiliser un nom local en liant le nommage global au sein des fichiers jboss web.xml et web.xml. La servlet qui utilise la session Hibernate, invoque la méthode gethibernatesession() du ServiceLocator. public class DestinationsServlet extends javax.servlet.http.httpservlet implements javax.servlet.servlet static final long serialversionuid = 1L; protected void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException List destinations = new ArrayList(); ENI Editions - All rigths reserved - Kaiss Tag

107 Session hibernate = null; hibernate = ServiceLocator.getHibernateSession(); Criteria criteria = hibernate.createcriteria(destinationto.class); destinations = criteria.list(); request.setattribute("destinations", destinations); RequestDispatcher rd = this.getservletcontext().getrequestdispatcher("/destinations.jsp"); rd.forward(request, response); protected void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException doget(request,response); La servlet récupère ensuite la liste des destinations et met cette liste dans un contexte de requête pour que la page destinations.jsp puisse l afficher. La récupération de la liste des destinations passe par la création d un objet Criteria, qui équivaudra à un "SELECT * FROM destinations". Nous avons pu interroger notre base de données sans une seule ligne de code JDBC. Maintenant, nous pourrions ajouter, supprimer ou modifier des destinations sans rien ajouter, en utilisant la session Hibernate. Pour résumer l utilisation que nous avons faite d Hibernate : 1. création de la source de données, fichier ds.xml ; 2. création des POJO ; 3. création du fichier de mapping, fichier hbm.xml ; 4. création du fichier décrivant le service Hibernate ; 5. déploiement du fichier HAR contenant les éléments précédents ; 6. codage d un ServiceLocator, qui sera réutilisé... ; 7. création de l application cliente. ENI Editions - All rigths reserved - Kaiss Tag - 7 -

108 Introduction aux applications Web Avant de démarrer dans les configurations et déploiements d une application Web, commençons par faire un point sur ce qu est une application Web et quelle est la place de ce type d application dans les spécifications J2EE/JEE. Une application Web est une application qui utilise HTTP (Hyper Text Transport Protocol) comme couche de transport. Cela veut dire que le client d une telle application est un navigateur et que l application elle même est sur le serveur. Le navigateur devient donc un client universel, présent sur toute plate forme, non spécialisé dans une application mais sachant interprété un langage de présentation, le HTML (HyperText Markup Language) et ses enrichissements : CSS, JavaScript. 1. Protocole HTTP Il est important de ne pas perdre de vue comment fonctionne le protocole HTTP pour bien mesurer les éventuels risques de sécurité et failles que pourrait présenter une application. Le navigateur va se connecter à une URL, qui correspond à une machine ayant une adresse IP sur le réseau Internet, ou un réseau interne. : permet d atteindre l application par défaut sur le serveur correspondant au domaine editions.eni.fr. Le serveur écoute par défaut, le port 80. console : permet d atteindre l application jmx-console sur la machine où est le navigateur. Le serveur écoute sur le port 8080, qui est précisé ici, car il n est pas le port par défaut. Il est donc question d application par défaut lorsqu uniquement le domaine est précisé. Et au sein d une application, il sera question de ressource par défaut. : atteint la ressource par défaut de l application. Cette ressource par défaut est souvent une page appelée index.html, index.jsp, default.html ou default.htm. Elle est aussi appelée page d accueil et nous verrons comment la configurer. : atteint la ressource de type page JSP qui s appelle admin.jsp. : atteint la ressource de type servlet qui est associée à l URL controleur. Il aurait pu s agir aussi de la ressource par défaut du répertoire controleur de l application secu, si aucune servlet n était associée à l URL. Lors de la demande de ressource, le navigateur émet une requête HTTP (request). Lors de l envoi de la ressource, le serveur émet vers le navigateur une réponse HTTP (response). Il est important de voir que les messages HTTP, requête et réponse, sont constitués de : ENI Editions - All rigths reserved - Kaiss Tag - 1 -

109 un en tête qui donne des renseignements au destinataire du message sur l émetteur et la ressource demandée. Cette en tête est textuelle, donc lisible très facilement. un corps de message qui peut être textuel si la réponse est du HTML, mais qui peut être binaire s il s agit d une image par exemple. L en tête et le corps sont séparés par une ligne vide. Certains outils nous permettent de visualiser les en têtes des messages. Sous Firefox par exemple, vous pouvez utiliser le plug in "Live HTTP Headers". Voici l en tête de la requête envoyée vers console. GET /jmx-console/ HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv: ) Gecko/ Firefox/3.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip,deflate Accept-Charset: ISO ,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Et voici l en tête de la réponse du serveur : HTTP/1.x 200 OK Server: Apache-Coyote/1.1 X-Powered-By: Servlet 2.4; JBoss GA (build: SVNTag=JBoss_4_2_2_GA date= )/tomcat-5.5 Set-Cookie: JSESSIONID=5F2D27F3BF97925CA22C0FCB521C290B; Path=/ Content-Type: text/html;charset=iso Transfer-Encoding: chunked Date: Fri, 05 Sep :53:43 GMT Une requête HTTP commence par une méthode HTTP. Dans l exemple précédent, la requête du navigateur a utilisé la méthode HTTP GET. Attention, lorsque nous parlons de méthode HTTP, il ne s agit nullement d une méthode comme nous l entendons dans le langage Java, mais d une commande. Les méthodes HTTP spécifient le type de requête, donc quelle action doit être effectuée par le serveur : GET : la méthode HTTP la plus utilisée, demande une ressource au serveur et permet aussi d envoyer un formulaire en mode GET. Le contenu du formulaire est alors ajouté à l URL : nom=toto&id= ENI Editions - All rigths reserved - Kaiss Tag

110 POST : commande utilisée lors de l envoi d un formulaire en mode POST. Le contenu du formulaire est envoyé dans le corps du message et peut être au format binaire. HEAD : demande d information sur une ressource. PUT : remplace ou ajoute une ressource au serveur. DELETE : supprime une ressource du serveur. TRACE : permet le diagnostic de la connexion en demandant au serveur de renvoyer ce qu il a reçu. CONNECT : permet d utiliser un proxy comme tunnel. OPTIONS : permet de connaître les options de communication du serveur. 2. Architecture Web pour J2EE/JEE Sun définit dans les spécifications servlet 2.2 ce qu est une application Web. C est une collection de ressources : servlets, pages HTML, classes et autres pouvant être packagées et pouvant s exécuter sur des conteneurs provenant de fournisseurs multiples. Les éléments d une application Web sont : des servlets ; des pages JSP ; des ressources statiques : images, pages HTML, documents PDF... ; des applets ; des composants Java Bean ; des descripteurs de déploiement ; des classes utilitaires Java. L ensemble de toutes ces ressources sont packagées dans une archive de type jar, dont l extension est war. Cette archive sera placée dans le répertoire de déploiement des conteneurs pour être automatiquement déployée. La structure d une archive war est la suivante : ENI Editions - All rigths reserved - Kaiss Tag - 3 -

111 Cette archive est prise en compte sur tous les conteneurs servlet/jsp. Il arrive que lors de la migration de l archive d un système d exploitation à un autre le répertoire WEB INF passe en minuscule. Ainsi, les fichiers de déploiement ne sont plus pris en compte par le conteneur. Nous avons eu ce problème avec des transferts d archive entre Ubuntu et RedHat. Il faut alors ouvrir l archive et corriger l erreur ENI Editions - All rigths reserved - Kaiss Tag

112 Configuration du conteneur Web Le service de déploiement Web est un service JBoss qui est déployé dans le répertoire deploy de votre configuration serveur. Le répertoire jboss web.deployer contient l ensemble des librairies et des fichiers de configuration de base. Le service est visible dans la console JMX, via console. Il est identifié par JBossWeb/2.0.1.GA qui est un sous projet JBoss contenant la version 5.5 de Tomcat : Le contenu du répertoire jboss web.deployer est le suivant : répertoire conf contenant un fichier web.xml de base pour les applications Web. Ce fichier contient, entre autres, la liste des types MIME. répertoire jsf libs contenant les librairies pour les composants JSF (Java Server Face). répertoire META INF contenant : le fichier jboss service.xml qui configure le service WebServer ; le fichier webserver mbean.xml qui configure le déploiement des archives war. le répertoire ROOT.war qui est une archive décompressée, correspondant à la page d accueil de JBoss : l application web par défaut, accessible par des librairies jar nécessaires au fonctionnement du service et la prise en charge des JSTL (Java Standard TagLib). le fichier server.xml qui configure le service. Ce fichier contient les configurations des connecteurs d écoute : port 8080, port sécurisé le fichier context.xml de base pour chaque application Web. Ce fichier contient la prise en compte ou non de la sérialisation des sessions et un écouteur (listener) JBoss pour le cycle de vie des servlets. Il peut être important, pour la mise en place de certains projets, de connaître la version de Tomcat utilisée. Voici un tableau récapitulatif des versions de spécification, par rapport aux versions de Tomcat. Spec. servlet Spec. JSP Version Tomcat ENI Editions - All rigths reserved - Kaiss Tag - 1 -

113 Le conteneur de servlets reçoit les requêtes provenant du navigateur. Il décode l en tête HTTP pour appeler ensuite la méthode adéquate pour la servlet. La servlet codée en Java par le développeur hérite de la classe javax.servlet.http.httpservlet. La servlet doit être compilée et le fichier.class doit être placé dans le répertoire WEB INF/classes de l archive de déploiement. Le développeur doit implémenter les méthodes correspondant aux méthodes HTTP, susceptibles d appeler la servlet. En général, deux méthodes uniquement sont souvent implémentées : doget(...) pour la méthode HTTP GET ; dopost(...) pour la méthode HTTP POST. Les méthodes de la servlet doxxx(...) où Xxx correspond à une méthode HTTP, ont la même signature : protected void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException Dans cette méthode, les paramètres : request, de type javax.servlet.http.httpservletrequest, encapsule la requête provenant du navigateur ; response, de type javax.servlet.http.httpservletresponse, encapsule la réponse vers le navigateur. Les méthodes sont susceptibles de lever des exceptions de type javax.servlet.servletexception ou java.io.ioexception. Les implémentations par défaut de ces méthodes renvoient une erreur 405 avec le message du type "La méthode n est pas supportée". 1. Les servlets Le conteneur gère le cycle de vie de la servlet. C est lui qui invoque les méthodes. La servlet est compilée par le développeur et déclarée dans le fichier web.xml. Les seules méthodes que, normalement, le développeur doit implémenter sont les méthodes en doxxx(...) ENI Editions - All rigths reserved - Kaiss Tag

114 Vous trouverez dans le projet "Chap 5 Web", les exemples qui nous serviront durant ce chapitre. Commençons par un exemple trivial de codage d une servlet, il s agit de la classe HelloServlet. public class HelloServlet extends javax.servlet.http.httpservlet implements javax.servlet.servlet static final long serialversionuid = 1L; protected void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException String nom = request.getparameter("nom"); String message = this.getinitparameter("message"); PrintWriter out = response.getwriter(); if (nom!= null) message = message + " " + nom; out.print("<html><head></head><body>"); out.print("<h2>" + message + "<h2>"); out.print("</body></html>"); Cette servlet est déclarée dans le fichier web.xml. <web-app>... <servlet> <description></description> <display-name>helloservlet</display-name> <servlet-name>helloservlet</servlet-name> <servlet-class> fr.eni.editions.servlets.helloservlet </servlet-class> <init-param> ENI Editions - All rigths reserved - Kaiss Tag - 3 -

115 <description></description> <param-name>message</param-name> <param-value>bonjour</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>... <web-app> Nous trouvons dans ce fichier deux parties importantes : la déclaration de la servlet dans l élément <servlet> qui contient les éléments fils : <description> facultatif, fournit une description de la servlet ; <display-name> contient la valeur affichée par certains outils de gestion, facultatif ; <servlet-name> est le nom de la servlet dans le fichier web.xml. Ce nom sert d alias à la classe d implémentation ; <servlet-class> contient le nom complet de la classe d implémentation ; <init-param> contient la définition d un paramètre qui ne sera disponible que pour la servlet par l intermédiaire de la méthode getinitparameter(...). Cet élément est facultatif et peut apparaître plusieurs fois. Il contient lui même le nom du paramètre dans <param-name> et sa valeur dans <paramvalue>. les associations de la servlet avec les URLs dans l élément <servlet-mapping> : <servlet-name> contient le nom de la servlet tel qu il a été défini dans le même élément au sein de <servlet> ; <url-pattern> contient l URL. Elle peut contenir des caractères génériques, comme *, par exemple *.do prendra en compte toutes les URLs finissant en.do (action.do). Quand cette application Web est déployée, nous pouvons invoquer la servlet par l URL (nous verrons, dans la suite de ce chapitre, comment le nom de l application chap5 a été paramétré) : Saisissez : Testez l URL : ENI Editions - All rigths reserved - Kaiss Tag

116 Le paramètre d URL a été récupéré dans la servlet par le code :...String nom = request.getparameter("nom"); Les JSP Comme nous avons pu le voir précédemment, les servlets sont des composants qui peuvent devenir vite très lourds, peu lisibles et peu maintenables, du fait qu il y ait mélange de code Java et d HTML. Les JSP (Java Server Page) a donc naturellement suivi les servlets. Ici, le concept de codage est différent. La page JSP est une page HTML dans laquelle vont apparaître des morceaux de code Java, les scriptlets. Une page JSP ressemble à d autres pages de technologies différentes comme le PHP, ou l ASP. page language="java" contenttype="text/html; charset=iso " pageencoding="iso "%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=iso "> <title>insert title here</title> </head> <body> <%! int additionner(int a, int b) return a+b; %> String[] villes = "Paris","Nantes","Marseilles"; <h3>bonjour tout le monde!!!</h3> Le résultat de l addition est <%=additionner(2,6) %> <br /> Liste des villes : <ul> <% for(int i=0 ; i<villes.length ; i++) out.println("<li>"+villes[i]+"</li>"); %> </ul> </body> </html> Dans cette page HTML, nous avons : des déclarations entourées par <%!... %> ; des scriptlets <%... %> ; ENI Editions - All rigths reserved - Kaiss Tag - 5 -

117 des expressions <%=... %>. La lisibilité peut s en trouver améliorée, si le code Java n est pas trop présent dans la page. Pour améliorer la lisibilité et enlever le code Java des pages JSP, d autres technologies sont venues s inscrire dans les JSP. Nous ne ferons que citer certaines d entre elles, et vous pourrez les apercevoir au détour de certains exemples : la bibliothèque JSTL pour Java Standard TagLib, qui est une librairie d éléments XML utilisés dans les pages JSP afin de remplacer les scriptlets ; l EL, pour Expression Language, qui permet de remplacer les expressions ; les JSF, pour Java Server Face, qui sont des composants côtés serveur générant le code HTML, le code Java et le JavaScript nécessaires à la construction de la page envoyée au navigateur. a. Cycle de vie d une JSP Alors qu une servlet est codée en Java, compilée et déployée dans le répertoire WEB INF/classes, une JSP est entièrement prise en charge par le conteneur. Elle va être traduite en une classe Java, puis compilée. Lorsqu une requête demande une ressource JSP, le conteneur vérifie si la classe correspondante à la JSP est chargée en mémoire, si ce n est pas le cas, ou si la JSP a changé, alors il y a traduction puis compilation de la page JSP. La traduction Java et le fichier compilé se trouvent dans le répertoire de travail : <configuration serveur>\work\jboss.web\localhost\<nom appli web>\org\apache\jsp Par exemple, dans notre cas : \server\default\work\jboss.web\localhost\chap5\org\apache\jsp La page JSP index.jsp, présentée précédemment, donne après traduction, le fichier source Java : index_jsp.java. package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; ENI Editions - All rigths reserved - Kaiss Tag

118 public final class index_jsp extends org.apache.jasper.runtime.httpjspbase implements org.apache.jasper.runtime.jspsourcedependent int additionner(int a, int b) return a+b; String[] villes = "Paris","Nantes","Marseille"; private static final JspFactory _jspxfactory = JspFactory.getDefaultFactory(); private static java.util.list _jspx_dependants; private javax.el.expressionfactory _el_expressionfactory; private org.apache.annotationprocessor _jsp_annotationprocessor; public Object getdependants() return _jspx_dependants; public void _jspinit() _el_expressionfactory = _jspxfactory.getjspapplicationcontext (getservletconfig().getservletcontext()).getexpressionfactory(); _jsp_annotationprocessor = (org.apache.annotationprocessor) getservletconfig().getservletcontext().getattribute(org.apache. AnnotationProcessor.class.getName()); public void _jspdestroy() public void _jspservice(httpservletrequest request, HttpServletResponse response) throws java.io.ioexception, ServletException PageContext pagecontext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; try response.setcontenttype("text/html; charset=iso "); pagecontext = _jspxfactory.getpagecontext(this, request, response, null, true, 8192, true); _jspx_page_context = pagecontext; application = pagecontext.getservletcontext(); config = pagecontext.getservletconfig(); session = pagecontext.getsession(); out = pagecontext.getout(); _jspx_out = out; out.write("\n"); out.write("<!doctype html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/tr/html4/loose.dtd\">\n"); out.write("<html>\n"); out.write("<head>\n"); out.write("<meta http-equiv=\"content-type\" content=\"text/html; charset=iso \">\n"); out.write("<title>insert title here</title>\n"); out.write("</head>\n"); ENI Editions - All rigths reserved - Kaiss Tag - 7 -

119 out.write("<body>\n"); out.write("\r\n"); out.write("\r\n"); out.write("<h3>bonjour tout le monde!!!</h3>\r\n"); out.write("\r\n"); out.write("le résultat de l addition est "); out.print(additionner(2,6) ); out.write("\r\n"); out.write("<br />\r\n"); out.write("liste des villes :\r\n"); out.write("<ul>\r\n"); for(int i=0 ; i<villes.length ; i++) out.println("<li>"+villes[i]+"</li>"); out.write("\r\n"); out.write("</ul>\r\n"); out.write("\n"); out.write("</body>\n"); out.write("</html>"); catch (Throwable t) if (!(t instanceof SkipPageException)) out = _jspx_out; if (out!= null && out.getbuffersize()!= 0) try out.clearbuffer(); catch (java.io.ioexception e) if (_jspx_page_context!= null) _jspx_page_context.handlepageexception(t); finally _jspxfactory.releasepagecontext(_jspx_page_context); Le code HTML a produit un code qui envoie les chaînes de caractères HTML vers le flux de sortie, dans des invocations out.write(...). out.write("<body>\n"); out.write("\r\n"); out.write("\r\n"); out.write("<h3>bonjour tout le monde!!!</h3>\r\n"); Le code présent dans la partie déclaration de la page JSP, a été traduit par des membres de classe : Dans la page JSP : <%! int additionner(int a, int b) return a+b; %> String[] villes = "Paris","Nantes","Marseille"; Dans la classe : int additionner(int a, int b) return a+b; String[] villes = "Paris","Nantes","Marseille"; La fonction JSP additionner(...) a été traduite par une méthode addtionner(...). La variable de page JSP villes a été traduite par la propriété villes. L expression JSP est évaluée et envoyée dans le flux de sortie. Dans la page JSP : ENI Editions - All rigths reserved - Kaiss Tag

120 <%=additionner(2,6) %> Dans la classe : out.print(additionner(2,6) ); Les scriptlets ont été transposées telles quelles dans la classe. Dans la page JSP : <% %> for(int i=0 ; i<villes.length ; i++) out.println("<li>"+villes[i]+"</li>"); Dans la classe : for(int i=0 ; i<villes.length ; i++) out.println("<li>"+villes[i]+"</li>"); ENI Editions - All rigths reserved - Kaiss Tag - 9 -

121 Les descripteurs de déploiement Il y a deux descripteurs de déploiement. Le descripteur de déploiement standard le fichier web.xml, et le descripteur de déploiement spécifique, le fichier jboss web.xml. Le descripteur de déploiement standard est portable d un serveur d application à l autre, le descripteur de déploiement spécifique est propre au serveur JBoss. Le descripteur standard contient la configuration de l application web, des références aux ressources. Le descripteur de déploiement spécifique contient la liaison entre les ressources référencées dans le fichier web.xml et leur déploiement dans le serveur d application. Les descripteurs de déploiement sont situés dans le répertoire WEB INF de l application Web. 1. Descripteur de déploiement standard web.xml L élément racine <web-app> du fichier web.xml comprend les éléments fils suivants : <icon>, <display-name>, <description> qui sont des éléments utilisés par certains outils de gestion de déploiement, pour afficher une icône, un nom et une description associés à l application Web. <distribuable> permet de marquer l application comme distribuable sur plusieurs serveurs, ce qui permet d exploiter la répartition de charge contrôlée par le serveur. <context-param> qui contient la valeur des paramètres utilisables dans toute l application. Ces paramètres, définis dans le fichier web.xml, peuvent être utilisés dans les servlets et les pages JSP. Les paramètres sont déclarés dans les balises <param-name> et <param-value>. <filter> et <filter-mapping> qui permettent de déclarer des filtres sur des URL. Les filtres vont permettre de faire des traitements avant que la requête n arrive à la servlet ou à la JSP, ou après que la réponse soit générée. Ce type de classe doit implémenter l interface javax.servletfilter. <listener> qui permet de déclarer des écouteurs sur des événements : entre autres, démarrage et retrait de l application web, début et fin de session. <servlet> et <servlet-mapping> qui permettent de déclarer les servlets et de les associer avec des URL. <session-config> qui contient l élément <session-timeout> permettant de définir le temps maximal d une session, en minutes. Le temps par défaut de 30 minutes est défini dans le fichier server\default\deploy\jbossweb.deployer\conf\web.xml. Vous pouvez régler ce temps, application par application. <mime-mapping> qui reprend les types MIME, ces types sont configurés dans le web.xml par défaut. <welcome-file-list> qui déclare la liste des noms des pages d accueils par défaut, si aucune ressource n est demandée dans l URL. <error-page> définit les pages d erreur à renvoyer en cas de code erreur HTTP, ou d exception Java. <error-code> contient le code erreur HTTP, par exemple 404 ; <exception-type> contient le nom de la classe d exception ; <location> contient le chemin de la page d erreur à afficher. <security-constraint>, <security-role>, <login-config> permettent de mettre en place des sections du site qui sont soumises à des autorisations d accès. Nous aurons l occasion de revenir plus en détail sur l utilisation de ces balises, dans le chapitre Gestion de la sécurité consacré à la sécurité. <resource-ref>, <ejb-ref> déclarent des références vers des ressources, ou des EJB, qui sont déployées sur le serveur. Ces déclarations seront associées aux ressources réelles dans le fichier de déploiement spécifique jboss web.xml. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

122 2. Descripteur de déploiement spécifique jboss web.xml Les ressources déclarées dans le fichier web.xml par l intermédiaire des éléments <resource ref>, font référence au nommage JNDI de l application, dans le contexte java:com/env. Les ressources réelles sont nommées dans contexte JNDI plus global. Il serait dommage que les servlets et JSP, si elles utilisent des ressources, soient obligées de connaître les noms JNDI de plus haut niveau, cela nuirait à la portabilité. Le fichier jboss web.xml va permettre d associer les contextes JNDI. L élément racine de ce fichier est <jboss-web>. Nous allons découvrir ce fichier en l illustrant par quelques exemples. a. Nom de l application <jboss-web> <context-root>chap5</context-root> </jboss-web> L élément <context-root> permet de préciser le nom de l application web. Si ce nom n est pas précisé, l application sera nommée avec le nom du fichier war. Si notre archive s appelle "Chap 5 Web.war", le nom de l application déployée sera "Chap 5 Web" qui correspondra à l URL 5 Web/. Si une valeur est donnée à l élément <context-root>, le nom de l application correspondra à cette valeur, dans notre cas : b. Association de ressources Association d une source de données Dans le fichier web.xml, la ressource est déclarée de la manière suivante : <web-app> <resource-ref> <res-ref-name>jdbc/bovoyage</res-ref-name> <res-type>javax.sql.datasource</res-type> <res-auth>container</res-auth> </resource-ref> </web-app> Dans la servlet, la récupération de la ressource est effectuée par un code ressemblant à cela : InitialContext context = new InitialContext(); DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/Bovoyage"); Dans le fichier jboss web.xml, l association est effectuée de la manière suivante : <jboss-web>... <resource-ref> <res-ref-name>jdbc/bovoyage</res-ref-name> <jndi-name>java:jdbc/bovoyageds</jndi-name> </resource-ref> ENI Editions - All rigths reserved - Kaiss Tag

123 </jboss-web> Si nous interrogeons la liste des noms JNDI, nous pouvons voir que l association a été effectuée : Contexte JNDI java: : java: Namespace +- jaas (class: javax.naming.context) +- HsqlDbRealm (class: org.jboss.security.plugins.securitydomaincontext) +- jbossmq (class: org.jboss.security.plugins.securitydomaincontext) +- JmsXARealm (class: org.jboss.security.plugins.securitydomaincontext) +- TransactionPropagationContextImporter (class: com.arjuna.ats.internal. jbossatx.jta.propagationcontextmanager) +- comp.ejb3 (class: javax.naming.context) NonContext: null +- JmsXA (class: org.jboss.resource.adapter.jms.jmsconnectionfactoryimpl) +- DefaultDS (class: org.jboss.resource.adapter.jdbc.wrapperdatasource) +- StdJMSPool (class: org.jboss.jms.asf.stdserversessionpoolfactory) +- TransactionManager (class: com.arjuna.ats.jbossatx.jta. TransactionManagerDelegate) +- test_seamdatasource (class: org.jboss.resource.adapter.jdbc. WrapperDataSource) +- TransactionPropagationContextExporter (class: com.arjuna.ats.internal. jbossatx.jta.propagationcontextmanager) +- ConnectionFactory (class: org.jboss.mq.spyconnectionfactory) +- jdbc (class: org.jnp.interfaces.namingcontext) +- BovoyageDS (class: org.jboss.resource.adapter.jdbc.wrapperdatasource) Contexte JNDI de l application Web : java:comp namespace of the Chap 5 - Web.war application: +- UserTransaction[link -> UserTransaction] (class: javax.naming.linkref) +- env (class: org.jnp.interfaces.namingcontext) +- unentier (class: java.lang.integer) +- jdbc (class: org.jnp.interfaces.namingcontext) +- Bovoyage[link -> java:jdbc/bovoyageds] (class: javax.naming. LinkRef) Nous constatons donc que les contextes JNDI ont bien été effectués. Il est important de travailler selon ce procédé, plutôt que d aller, dans l application Web, chercher dans les contextes JNDI de haut niveau. En effet cela permet d assurer une meilleure portabilité entre les serveurs d applications. Association avec un EJB Dans ce type d association, nous pouvons utiliser des EJB situés : sur le même serveur, donc les interfaces locales seront utilisées ; sur un autre serveur, et alors les interfaces distantes sont utilisées. Dans le fichier web.xml, les références locales sont mises en place par l élément <ejb-local-ref> et les références distantes le sont par <ejb-ref>. <web-app>... <ejb-ref> <ejb-ref-name>ejb/calc</ejb-ref-name> <ejb-ref-type>session</ejb-ref-type> <home> fr.eni.editions.jboss.ejb2.calculette.calculettehome </home> <remote> fr.eni.editions.jboss.ejb2.calculette.calculette </remote> </ejb-ref> ENI Editions - All rigths reserved - Kaiss Tag - 3 -

124 <ejb-local-ref> <ejb-ref-name>ejb/calch</ejb-ref-name> <ejb-ref-type>session</ejb-ref-type> <local-home> fr.eni.editions.jboss.ejb2.calculette.calculettelocalhome </local-home> <local> fr.eni.editions.jboss.ejb2.calculette.calculettelocal </local> </ejb-local-ref> </web-app> <ejb-ref-name> contient la valeur utilisée dans la recherche dans le contexte JNDI. Cette recherche produirait un code ressemblant à celui ci, pour l EJB local : InitialContext context = new InitialContext(); CalculetteLocalHome home = (CalculetteLocalHome)context.lookup("java:comp/env/ejb/calcH"); CalculetteLocal bean = home.create(); Ou produirait un code ressemblant à celui ci, pour l EJB distant : InitialContext context = new InitialContext(); CalculetteHome home = (CalculetteHome)context.lookup(("java:comp/env/ejb/calc"); Calculette bean = home.create(); Le fichier jboss web.xml met en place les associations de contexte : <jboss-web>... <ejb-ref> <ejb-ref-name>ejb/calc</ejb-ref-name> <jndi-name>ejb2/calculette/remote</jndi-name> </ejb-ref> <ejb-local-ref> <ejb-ref-name>ejb/calch</ejb-ref-name> <local-jndi-name> ejb2/calculette/local </local-jndi-name> </ejb-local-ref> </jboss-web> Si nous interrogeons la liste des noms JNDI, nous pouvons voir que l association a été effectuée : Dans le contexte JNDI global : +- ejb2 (class: org.jnp.interfaces.namingcontext) +- calculette (class: org.jnp.interfaces.namingcontext) +- local (proxy: $Proxy60 implements interface fr.eni.editions.jboss. ejb2.calculette.calculettelocalhome) +- remote (proxy: $Proxy62 implements interface fr.eni.editions. jboss.ejb2.calculette.calculettehome,interface javax.ejb.handle) Dans le contexte JNDI de l application Web : java:comp namespace of the Chap 5 - Web.war application: +- UserTransaction[link -> UserTransaction] (class: javax.naming.linkref) +- env (class: org.jnp.interfaces.namingcontext) +- unentier (class: java.lang.integer) +- jdbc (class: org.jnp.interfaces.namingcontext) +- Bovoyage[link -> java:jdbc/bovoyageds] (class: javax.naming. LinkRef) ENI Editions - All rigths reserved - Kaiss Tag

125 +- ejb (class: org.jnp.interfaces.namingcontext) +- calc[link -> ejb2/calculette/remote] (class: javax.naming. LinkRef) +- calch[link -> ejb2/calculette/local] (class: javax.naming. LinkRef) Accès à l environnement. Des valeurs peuvent être mises en contexte JNDI par l intermédiaire de l élément <env-entry> dans le fichier web.xml. <web-app>... <env-entry> <env-entry-name>unentier</env-entry-name> <env-entry-type>java.lang.integer</env-entry-type> <env-entry-value>25</env-entry-value> </env-entry> </web-app> <env-entry-name> est le nom JNDI dans le contexte de l application ; <env-entry-type> est le type de l entrée. Cela peut être java.lang.boolean, java.lang.integer, java.lang.double, java.lang.float ou java.lang.string ; <env-entry-value> est la valeur de l entrée. Cela se traduit par la mise en place dans le contexte JNDI de l entrée : java:comp namespace of the Chap 5 - Web.war application: +- UserTransaction[link -> UserTransaction] (class: javax.naming.linkref) +- env (class: org.jnp.interfaces.namingcontext) +- unentier (class: java.lang.integer) Et la recherche de l entrée pourrait être un code ressemblant à celui ci : Integer entier = null; try InitialContext ctx = new InitialContext(); entier = (Integer)ctx.lookup("java:comp/env/unEntier"); System.out.println("<<< valeur de l entier : "+entier); catch(exception e) System.out.println("<<< erreur : "+e); Les recherches dans un contexte JNDI peuvent être remplacées par de l injection de ressources avec Tomcat 6. La version de Tomcat utilisée ici par JBoss est la 5.5. ENI Editions - All rigths reserved - Kaiss Tag - 5 -

126 Les hôtes virtuels Les hôtes virtuels permettent d associer plusieurs noms de domaine avec une application Web. Le nom de domaine doit être enregistré auprès d une autorité DNS. Mais vous pouvez aussi forcer un nom de domaine en modifiant le fichier hosts. Ce fichier est situé : sous Ubuntu, dans /etc/hosts ; sous Windows, dans C:\WINDOWS\system32\drivers\hosts localhost Des domaines et des adresses IP sont associés dans ce fichier. Ici, il y deux nouveaux domaines associés à la machine. Lors de l invocation des domaines et l adresse sera réellement invoquée. Le fichier server.xml, situé sous <répertoire jboss>/server/default/conf, a été modifié pour ajouter les lignes suivantes dans la balise <Engine> : <Engine>... <Host name="toto" autodeploy="false" deployonstartup="false" deployxml="false" configclass="org.jboss.web.tomcat.security.config.jbosscontextconfig"> <Alias>www.toto.net</Alias> <Alias>www.titi.net</Alias> <Valve classname="org.jboss.web.tomcat.service.jca.cachedconnectionvalve" cachedconnectionmanagerobjectname="jboss.jca:service=cachedconnectionmanager" transactionmanagerobjectname="jboss:service=transactionmanager" /> </Host> <Engine> La balise <Host> représente un hôte virtuel. Elle possède les attributs suivants : name : le nom de l hôte virtuel, habituellement un nom réseau ; appbase : chemin relatif ou absolu où se trouvent les applications Web, par défaut le répertoire de déploiement ; autodeploy : auto déploiement des applications, ici à false car un service JBoss déploie les applications et non pas Tomcat ; deployonstartup : déploiement automatique au démarrage ; deployxml : désactivation des fichiers XML de contexte ; configclass : classe de gestion de la configuration. Les balises <Alias> permettent d ajouter des alias au nom réseau défini dans l attribut name de <Host>. La balise <Valve> permet de définir des éléments qui viendront s insérer dans le traitement des requêtes. Dans le fichier jboss web.xml, nous pouvons associer un hôte virtuel défini dans server.xml avec notre application Web, et un nom d application. <jboss-web> <context-root>/</context-root> <virtual-host>toto</virtual-host> ENI Editions - All rigths reserved - Kaiss Tag - 1 -

127 </jboss-web> L élément <context-root> contient "/" qui est l application par défaut. Par ce biais, nous avons associé notre application aux URL : Mais vous pouvez vérifier que l URL pointe toujours vers la page d accueil de JBoss ENI Editions - All rigths reserved - Kaiss Tag

128 Configuration du conteneur d EJB Comme nous avons pu le voir lors des rappels sur les EJB au chapitre Introduction, le client d un EJB ne crée jamais directement d instance d EJB, et n invoque jamais directement une méthode sur l EJB. C est le conteneur d EJB du serveur JBoss qui est chargé d effectuer ces appels. Pour un EJB2 par exemple, il est de la responsabilité du serveur de fournir les javax.ejb.ejbhome et javax.ejb.ejbobject pour un EJB, le client référencera EJBHome pour tout ce qui a trait au cycle de vie de l EJB et EJBObject pour les invocations des méthodes métier. Côté client Côté client, les phases de déploiement d un EJB2 et la fabrication des proxies par le serveur peuvent être résumées par les étapes suivantes : 1. Le moteur de déploiement d EJB (org.jboss.ejb.ejbdeployer) déploie l archive JAR de l EJB. Un module EJB (org.jboss.ejb.ejbmodule) est alors créé. 2. Lors de la phase de création du module EJB, une fabrique de proxy (org.jboss.ejb.ejbfactory) gère la création des proxies des interfaces Home et Object de l EJB. 3. La fabrique de proxy crée un proxy logique composé d un proxy dynamique (java.lang.reflect.proxy), des interfaces Home de l EJB, d une implémentation d un ProxyHandler (java.lang.reflect.invocationhandler) et des classes d interception. Les interfaces homes de l EJB sont liées au contexte JNDI. 4. Lorsque le client recherche dans un contexte JNDI l interface Home de l EJB, le proxy associé est transporté dans la machine virtuelle du client. Lorsque le client invoque une méthode de l EJB, il y a création d une instance de la classe org.jboss.invocation.invocation qui encapsule la demande du client. Cette invocation passe au travers d une chaîne de classes d interception. L ensemble des classes associées à la fabrique des proxies et liées à la chaîne d interception des invocations sont décrites dans le fichier <répertoire du serveur>/conf/standardjboss.xml dont voici un extrait : <invoker-proxy-binding> <name>stateless-unified-invoker</name> <invoker-mbean>jboss:service=invoker,type=unified</invoker-mbean> <proxy-factory>org.jboss.proxy.ejb.proxyfactory</proxy-factory> <proxy-factory-config> <client-interceptors> <home> <interceptor>org.jboss.proxy.ejb.homeinterceptor</interceptor> <interceptor>org.jboss.proxy.securityinterceptor</interceptor> <interceptor>org.jboss.proxy.transactioninterceptor</interceptor> <interceptor call-by-value= "false">org.jboss.invocation.invokerinterceptor</interceptor> <interceptor call-by-value= "true">org.jboss.invocation.marshallinginvokerinterceptor</interceptor> </home> <bean> <interceptor>org.jboss.proxy.ejb.statelesssessioninterceptor </interceptor> <interceptor>org.jboss.proxy.securityinterceptor</interceptor> <interceptor>org.jboss.proxy.transactioninterceptor</interceptor> <interceptor call-by-value="false">org.jboss.invocation. InvokerInterceptor</interceptor> <interceptor call-by-value="true">org.jboss.invocation. MarshallingInvokerInterceptor</interceptor> </bean> </client-interceptors> </proxy-factory-config> </invoker-proxy-binding> Le nom de la classe de fabrique des proxies se retrouve dans la balise <proxy-factory>. Puis la description de la chaîne d interception pour les interfaces de gestion du cycle de vie et d exposition des méthodes métier de l EJB se retrouve dans les balises <home> et <bean>. Nous voyons que nous avons des intercepteurs pour : les interfaces : org.jboss.proxy.ejb.homeinterceptor et org.jboss.proxy.ejb.statelesssessioninterceptor ; ENI Editions - All rigths reserved - Kaiss Tag - 1 -

129 le contexte sécurité : org.jboss.proxy.securityinterceptor ; les transactions : org.jboss.proxy.transactioninterceptor ; le mode de transport de la requête du client :. par référence, c est à dire dans la même machine virtuelle, avec org.jboss.invocation.invokerinterceptor ; par valeur, c est à dire par RMI, avec org.jboss.invocation.marshallinginvokerinterceptor. Côté serveur L invocation d un EJB se termine côté serveur. L invocation d une méthode de l EJB va être transportée vers la machine virtuelle de JBoss, via le bus JMX. Chaque proxy est associé à une classe d invocation et à un protocole de transport. Le service EJBDeployer est responsable de la création des conteneurs EJB. Nous pouvons retrouver ce service dans la console de visualisation des services, à l adresse : console/ puis, en recherchant le lien service=ejbdeployer sous la rubrique jboss.ejb. Vous pouvez alors voir les attributs du MBean sur l écran suivant : ENI Editions - All rigths reserved - Kaiss Tag

130 Parmi les attributs modifiables : VerifyDeployments : vérifie que l EJB est conforme aux spécifications EJB2.1. Il est très utile pour s assurer de la validité du déploiement. Le résultat de la vérification n affecte pas le déploiement lui même, voir StrictVerifier. VerifierVerbose : passe la vérification du déploiement en mode "bavard". StrictVerifier : si cet attribut est positionné à "true", le déploiement n est pas effectué si la vérification a échoué. CallByValue : mise en place par défaut, des invocations avec passage des paramètres par valeur. ValidateDTDs : vérifie que les fichiers XML ejb jar.xml et jboss.xml sont valides par rapport à leur DTD. ENI Editions - All rigths reserved - Kaiss Tag - 3 -

131 Déploiement des EJB 2 Le composant EJB2 est packagé dans un module EJB (archive en.jar). Ce module peut être déployé directement, ou être lui même inclus dans une application d entreprise (archive en.ear). 1. Packaging a. Packaging en module EJB Le répertoire META INF comporte : le fichier de déploiement standard de l EJB : ejb jar.xml ; le fichier de déploiement spécifique pour JBoss : jboss.xml. Le fichier de déploiement standard sera portable d un serveur à l autre, tandis que le fichier de déploiement spécifique est propre à JBoss. Ce fichier spécifique sera donc à réécrire en cas de déploiement sous un autre serveur d application. Heureusement, ces fichiers ont une syntaxe très proche les uns des autres. b. Packaging dans une application d entreprise ENI Editions - All rigths reserved - Kaiss Tag - 1 -

132 Le module application d entreprise (fichier ear) peut regrouper : des modules Web (fichiers war) ; des modules EJB (fichiers jar) ; des librairies java (fichiers jar) ; un répertoire META INF contenant le fichier application.xml qui permet de déclarer les modules et de surcharger les déploiements par défaut. c. Déploiement Le déploiement est effectué très simplement en plaçant le module EJB, ou l application d entreprise, dans le répertoire deploy du serveur. Par exemple, si vous travaillez sur le serveur par défaut, le répertoire de déploiement sera : <répertoire installation JBoss>/server/default/deploy. Ce répertoire est normalement le répertoire de déploiement à chaud par défaut. Il est géré par le MBean org.jboss.deployment.scanner.urldeploymentscanner. Nous avons vu au chapitre Architecture de JBoss comment nous pouvions modifier le répertoire de déploiement. 2. Descripteurs de déploiements Les descripteurs de déploiement sont au format XML. Le répertoire <répertoire installation JBoss>/docs/dtd contient l ensemble des fichiers DTD (Document Type Definition) utilisés par JBoss. Il y a deux types de descripteurs de déploiement : les standards qui sont conformes aux spécifications de Sun ; les spécifiques qui sont propres au serveur d application. Par exemple, les spécifications J2EE expliquent comment faire référence et utiliser une source de données, une authentification dans un module, mais ne spécifient pas comment les mettre en place et comment les lier avec le module. Cette mise en place de la source de données et la liaison avec le module sont propres à chaque serveur. a. Descripteur de déploiement standard ejb jar.xml Vous pouvez télécharger le schéma XML correspondant au fichier ejb jar.xml à l URL suivante : Ce fichier XML est portable d un serveur à l autre. Il permet de constituer le composant, en y décrivant : ENI Editions - All rigths reserved - Kaiss Tag

133 les classes interface ; la classe d implémentation ; le type d EJB ; les configurations de gestion de l EJB ; la déclaration des champs persistants pour les EJB entités. Nous ne reprendrons ici que les éléments principaux. Les exemples de déploiement qui suivent dans ce chapitre vont permettre d illustrer ce fichier ejb jar.xml. <ejb-jar> : racine du document XML ; <enterprise-beans> : contient les éléments fils <session>, <entity>, <message-driven> correspondant aux différents EJB du module ; <session> : déclaration d un EJB de type session ; <entity> : déclaration d un EJB de type entité, pour la persistance ; <message-driven> : déclaration d un EJB de type orienté message ; <ejb-name> : nom de l EJB, c est ce nom qui sera utilisé dans le fichier jboss.xml ; <home> : nom de l interface qui étend l interface javax.ejb.ejbhome, celle ci présentant les méthodes du cycle de vie utilisables à distance par RMI ; <local-home> : nom de l interface qui étend l interface javax.ejb.ejblocalhome, présentant les méthodes du cycle de vie utilisables en local, c est à dire dans la même machine virtuelle ; <remote> : nom de l interface qui étend l interface javax.ejb.ejbobject, présentant les méthodes métier utilisables à distance par RMI ; ENI Editions - All rigths reserved - Kaiss Tag - 3 -

134 <local> : nom de l interface qui étend l interface javax.ejb.ejblocalobject, présentant les méthodes métier utilisables en local, c est à dire dans la même machine virtuelle ; <ejb-class> : nom de la classe d implémentation de l EJB, qui étend une des classes javax.ejb.sessionbean, javax.ejb.entitybean ou javax.ejb.messagedrivenbean en fonction du type d EJB ; <relationships> : décrit les relations entre les EJB entités. b. Descripteur de déploiement spécifique jboss.xml Le fichier jboss.xml est le fichier de déploiement spécifique à JBoss. En fonction de la version de JBoss que vous utilisez, vous pouvez référencer des DTD différentes. <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd"> <jboss>... </jboss> Vous retrouverez l ensemble des DTDs disponibles dans le répertoire <répertoire installation JBoss>/docs/dtd. Chaque fichier jboss.dtd commence par un commentaire présentant la structure du fichier jboss.xml. Pour le fichier jboss.dtd, nous avons la structure suivante : <jboss> <secure /> <security-domain /> <enterprise-beans> <entity> <ejb-name /> <jndi-name /> <resource-ref> <res-ref-name /> <resource-name /> </resource-ref> </entity> <session> <ejb-name /> <jndi-name /> <resource-ref> <res-ref-name /> <resource-name /> </resource-ref> </session> </enterprise-beans> <resource-managers> <resource-manager> <res-name /> <res-jndi-name /> </resource-manager> <resource-manager> <res-name /> <res-url /> </resource-manager> ENI Editions - All rigths reserved - Kaiss Tag

135 </resource-managers> <container-configurations> <container-configuration> <container-name /> <container-invoker /> <container-interceptors /> <instance-pool /> <instance-cache /> <persistence-manager /> <transaction-manager /> <container-invoker-conf /> <container-cache-conf /> <container-pool-conf /> <commit-option /> <role-mapping-manager/> <authentication-module/> </container-configuration> </container-configurations> </jboss> Cette structure de base s est enrichie au fur et à mesure de l évolution des versions de JBoss. Les exemples de déploiement exposés dans ce chapitre permettront d illustrer l utilisation de ce fichier. Dans le fichier jboss.xml, nous allons pouvoir, entre autres, y préciser : les nommages JNDI des EJB ; les références à des ressources, comme les sources de données... Seuls les éléments les plus utilisés seront ici décrits. Certains éléments, comme l élément <secure> ont disparu avec les versions supérieures des DTD. Il convient donc toujours de bien vérifier les versions qui sont utilisées. <enterprise-beans> encapsule les balises <session>, <entity> et <message-driven>. L ensemble de ces balises correspond aux balises de même nom dans le fichier ejb jar.xml en y ajoutant des paramètres supplémentaires spécifiques à JBoss. Nous avons donc en général, autant d entrées d EJB de type session entité ou orienté message dans les deux fichiers ejb jar.xml et jboss.xml. <ejb-name> est un élément fils des éléments <session>, <entity> et <message-driven>. Il contient le nom de l EJB qui doit être le même que dans le fichier ejb jar.xml. <jndi-name> est un élément fils des éléments <session>, <entity>. Il contient le nom de JNDI de l interface Home distante de l EJB. <local-jndi-name> est un élément fils des éléments <session>, <entity>. Il contient le nom de JNDI de l interface Home locale de l EJB. <ejb-ref> est un élément fils des éléments <session>, <entity> et <message-driven>. Il contient la référence vers un autre EJB distant. c. Descripteur de déploiement application.xml Le plus simple pour déployer un ensemble de composants sur un même serveur est de regrouper l ensemble de ces composants dans une même archive. Cette archive est un fichier dont l extension est ear, pour enterprise archive. Cette archive comporte dans son répertoire META INF, un descripteur de déploiement, le fichier application.xml, dont la racine est <application>. ENI Editions - All rigths reserved - Kaiss Tag - 5 -

136 Le fichier XML suivant présente un exemple typique de ce fichier. Ce fichier est extrait du projet BovoyageCMP_EAR que nous retrouverons plus loin dans ce chapitre. <?xml version="1.0" encoding="utf-8"?> <application xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" xsi:schemalocation="http://java.sun.com/xml/ns/javaee id="application_id" version="5"> <module> <ejb>bovoyage_cmp.jar</ejb> </module> <module> <web> <web-uri>bovoyageweb_cmp.war</web-uri> <context-root>bovoyage-cmp</context-root> </web> </module> </application> Nous y retrouvons la déclaration d un module EJB : <module> <ejb>bovoyage_cmp.jar</ejb> </module> et d un module Web auquel nous avons défini un nom d application : <module> <web> <web-uri>bovoyageweb_cmp.war</web-uri> <context-root>bovoyage-cmp</context-root> </web> </module> ENI Editions - All rigths reserved - Kaiss Tag

137 3. Outils d aide au codage des EJB 2 Les composants EJB 2 peuvent vite devenir complexes à écrire. Ainsi, pour créer une EJB2 de type session, le développeur doit créer les 5 classes nécessaires à notre EJB, et les fichiers XML : l interface qui étend javax.ejb.ejbhome ; l interface qui étend javax.ejb.ejblocalhome ; l interface qui étend javax.ejb.ejbobject ; l interface qui étend javax.ejb.ejblocalobject ; la classe d implémentation qui étend javax.ejb.sessionbean ; le fichier ejb jar.xml ; le fichier jboss.xml. XDoclet est une bibliothèque open source qui via, des balises de documentation spécifiques, générera les fichiers java et xml adaptés à la cible choisie. Dans notre cas, cette cible sera de l EJB 2 avec comme serveur de déploiement JBoss. Vous trouverez dans le chapitre Produits supplémentaires une présentation succincte de l utilisation de XDoclet. XDoclet allège le processus de création. Le développeur n a qu à créer la classe d implémentation et paramétrer les balises XDoclet, l outil générera l ensemble des fichiers nécessaires, ainsi que des classes d aide (helper) : une classe xxxutil, dans notre cas CalculetteUtil, qui possède un certain nombre de méthodes permettant d encapsuler la recherche des interfaces Home et LocalHome via JNDI ; une classe xxxsession, dans notre cas CalculetteSession, qui hérite de notre classe d implémentation et de javax.ejb.sessionbean. C est cette classe qui sera référencée dans le fichier ejb jar.xml. Pour les autres types d EJB, le nom de la classe est différent : xxxcmp pour les entités CMP par exemple ; une classe xxxdata de type POJO (Plain Old Java Object), pour les EJB de type entité, qui pourra être utilisée avec des objets de transfert. 4. EJB2 de session Les exemples qui illustrent les EJB2 sont disponibles dans l archive téléchargeable sur le site ENI. Ces exemples sont une vue simplifiée d une application d entreprise. Entre autres, un certain nombre de modèles de conception, que nous utilisons dans des réalisations réelles, ne sont pas présents ici pour ne pas obscurcir la lisibilité du code : pas d objets de transferts (TO pour Transfer Object), une couche DAO simplifiée, des façades simplifiées, absence de classe de localisation (Locator). ENI Editions - All rigths reserved - Kaiss Tag - 7 -

138 De même, la partie Web n utilise pas de framework comme Struts ou autre, mais en garde l esprit en utilisant un contrôleur. Cet exemple simule le choix d un voyage sur une agence en ligne. Les EJB de cet exemple ont été générés avec XDoclet. Seules les classes EJB se terminant par Bean (CaddieBean, DestinationFacadeBean...) ont été écrites. Les interfaces et classes helpers, ainsi que les fichiers de déploiement ejbjar.xml et jboss.xml, ont été générés par un script Ant utilisant XDoclet. L utilisation de XDoclet dans Eclipse est automatisée, le chapitre Produits supplémentaires abordera ce sujet. Cet ouvrage n est pas centré sur les EJB 2 ou EJB 3, il n y aura donc pas une présentation en profondeur de ces frameworks. Les EJB 2 sont présentés avec les fichiers xml minimum pour que le lecteur qui ne connaît pas cette technologie, ne soit pas perdu s il la rencontre. Les EJB 3 ont supplanté les EJB 2 dans les nouveaux projets. Mais il n est pas rare qu un développeur, administrateur ou chef de projet soit amené à intervenir ou à déployer des EJB 2 sur des projets plus anciens, c est la raison pour laquelle ils sont présentés dans cet ouvrage. Les EJB de session sont des composants qui vont être utilisés par une application cliente, distante ou non, mais dont les états ne seront pas persistés en base de données. Tandis que par définition, les EJB entités sont persistants, et donc leur état est sauvegardé en base de données. Les EJB de session sont utilisés pour effectuer des traitements liés à des requêtes du client, ou gérer des objets de session. Les EJB de session peuvent être sans état (stateless), ou avec état (statefull). L EJB sans état ne conserve pas son état, d un appel à l autre d un client, alors que l EJB avec état, le conserve. Une instance d EJB sans état peut être utilisée par plusieurs clients, alors que l instance d une EJB avec état est utilisée par un seul client. Il faut noter que ce n est pas parce que le client demande la création d un EJB par la méthode create(...) sur son interface Home, qu il y a instanciation d un EJB. Le serveur peut gérer des pools d instances et recycler les instances qui ne sont pas utilisées. De même, le serveur peut être amené à sérialiser un EJB de session, et donc à le désérialiser. Attention, ce n est pas parce qu il y a sérialisation, qu il y a persistance. La sérialisation est un mécanisme de gestion des instances interne au serveur. La persistance, quant à elle, permet de sauvegarder l état d un objet en base de données. Les méthodes du cycle de vie de l EJB, qui sont exposées par le biais des interfaces Home, sont appelées par le serveur. De même les méthodes métier ne sont jamais directement invoquées par le client, elles le sont par le serveur si toutes les conditions de transactions, d autorisations sont satisfaites. Quelques exemples d EJB stateless : un calcul d intérêt ; la récupération du code postal d une ville. Quelques exemples d EJB statefull : un panier de commande ; un suivi de paiement. a. stateless Comme vu précédemment, un EJB sans état n est pas associé à un client donné. Une même instance d EJB stateless peut être utilisée par plusieurs requêtes de clients. Une seule requête est exécutée à la fois, les EJB n étant pas multithreadés. Cycle de vie Le cycle de vie d un EJB sans état est très simple. Son instance est existante ou pas ENI Editions - All rigths reserved - Kaiss Tag

139 Comme illustration d un EJB sans état, nous prendrons l EJB DestinationFacadeBean du projet Bovoyage_CMP. Cet EJB permet à une application cliente de récupérer un certain nombre de données sur les destinations. Cet EJB rend des services à l application cliente, mais ne conserve aucun état entre deux requêtes du client. Il s agit donc bien d un EJB sans état. La méthode ejbcreate() est codée dans la classe héritant de javax.ejb.sessionbean. Remarquez que cette méthode renvoie void. public abstract class DestinationFacadeBean implements javax.ejb.sessionbean... public void ejbcreate()... La méthode create() est exposée dans la classe de type javax.ejb.ejbhome. Cette méthode renvoie un proxy sur l interface distante javax.ejb.ejbobject, qui implémente les méthodes métier accessibles via RMI. public interface DestinationFacadeHome extends javax.ejb.ejbhome public org.bovoyage.ejb2.destinationfacade create() throws javax.ejb.createexception,java.rmi.remoteexception; La méthode create() est aussi exposée dans la classe de type javax.ejb.ejblocalhome. Cette méthode renvoie un proxy sur l interface locale javax.ejb.ejblocalobject, qui implémente les méthodes métier accessibles au sein de la même machine virtuelle. public interface DestinationFacadeLocalHome extends javax.ejb.ejblocalhome public DestinationFacadeLocal create() throws javax.ejb.createexception; Méthodes du cycle de vie Notez que les exceptions susceptibles d être levées sont différentes : l exception java.rmi.remoteexception n est levée que s il s agit de méthodes distantes. Méthodes métier Les méthodes métier sont exposées par les interfaces de type javax.ejb.ejbobject pour les méthodes accessibles via RMI, et javax.ejb.ejblocalobject pour les méthodes accessibles localement, au sein de la même machine virtuelle. Ces méthodes sont implémentées dans la classe héritant de javax.ejb.sessionbean. ENI Editions - All rigths reserved - Kaiss Tag - 9 -

140 Extraits des classes : public interface DestinationFacade extends javax.ejb.ejbobject public java.util.list getdestinations( ) throws java.rmi.remoteexception;... public java.util.list getsejours(string iddestination ) throws java.rmi.remoteexception; public interface DestinationFacadeLocal extends javax.ejb.ejblocalobject public java.util.list getdestinations( ) ;... public java.util.list getsejours(string iddestination ) ; public abstract class DestinationFacadeBean implements javax.ejb.sessionbean... public List getdestinations() ArrayList destinations = new ArrayList(); try DestinationLocalHome home = DestinationUtil.getLocalHome(); Collection liste = home.findall(); Iterator it = liste.iterator(); while (it.hasnext()) DestinationLocal local = (DestinationLocal) it.next(); DestinationData data = new DestinationData(local.getId(), local.getpays(), local.getdescription()); destinations.add(data); catch (Exception e) // TODO Auto-generated catch block e.printstacktrace(); return destinations;... Descripteur ejb jar.xml Pour cet EJB stateless, le descripteur de déploiement standard ejb-jar.xml contient les lignes suivantes : <session id="session_destinationfacade"> <description><![cdata[an EJB named DestinationFacade]]></description> <display-name>destinationfacade</display-name> ENI Editions - All rigths reserved - Kaiss Tag

141 <ejb-name>destinationfacade</ejb-name> <home>org.bovoyage.ejb2.destinationfacadehome</home> <remote>org.bovoyage.ejb2.destinationfacade</remote> <local-home> org.bovoyage.ejb2.destinationfacadelocalhome </local-home> <local>org.bovoyage.ejb2.destinationfacadelocal</local> <ejb-class> org.bovoyage.ejb2.destinationfacadesession </ejb-class> <session-type>stateless</session-type> <transaction-type>container</transaction-type> </session> L élément <session> qui indique que l EJB décrit est de type session contient ici les éléments suivants : <description> et <display-name> sont utilisés par certains outils de gestion d EJB au sein d un serveur. Ils peuvent être omis. <ejb-name> contient le nom de l EJB. C est ce nom qui sera repris dans le fichier jboss.xml. <home> contient le nom de l interface qui étend javax.ejb.ejbhome, exposant les méthodes distantes du cycle de vie. <remote> contient le nom de l interface qui étend javax.ejb.ejbobject, exposant les méthodes métier distantes. <local-home> contient le nom de l interface qui étend javax.ejb.ejblocalhome, exposant les méthodes locales du cycle de vie. <local> contient le nom de l interface qui étend javax.ejb.ejblocalobject, exposant les méthodes métier locales. <ejb-class> contient le nom de la classe d implémentation des méthodes du cycle de vie et des méthodes métier. Cette classe implémente l interface javax.ejb.sessionbean. <session-type> indique le type d EJB de session, ici un EJB sans état. <transaction-type> indique ici que les transactions sont gérées par le conteneur. Descripteur jboss.xml Pour cet EJB, le descripteur de déploiement spécifique jboss.xml contient les lignes suivantes : <session> <ejb-name>destinationfacade</ejb-name> <jndi-name>ejb2/destinationfacade</jndi-name> <local-jndi-name>ejb2/local/destinationfacade</local-jndi-name> </session> L élément <session> du fichier jboss.xml est le pendant du même élément du fichier ejb jar.xml. Il permet de préciser le déploiement dans le serveur JBoss. Nous y trouvons ici : <ejb-name> qui contient le nom de l EJB tel qu il a été défini dans la balise <ejb-name> du fichier ejb jar.xml. <jndi-name> contient le nom distant de l EJB, c est ce nom qui sera utilisé par les clients distants, via RMI. L EJB est mis dans le contexte JNDI le plus élevé du serveur pour pouvoir être accessible en dehors du contexte serveur. ENI Editions - All rigths reserved - Kaiss Tag

142 <local-jndi-name> contient le nom local de l EJB. C est ce nom qui sera utilisé par les clients qui sont dans la même machine virtuelle que l EJB, donc au sein du même serveur. Ce nom fait aussi parti du contexte JNDI le plus élevé, mais il ne peut pas être utilisé par un client distant. b. statefull Cycle de vie L instance de l EJB statefull est liée au client qui l utilise, l état de cet EJB peut donc être sérialisé. Ainsi, le cycle de vie de l EJB est un peu plus complexe, puisque l instance peut exister mais être "passiver". Comme illustration d un EJB avec état, nous prendrons l EJB CaddieBean du projet Bovoyage_EJB2. Cet EJB reflète le contenu du panier d achat d un utilisateur, c est donc bien un EJB statefull. Méthodes du cycle de vie Ce type d EJB peut posséder plusieurs méthodes de création. Il faut veiller à ce qu il y ait autant de méthodes createxxxx(...) et create(...) exposées par les interface Home et LocalHome, que de méthodes ejbcreatexxxx (...) et ejbcreate(...) dans la classe d implémentation. public abstract class CaddieBean implements javax.ejb.sessionbean private SessionContext ctx; private List sejours = new ArrayList();... public void ejbcreateavecsejour(sejourdata sejour) this.add(sejour); public void ejbcreate(sejourdata sejour) this.add(sejour); public void ejbcreate() public void setsessioncontext(sessioncontext arg0) throws EJBException, RemoteException this.ctx = arg0; ENI Editions - All rigths reserved - Kaiss Tag

143 Notez que la classe d implémentation met à jour sa propriété ctx de type javax.ejb.sessioncontext, lors de l invocation par le conteneur de la méthode setsessioncontext(...). Voici les signatures dans l interface javax.ejb.ejblocalhome, notez qu elles ne sont pas susceptibles de générer une exception de type java.rmi.remoteexception, puisque les valeurs sont transmises par référence. public interface CaddieLocalHome extends javax.ejb.ejblocalhome public CaddieLocal createavecsejour(sejourdata sejour) throws javax.ejb.createexception; public CaddieLocal create(sejourdata sejour) throws javax.ejb.createexception; public CaddieLocal create() throws javax.ejb.createexception; Voici les signatures dans l interface javax.ejb.ejbhome : public interface CaddieHome extends javax.ejb.ejbhome public Caddie createavecsejour(sejourdata sejour) throws javax.ejb.createexception,java.rmi.remoteexception; public Caddie create(sejourdata sejour) throws javax.ejb.createexception,java.rmi.remoteexception; public Caddie create() throws javax.ejb.createexception,java.rmi.remoteexception; Les méthodes métier sont exposées par les interfaces de type javax.ejb.ejbobject pour les méthodes accessibles via RMI, et javax.ejb.ejblocalobject pour les méthodes accessibles localement, au sein de la même machine virtuelle. Ces méthodes sont implémentées dans la classe héritant de javax.ejb.sessionbean. Extraits des classes : public interface Caddie extends javax.ejb.ejbobject public void add(sejourdata sejour ) throws java.rmi.remoteexception;... Méthodes métier public void remove(sejourdata sejour ) throws java.rmi.remoteexception; public double getprix( ) throws java.rmi.remoteexception; public interface CaddieLocal extends javax.ejb.ejblocalobject public void add(sejourdata sejour ) ; ENI Editions - All rigths reserved - Kaiss Tag

144 public void remove(sejourdata sejour ) ; public double getprix( ) ;... public abstract class CaddieBean implements javax.ejb.sessionbean private SessionContext ctx; private List sejours = new ArrayList(); public void add(sejourdata sejour) if(!sejours.contains(sejour)) sejours.add(sejour); public void remove(sejourdata sejour) if(sejours.contains(sejour)) sejours.remove(sejour);... public double getprix() double prix=0; Iterator it = sejours.iterator(); while(it.hasnext()) SejourData s = (SejourData)it.next(); prix += s.getprix().doublevalue(); return prix; Descripteur ejb jar.xml Pour cet EJB statefull, le descripteur de déploiement standard ejb-jar.xml contient les lignes suivantes : <session id="session_caddie"> <description><![cdata[an EJB named Caddie]]></description> <display-name>caddie</display-name> <ejb-name>caddie</ejb-name> <home>org.bovoyage.ejb2.caddiehome</home> <remote>org.bovoyage.ejb2.caddie</remote> <local-home>org.bovoyage.ejb2.caddielocalhome</local-home> <local>org.bovoyage.ejb2.caddielocal</local> <ejb-class>org.bovoyage.ejb2.caddiesession</ejb-class> <session-type>stateful</session-type> <transaction-type>container</transaction-type> </session> L élément <session> qui indique que l EJB décrit est de type session contient ici les éléments suivants : <description> et <display-name> sont utilisés par certains outils de gestion de EJB au sein d un serveur. Ils ENI Editions - All rigths reserved - Kaiss Tag

145 peuvent être omis. <ejb-name> contient le nom de l EJB. C est ce nom qui sera repris dans le fichier jboss.xml. <home> contient le nom de l interface qui étend javax.ejb.ejbhome, exposant les méthodes distantes du cycle de vie. <remote> contient le nom de l interface qui étend javax.ejb.ejbobject, exposant les méthodes métier distantes. <local-home> contient le nom de l interface qui étend javax.ejb.ejblocalhome, exposant les méthodes locales du cycle de vie. <local> contient le nom de l interface qui étend javax.ejb.ejblocalobject, exposant les méthodes métier locales. <ejb-class> contient le nom de la classe d implémentation des méthodes du cycle de vie et des méthodes métier. Cette classe implémente l interface javax.ejb.sessionbean. <session-type> indique le type d EJB de session, ici un EJB avec état. Attention à l orthographe de Stateful qui ne prend ici qu une lettre "l" finale. <transaction-type> indique ici que les transactions sont gérées par le conteneur. Descripteur jboss.xml Pour cet EJB, le descripteur de déploiement spécifique jboss.xml contient les lignes suivantes : <session> <ejb-name>caddie</ejb-name> <jndi-name>ejb2/caddie</jndi-name> <local-jndi-name>ejb2/local/caddie</local-jndi-name> </session> L élément <session> du fichier jboss.xml est le pendant du même élément du fichier ejb jar.xml. Il permet de préciser le déploiement dans le serveur JBoss. Nous y trouvons ici : <ejb-name> qui contient le nom de l EJB tel qu il a été défini dans la balise <ejb-name> du fichier ejb jar.xml. <jndi-name> contient le nom distant de l EJB, c est ce nom qui sera utilisé par les clients distant, via RMI. L EJB est mis dans le contexte JNDI le plus élevé du serveur pour pouvoir être accessible en dehors du contexte serveur. <local-jndi-name> contient le nom local de l EJB. C est ce nom qui sera utilisé par les clients qui sont dans la même machine virtuelle que l EJB, donc au sein du même serveur. Ce nom fait aussi partie du contexte JNDI le plus élevé, mais il ne peut pas être utilisé par un client distant. 5. EJB2 entité L EJB entité représente un objet persistant dont l état sera donc synchronisé avec un enregistrement en base de données. C est un objet qui possède en plus des méthodes, des données qui correspondent à une réalité du métier. Cette réalité existe en dehors de tout traitement, par exemple un compte client, l identité d une personne, un voyage, etc. Le conteneur d EJB est chargé de retrouver un EJB entité en utilisant les données stockées en base. À chaque enregistrement en base correspond une instance d EJB entité différente. Lorsque l état de l EJB entité change, le conteneur synchronise le contenu de la base de données. Le conteneur doit connaître les associations entre l entité et la base de données. Pour cela, le mapping décrit comment les propriétés de l entité sont enregistrées dans une colonne d une table de la base de données. ENI Editions - All rigths reserved - Kaiss Tag

146 Il existe deux types d EJB entité : les CMP pour Container Managed Persistence. Ce type d EJB est complètement pris en charge par le conteneur d EJB. C est le conteneur qui assure la persistance des données, grâce aux descripteurs de déploiement. les BMP pour Bean Managed Persistence. C est le bean qui assure la persistance des données. Le développeur écrit le code de persistance. L unicité d un EJB entité est liée à la clé primaire qui est, par définition, unique. Cette clé est toujours la même dans tout le cycle de vie de l EJB. Cette notion de clé primaire est primordiale car le conteneur ne connait que cette propriété (qui est immuable pour lui) pour identifier, de manière sûre, un EJB entité. Pour que les états d un EJB entité soient persistés, il faut que les propriétés liées aux états soient sérialisables. Un EJB entité représentant un ensemble de données provenant du système d information, il peut être sollicité simultanément par plusieurs clients. Dans notre exemple, une entité qui représente une destination précise peut être consultée par plusieurs utilisateurs. Les EJB entité sont donc soumis à une concurrence. C est le conteneur qui gère cette concurrence. Concurrence Cette gestion de la concurrence est importante lorsque deux utilisateurs veulent modifier le même EJB entité. Imaginons que sur une destination d1, la secrétaire veuille modifier le champ pays pour corriger une faute de frappe, et qu au même instant, le responsable commercial modifie la description de la destination. La concurrence apparaît si plusieurs utilisateurs utilisent une même entité simultanément. Elle n apparaît pas si les utilisateurs utilisent le bean entité de manière successive et ceci même si les utilisateurs référencient le bean de manière continue. Réentrance ENI Editions - All rigths reserved - Kaiss Tag

147 La réentrance est le fait que, lors de l exécution d un code sollicitant des EJB entité ou session, il est possible d y retrouver un même EJB deux fois. Le bean est sollicité une première fois par un appel de méthode, puis du fait des appels successifs de méthodes, il sera sollicité une seconde fois. Si vous entrez dans le bean une seconde fois, il y a réentrance. Ici, la méthode setprix() sur s1 invoque la méthode mettreajourprix() sur d1, alors que la méthode setprix() de d1 n est pas terminée. Il n y a pas réentrance si les méthodes sont appelées successivement. Il n est pas possible par défaut de faire de la réentrance sur les JEB. L élément <reentrant> du fichier ejb jar.xml permet de modifier cette politique. a. CMP Cycle de vie Le cycle de vie d un EJB entité est plus complexe que celui d un EJB session. En effet, en plus des méthodes de type create(), il y a toutes les méthodes de recherche d un EJB en base de données, en fonction de sa clé primaire. C est le conteneur qui gère ces recherches, qui vont déboucher sur la création d une instance. Il s agit donc de méthodes de création d objet. Ces méthodes de recherches sont du type findxxxx(...), elles sont appelées méthodes "finder". Ces méthodes sont déclarées dans les interfaces de type javax.ejb.ejblocalhome et javax.ejb.ejbhome. Il faut noter que pour respecter l encapsulation de la couche DAO par rapport aux applications clientes, l accès aux finders est souvent effectué par des EJB de session. Il en résulte que souvent, seules les interfaces de type Local sont utilisées. ENI Editions - All rigths reserved - Kaiss Tag

148 Le conteneur appelle les différentes méthodes du cycle de vie. En l occurrence, avant l appel d une méthode métier, le conteneur va synchroniser le CMP avec la base de données. Ensuite, il va appeler la méthode ejbload(), le lien entre l EJB et l enregistrement étant la clé primaire. Si certaines propriétés du CMP ne sont pas persistantes, comme des valeurs calculées, le développeur utilisera la méthode ejbload() pour mettre à jour ces propriétés. Il faut noter que le développeur ne fournit que des classes abstraites. Le conteneur créera les classes concrètes, qui étendront les classes du développeur. Le développeur ne fournit pas non plus les variables d instances qui stockent l état du CMP. Les méthodes du cycle de vie sont exposées via l interface Home, ici javax.ejb.localhome. Notez que les méthodes de recherche font partie des méthodes du cycle de vie. public interface DestinationLocalHome extends javax.ejb.ejblocalhome public DestinationLocal create() throws javax.ejb.createexception; Méthodes du cycle de vie public Collection findall() throws javax.ejb.finderexception; public DestinationLocal findbypays(string nom) throws javax.ejb.finderexception; public DestinationLocal findbyprimarykey(integer pk) throws javax.ejb.finderexception; La classe d implémentation qui implémente javax.ejb.entitybean ne fournit pas d implémentation pour les méthodes de recherche. Ces méthodes "finders" seront décrites dans le fichier ejb jar.xml. Le conteneur se chargera de la création des méthodes. Nous avons les implémentations classiques des méthodes du cycle de vie create(), load(), etc ENI Editions - All rigths reserved - Kaiss Tag

149 Extraits de la classe d implémentation : public abstract class DestinationBean implements javax.ejb.entitybean private EntityContext ctx = null; public java.lang.integer ejbcreate() throws javax.ejb.createexception return null; public void ejbpostcreate() throws javax.ejb.createexception public void setentitycontext(entitycontext arg0) throws EJBException,RemoteException this.ctx = arg0; public void unsetentitycontext() throws EJBException, RemoteException this.ctx=null; En général, les méthodes métier sont principalement composées des getters et setters. Les méthodes sont ici exposées par l interface DestinationLocal qui étend javax.ejb.ejblocalobject. public interface DestinationLocal extends javax.ejb.ejblocalobject public java.lang.integer getid( ) ; Méthodes métier public void setid(integer id ) ; public java.lang.string getpays( ) ; public void setpays(string pays ) ; public java.lang.string getdescription( ) ; public void setdescription(string description ) ; public java.util.collection getsejours( ) ; public void setsejours(collection sejours ) ; L implémentation consiste uniquement à fournir des méthodes abstraites. public class DestinationBean implements javax.ejb.entitybean public abstract java.lang.integer getid( ) ; public abstract void setid(integer id ) ; public abstract java.lang.string getpays( ) ; public abstract void setpays(string pays ) ; public abstract java.lang.string getdescription( ) ; ENI Editions - All rigths reserved - Kaiss Tag

150 public abstract void setdescription(string description ) ; public abstract java.util.collection getsejours( ) ; public abstract void setsejours(collection sejours ) ; Descripteur ejb jar.xml Visualisons d abord l extrait du fichier ejb jar.xml correspondant à la déclaration des EJB entités. <entity id="containermanagedentity_sejour"> <ejb-name>sejour</ejb-name> <local-home>org.bovoyage.ejb2.cmp.sejourlocalhome</local-home> <local>org.bovoyage.ejb2.cmp.sejourlocal</local> <ejb-class>org.bovoyage.ejb2.cmp.sejourcmp</ejb-class> <persistence-type>container</persistence-type> <prim-key-class>java.lang.integer</prim-key-class> <reentrant>false</reentrant> <cmp-version>2.x</cmp-version> <abstract-schema-name>sejour</abstract-schema-name> <cmp-field id="cmpattribute_1"> <field-name>id</field-name> </cmp-field> <cmp-field Id="CMPAttribute_2"> <field-name>depart</field-name> </cmp-field> <cmp-field id="cmpattribute_3"> <field-name>retour</field-name> </cmp-field> <cmp-field id="cmpattribute_4"> <field-name>prix</field-name> </cmp-field> <primkey-field>id</primkey-field> <query> <query-method> <method-name>findall</method-name> <method-params> </method-params> </query-method> <ejb-ql><![cdata[select OBJECT(a) FROM Sejour as a]]></ejb-ql> </query> </entity> <entity id="containermanagedentity_destination"> <ejb-name>destination</ejb-name> <local-home>org.bovoyage.ejb2.cmp.destinationlocalhome</local-home> <local>org.bovoyage.ejb2.cmp.destinationlocal</local> <ejb-class>org.bovoyage.ejb2.cmp.destinationcmp</ejb-class> <persistence-type>container</persistence-type> <prim-key-class>java.lang.integer</prim-key-class> <reentrant>false</reentrant> <cmp-version>2.x</cmp-version> <abstract-schema-name>destination</abstract-schema-name> <cmp-field id="cmpattribute_5"> <field-name>id</field-name> </cmp-field> <cmp-field id="cmpattribute_6"> <field-name>pays</field-name> </cmp-field> <cmp-field id="cmpattribute_7"> <field-name>description</field-name> </cmp-field> <primkey-field>id</primkey-field> <query> <query-method> <method-name>findall</method-name> ENI Editions - All rigths reserved - Kaiss Tag

151 <method-params></method-params> </query-method> <ejb-ql><![cdata[select OBJECT(a) FROM Destination as a]]>...</ejb-ql> </query> </entity> L élément <session> qui indique que les EJB décrits sont de type entité, contient ici, les éléments suivants : <description> et <display-name> sont utilisés par certains outils de gestion de EJB au sein d un serveur. Ils peuvent être omis. <ejb-name> contient le nom de l EJB. C est ce nom qui sera repris dans le fichier jboss.xml. <home> contient le nom de l interface qui étend javax.ejb.ejbhome, exposant les méthodes distantes du cycle de vie. Dans l exemple, il n y a pas d interface Home distante. <remote> contient le nom de l interface qui étend javax.ejb.ejbobject, exposant les méthodes métier distantes. Dans l exemple, il n y a pas d interface Object distante. <local-home> contient le nom de l interface qui étend javax.ejb.ejblocalhome, exposant les méthodes locales du cycle de vie. <local> contient le nom de l interface qui étend javax.ejb.ejblocalobject, exposant les méthodes métier locales. <ejb-class> contient le nom de la classe d implémentation des méthodes du cycle de vie et des méthodes métier. Cette classe implémente l interface javax.ejb.entitybean. <persistence-type> indique comment le conteneur gère la persistance. Il s agit ici de CMP, donc la valeur de l élément est Container, la valeur Bean est réservée pour les entités de type BMP. <reentrant> indique si la réentrace dans l EJB est permise ou pas. False indique ici que la réentrance n est pas permise. <cmp-version> indique la version du CMP. <prim-key-class> indique le type Java de la clé primaire. <abstract-schema-name> : contient le nom du schéma abstrait, qui sera, entre autres, repris dans les requêtes en EJB QL. Ensuite, les différentes propriétés à persister sont décrites dans un élément <cmp-field> qui contient l élément <description> utilisé par certains outils, mais surtout, l élément <fiel-name> contenant le nom du champ dans le schéma abstrait. Ce nom correspond aux accesseurs de la classe abstraite de l entité. Par exemple, le champ prix correspond aux méthodes abstraites setprix(...) et getprix(). Nous trouvons ensuite la déclaration des requêtes. Les requêtes correspondent aux méthodes de recherche d entités, dites "méthodes finders". Elles sont déclarées dans l interface Home, puisqu elles concourent à la création d une instance et donc, font partie du cycle de vie de l EJB entité. L élément <query> comporte les éléments fils : <query-method> qui décrit le côté Java de la méthode finder. <method-name> qui est un élément de <query-method> et contient le nom du finder, ici findall. Ce nom correspond à la méthode findall() de l interface Home. <method-params> qui est un élément de <query-method> et qui décrit les éventuels paramètres à passer à la méthode dans un élément <method-param>. Celui ci contient le type Java du paramètre et correspondra à un paramètre de requête en EJB QL symbolisé par?x, où x est le rang du paramètre dans la requête. ENI Editions - All rigths reserved - Kaiss Tag

152 <ejb-ql> : contient la requête écrite en EJB QL. En général, cette requête est contenue dans un CDATA pour éviter l interprétation des signes >, en effet > peut se trouver dans une clause WHERE de la requête. Par exemple : <query> <query-method> <method-name>findbyprixinferieura</method-name> <method-params> <method-param>java.lang.double</method-param> </method-params> </query-method> <ejb-ql> <![CDATA[SELECT OBJECT(d) FROM Destination AS d WHERE d.prix <?1]]> </ejb-ql> </query> Voici maintenant l extrait du fichier ejb jar.xml correspondant à la description de la relation existant entre les deux EJB entité. <relationships id="relationships_1"> <ejb-relation id="ejbrelation_1"> <ejb-relation-name> Destination-to-Sejours </ejb-relation-name> <ejb-relationship-role id="ejbrelationshiprole_1"> <ejb-relationship-role-name> sejour-vers-une-destination </ejb-relationship-role-name> <multiplicity>many</multiplicity> <relationship-role-source id="rolesource_1"> <ejb-name>sejour</ejb-name> </relationship-role-source> <cmr-field id="cmrfield_1"> <cmr-field-name>destination</cmr-field-name> </cmr-field> </ejb-relationship-role> <ejb-relationship-role id="ejbrelationshiprole_2"> <ejb-relationship-role-name> destination-vers-plusieurs-sejours </ejb-relationship-role-name> <multiplicity>one</multiplicity> <relationship-role-source id="rolesource_2"> <ejb-name>destination</ejb-name> </relationship-role-source> <cmr-field id="cmrfield_2"> <cmr-field-name>sejours</cmr-field-name> <cmr-field-type> java.util.collection </cmr-field-type> </cmr-field> </ejb-relationship-role> </ejb-relation> </relationships> La balise <relationships> contient la définition des relations entre entités. Chaque relation est définie par un élément <ejb-relation>. Avant de décrire les éléments de la relation, regardons comment les relations sont exprimées dans le schéma abstrait ENI Editions - All rigths reserved - Kaiss Tag

153 Il s agit d une relation bidirectionnelle du type "un vers plusieurs". Il existe une collection de Sejours dans Destination et une Destination dans Sejour. Le conteneur doit pouvoir retrouver les données qui correspondent aux deux entités. La description logique d une relation est effectuée dans l élément <ejb-relation>. Comme le nom de l élément l indique, il s agit bien de la description de la relation entre deux EJB, et non pas en base de données, qui sera explicitée dans le fichier jbosscmp jdbc.xml. Descripteur jboss.xml La partie déclarant les entités dans le descripteur jboss.xml est assez simple. Nous y retrouvons un élément <entity> qui est dans l élément père <enterprise-beans>.... <entity> <ejb-name>sejour</ejb-name> <local-jndi-name>ejb2/local/sejour</local-jndi-name> <method-attribute></method-attribute> </entity> <entity> <ejb-name>destination</ejb-name> <local-jndi-name>ejb2/local/destination </local-jndi-name> </entity>... Nous y retrouvons de manière classique maintenant : <ejb-name> contient le nom de l EJB tel qu il a été défini dans la balise <ejb-name> du fichier ejb jar.xml. <jndi-name> contient le nom distant de l EJB, c est ce nom qui sera utilisé par les clients distants, via RMI. L EJB est mis dans le contexte JNDI le plus élevé du serveur pour pouvoir être accessible en dehors du contexte serveur. Cet élément n est pas utilisé ici. <local-jndi-name> contient le nom local de l EJB. C est ce nom qui sera utilisé par les clients qui sont dans la même machine virtuelle que l EJB, donc au sein du même serveur. L élément <method-attribute> n est pas utilisé ici, il permet d optimiser le comportement du conteneur vis à vis de certaines méthodes et de leur gestion dans les transactions. Cet élément peut contenir des éléments fils <method> qui contiennent à leur tour : <method-name> contient le nom d une méthode, ou un modèle de nom de méthode, comme get*, qui correspond à toutes les getters de l entité. <read-only> contient la valeur true qui permettra à JBoss d éviter les accès concurrents sur la même instance d entité, lors de l appel des méthodes marquées en lecture seule. <transaction-timeout> peut contenir une valeur de limite temporelle sur une transaction, exprimée en secondes. Descripteur jbosscmp jdbc.xml Ce descripteur permet à JBoss de faire les liaisons entre les EJB entités décrits dans le fichier ejb jar.xml et les ENI Editions - All rigths reserved - Kaiss Tag

154 champs en base de données. Ce fichier vient compléter les paramétrages généraux qui sont définis dans le fichier de configuration standardjbosscmp jbdc.xml, celui ci étant dans le répertoire conf de la configuration serveur. <jbosscmp-jdbc> <defaults> <datasource>java:/bovoyageds</datasource> <datasource-mapping>mysql</datasource-mapping> <create-table>false</create-table> <alter-table>false</alter-table> <remove-table>false</remove-table> <preferred-relation-mapping> foreign-key </preferred-relation-mapping> </defaults> <enterprise-beans> <entity>... </entity> <entity>... </entity> </enterprise-beans> <relationships> <ejb-relation>... </ejb-relation> </relationships> </jbosscmp-jdbc> La racine <jbosscmp-jdbc> contient principalement les éléments suivants : <defaults> contient les valeurs par défaut, utilisées par les EJB entités et les relations. Le fichier standardjbosscmp jbdc.xml contient une source de données par défaut, qui est DefaultDS. Ici, une nouvelle source de données est mise en place par défaut, pour nos entités et relations. N oubliez pas que pour que la source de données existe, il faut qu elle ait été déployée par l intermédiaire d un fichier xxx ds.xml. <enterprise-beans> contient les EJB entités qui seront à associer à la base de données <relationships> contient la description des relations entre les entités par rapport à la base de données. <dependent-value-classes> contient la description de types complexes, autres classes, qui pourraient correspondre à des descriptions de champ contenus dans des éléments <cmp-field>. L élément <cmp-field> sera étudié plus loin. <type-mappings> contient le mapping entre les types java, JDBC et SQL. Ce mapping dépend aussi de la base de données. Une liste existe par défaut dans le fichier standardjbosscmp jbdc.xml. <reserved-words> contient des éléments <word> permettant de créer une liste de mots réservés. Ces mots réservés ne peuvent pas être utilisés pour nommer des tables ou des champs. Une liste existe par défaut dans le fichier standardjbosscmp jbdc.xml. <user-type-mappings> contient les associations de type personnalisées. <entity-commands> permet de définir des commandes qui pourront être utilisées au sein d un élement <entity>. Une liste d entity-command existe dans le fichier standardjbosscmp jbdc.xml. Exemple d entity-command, extrait du fichier standardjbosscmp jbdc.xml. <!-- retrieves generated key of the record inserted into hsql db --> ENI Editions - All rigths reserved - Kaiss Tag

155 <entity-command name="hsqldb-fetch-key" class="org.jboss.ejb.plugins.cmp.jdbc.keygen.jdbchsqldbcreatecommand"> <attribute name="pk-sql">call IDENTITY()</attribute> </entity-command> Exemple d utilisation de cette entity-command. <jbosscmp-jdbc> <enterprise-beans> <entity> <ejb-name>locationejb</ejb-name>... <entity-command name="hsqldb-fetch-key"/> </entity> </enterprise-beans> </jbosscmp-jdbc> Nous allons voir maintenant comment est effectué le mapping entre l EJB entité et la base de données.... <entity> <ejb-name>sejour</ejb-name> <datasource>java:jdbc/bovoyageds</datasource> <datasource-mapping>mysql</datasource-mapping> <create-table>false</create-table> <remove-table>false</remove-table> <table-name>sejours</table-name> <cmp-field> <field-name>id</field-name> <read-only>false</read-only> <column-name>kp_sejour</column-name> <jdbc-type>integer</jdbc-type> <sql-type>integer</sql-type> </cmp-field> <cmp-field> <field-name>depart</field-name> <read-only>false</read-only> <column-name>depart</column-name> <jdbc-type>date</jdbc-type> <sql-type>datetime</sql-type> </cmp-field>... </entity>... L élément <entity>, contenu dans l élément <enterprise-beans>, contient principalement : <ejb-name> contient le nom de l EJB tel qu il a été défini dans les fichiers ejb jar.xml et jboss.xml. <datasource> contient le nom de la source de données utilisée par cette entité, sinon la source de données par défaut est utilisée. <datasource-mapping> contient le mapping de type utilisé. Attention de bien respecter l orthographe qui est déclaré dans le fichier standardjbosscmp jbdc.xml. <create-table> contient true ou false qui permet la création de la table si celle ci n existe pas. <remove-table> contient true ou false qui permet la suppression de la table lors du repli de l application. ENI Editions - All rigths reserved - Kaiss Tag

156 <table-name> contient le nom de la table utilisée pour le mapping avec l EJB entité. <cmp-field> contient la description des associations entre les propriétés de l entité et les champs de la base de données. Dans l élément <cmp-field>, nous trouverons en général : <field-name> qui contient le nom du champ dans le CMP. <read-only> qui précise si le champ est en lecture seule ou non. <column-name> qui contient le nom de la colonne de la table. <jdbc-type> qui correspond au type JDBC. <sql-type> qui correspond au type SQL. Visualiser les appels à la base de données Le conteneur d EJB gère et génère les requêtes SQL. Pour pouvoir les visualiser sur la console, vous pouvez ajouter une configuration pour le framework de suivi des logs : Log4j. L ajout d un appender dans le fichier jboss log4j.xml du répertoire conf de la configuration serveur, permettra de suivre, sur la console, où vers un fichier en modifiant la configuration, les opérations effectuées en base de données. Dans la liste des appenders présents, vous pouvez ajouter les lignes suivantes : <appender name="cmp" class="org.apache.log4j.consoleappender"> <errorhandler class="org.jboss.logging.util.onlyonceerrorhandler"/> <param name="target" value="system.out"/> <layout class="org.apache.log4j.patternlayout"> <param name="conversionpattern" value="%dabsolute %-5p [%c1] %m%n"/> </layout> </appender> Ainsi, vous pourrez voir dans la console d exécution de JBoss, la prise en charge des CMP et les requêtes générées. 13:49:42,218 DEBUG [Sejour] Initializing CMP plugin for Sejour 13:49:42,234 DEBUG [Sejour] Loading standardjbosscmp-jdbc.xml : file:/c:/ SERVEURS/jboss GA/server/default/conf/standardjbosscmp-jdbc.xml 13:49:42,250 DEBUG [Sejour] jar:file:/c:/serveurs/jboss ga/server/ default/tmp/deploy/tmp1741bovoyageejb2_ear.ear-contents/bovoyage_ejb2.jar!/ META-INF/jbosscmp-jdbc.xml found. Overriding defaults 13:49:42,265 DEBUG [Destination] Initializing CMP plugin for Destination 13:49:42,281 DEBUG [Sejour] Insert Entity SQL: INSERT INTO sejours (kp_sejour, depart, retour, prix, ke_destination) VALUES (?,?,?,?,?) 13:49:42,281 DEBUG [Sejour] Entity Exists SQL: SELECT COUNT(*) FROM sejours WHERE kp_sejour=? 13:49:42,281 DEBUG [Sejour] entity-command: [commandname=default,commandclass =class org.jboss.ejb.plugins.cmp.jdbc.jdbccreateentitycommand,attributes=] 13:49:42,281 DEBUG [Sejour] Remove SQL: DELETE FROM sejours WHERE kp_sejour=? 13:49:42,281 DEBUG [Sejour] Table not create as requested: sejours 13:49:42,281 DEBUG [Sejour#findByPrimaryKey] SQL: SELECT t0_sejour.kp_sejour FROM sejours t0_sejour WHERE t0_sejour.kp_sejour=? 13:49:42,281 DEBUG [Sejour] Added findbyprimarykey query command for local home interface 13:49:42,281 DEBUG [Sejour#findAll] EJB-QL: SELECT OBJECT(a) FROM Sejour as a 13:49:42,281 DEBUG [Sejour#findAll] SQL: SELECT t0_a.kp_sejour FROM sejours t0_a 13:49:42,281 DEBUG [Destination] Insert Entity SQL: INSERT INTO destinations (kp_destination, pays, description) VALUES (?,?,?) 13:49:42,281 DEBUG [Destination] Entity Exists SQL: SELECT COUNT(*) FROM destinations WHERE kp_destination=? 13:49:42,281 DEBUG [Destination] entity-command: [commandname=default, commandclass=class org.jboss.ejb.plugins.cmp.jdbc.jdbccreateentitycommand, ENI Editions - All rigths reserved - Kaiss Tag

157 attributes=] 13:49:42,281 DEBUG [Destination] Remove SQL: DELETE FROM destinations WHERE kp_destination=? 13:49:42,281 DEBUG [Destination] Table not create as requested: destinations 13:49:42,281 DEBUG [Destination#findByPrimaryKey] SQL: SELECT t0_destination. kp_destination FROM destinations t0_destination WHERE t0_destination.kp_ destination=? 13:49:42,281 DEBUG [Destination] Added findbyprimarykey query command for local home interface 13:49:42,281 DEBUG [Destination#findAll] EJB-QL: SELECT OBJECT(a) FROM Destination as a 13:49:42,281 DEBUG [Destination#findAll] SQL: SELECT t0_a.kp_destination FROM destinations t0_a 13:49:42,281 DEBUG [Destination#findByPays] EJB-QL: SELECT OBJECT(a) FROM Destination AS a WHERE a.pays =?1 13:49:42,296 DEBUG [Destination#findByPays] SQL: SELECT t0_a.kp_destination FROM destinations t0_a WHERE (t0_a.pays =?) 13:49:42,296 DEBUG [Sejour] Foreign key constraint not added as requested: relationshiprolename=sejour-vers-une-destination Vous pouvez y voir la prise en charge des CMP, puis la création des requêtes SQL à partir des requêtes en EJB QL. b. BMP Les EJB entité de type BMP (Bean Managed Persistence) demandent un peu plus de travail de la part du développeur. Ils peuvent être utiles lorsque plus de souplesse est demandée à l entité, et lorsque le langage EJB QL ne suffit pas. La prise en charge par le conteneur, d un BMP par rapport à un CMP, diffère par le fait que les accès à la base de données sont codés par le développeur. Bien que le développeur code les méthodes, elles seront toujours appelées par le conteneur d EJB. Cycle de vie Le cycle de vie d un BMP est très proche du cycle de vie d un CMP. La grande différence est que le développeur devra fournir le code pour les méthodes de recherches du type findxxxx(...). Ces méthodes sont déclarées classiquement dans les interfaces de type javax.ejb.ejblocalhome et javax.ejb.ejbhome. Comme pour les CMP, afin de respecter l encapsulation de la couche DAO par rapport aux applications clientes, l accès aux finders est souvent effectué par des EJB de session. Il en résulte que souvent, seules les interfaces de type Local sont utilisées. ENI Editions - All rigths reserved - Kaiss Tag

158 Méthodes du cycle de vie L interface de type javax.ejb.localhome expose les méthodes du cycle de vie. Nous y retrouvons les méthodes de création et de recherche. public interface ParticipantLocalHome extends EJBLocalHome public ParticipantLocal create(string civilite,string nom,string prenom,string , String passeport,integer sejourkey) throws CreateException; public ParticipantLocal create(participantdata participant) throws CreateException; public ParticipantLocal findbyprimarykey(integer id) throws FinderException; public ParticipantLocal findby (string ) throws FinderException; public Collection findbysejourkey(integer sejourkey) throws FinderException; Les implémentations des méthodes métier sont plus complexes que pour le CMP, puisque le développeur doit luimême gérer les requêtes en base de données. Exemple d implémentation d une méthode create(...) : public class ParticipantBean implements EntityBean... public Integer ejbcreate(participantdata participant) throws CreateException ENI Editions - All rigths reserved - Kaiss Tag

159 Integer kp = null; this.civilite = participant.getcivilite(); this.nom = participant.getnom(); this.prenom = participant.getprenom(); this. = participant.get (); this.passeport = participant.getpasseport(); this.sejourkey = participant.getsejourkey(); try kp = bmpcreate(); catch (SQLException e) throw new CreateException("Erreur creation participant \n"+e); return kp; public void ejbpostcreate(participantdata participant) public Integer bmpcreate() throws SQLException String sql = "INSERT INTO participants SET civilite=?,nom=?,prenom=?, =?,passeport=?,ke_sejour=?"; Integer kp = null; Connection con = ds.getconnection(); PreparedStatement ps = con.preparestatement(sql); ps.setstring(1, this.civilite); ps.setstring(2, this.nom); ps.setstring(3, this.prenom); ps.setstring(4, this. ); ps.setstring(5, this.passeport); ps.setint(6, this.sejourkey.intvalue()); ps.executeupdate(); ResultSet rs = ps.getgeneratedkeys(); if (rs.next()) kp = new Integer(rs.getInt(1)); ps.close(); con.close(); return kp;... Exemple d implémentation d un finder : public class ParticipantBean implements EntityBean... public Integer ejbfindbyprimarykey(integer kp) throws FinderException String sql = "SELECT * FROM participants WHERE kp_participant=?"; Connection con = null; boolean trouve=false; try con = ds.getconnection(); PreparedStatement ps = con.preparestatement(sql); ENI Editions - All rigths reserved - Kaiss Tag

160 ps.setint(1, kp.intvalue()); ResultSet rs = ps.executequery(); trouve = rs.next(); con.close(); catch (SQLException e) throw new EJBException("Erreur recherche primarykey"); if(trouve) return this.primarykey; else throw new ObjectNotFoundException("Pas de primarykey en "+kp);... Méthodes métier Classiquement, les accesseurs sont exposés dans les interfaces javax.ejb.ejboject et javax.ejb.ejblocalobjetc. public interface ParticipantLocal extends EJBLocalObject public String getcivilite(); public void setcivilite(string civilite); public String getnom(); public void setnom(string nom); public String getprenom(); public void setprenom(string prenom); public String get (); public void set (string ); public String getpasseport(); public void setpasseport(string passeport); La classe d implémentation de type javax.ejb.entitybean implémente les accesseurs et méthodes métier. Notez que la classe d implémentation d un CMP doit utiliser des propriétés d instance. public class ParticipantBean implements EntityBean private Integer primarykey; private Integer sejourkey; private String civilite; private String nom; private String prenom; private String ; private String passeport; public String getcivilite() return civilite; ENI Editions - All rigths reserved - Kaiss Tag

161 ... public void setcivilite(string civilite) this.civilite = civilite; Descripteur ejb jar.xml Nous retrouvons de manière classique la définition de l EJB....<entity> <ejb-name>participant</ejb-name>... <local-home>org.bovoyage.ejb2.bmp.participantlocalhome</local-home> <local>org.bovoyage.ejb2.bmp.participantlocal</local> <ejb-class>org.bovoyage.ejb2.bmp.participantbean</ejb-class> <persistence-type>bean</persistence-type> <prim-key-class>java.lang.integer</prim-key-class> <reentrant>false</reentrant> </entity>... La recherche de la source de données de type javax.sql.datasource est effectuée lors de l appel de la méthode setentitycontext(...). Il y a recherche dans le contexte JNDI par le nom JNDI, mis en place par le serveur via le fichier de configuration de la source de données. public class ParticipantBean implements EntityBean... private final String dsname = "java:jdbc/bovoyageds"; private DataSource ds; public void setentitycontext(entitycontext arg0) throws EJBException, RemoteException this.ctx = arg0; try InitialContext ct = new InitialContext(); ds = (DataSource) ct.lookup(this.dsname); catch (NamingException e) throw new EJBException(">>> Erreur recherche DataSource", e);... Il faut alors ajouter dans le fichier ejb jar.xml une référence vers une ressource. Ceci est effectué avec l élément <resource-ref>. Le fichier ejb jar.xml devient alors le suivant : <entity>... <ejb-name>participant</ejb-name> <local-home>org.bovoyage.ejb2.bmp.participantlocalhome</local-home> <local>org.bovoyage.ejb2.bmp.participantlocal</local> <ejb-class>org.bovoyage.ejb2.bmp.participantbean</ejb-class> <persistence-type>bean</persistence-type> <prim-key-class>java.lang.integer</prim-key-class> <reentrant>false</reentrant> <resource-ref> <res-ref-name>jdbc/toto</res-ref-name> ENI Editions - All rigths reserved - Kaiss Tag

162 <res-type>javax.sql.datasource</res-type> <res-auth>container</res-auth> </resource-ref>... </entity> L élément <resource-ref> accepte les éléments fils suivants : <res-ref-name> qui correspond au nom de la ressource dans le contexte java:comp/env de l EJB ; <res-type> qui contient le nom de la classe correspondant à la ressource, ici javax.sql.datasource ; <res-auth> qui demande l authentification auprès de la ressource par l intermédiaire du conteneur. Si l EJB gère l authentification par programmation, cet élément doit contenir Application. Il faut faire attention dans ce cas aux problèmes de portabilité de l EJB. Avec cette configuration, la ressource peut être accessible par le nom JNDI java:comp/env/jdbc/toto au lieu de java:jdbc/bovoyageds. Pour que ceci fonctionne, il faut aussi mettre en place, dans le fichier jboss.xml, l association entre les deux nommages JNDI. C est ce que nous allons voir maintenant. Descripteur jboss.xml Dans le descripteur jboss.xml, la déclaration du BMP dans l élément <entity> vous est maintenant familière. Vous y retrouvez le nom de l EJB tel qu il est défini dans le fichier ejb jar.xml, et ses associations JNDI. Ici, seule l interface LocalHome est présente, il n y a donc pas de nom JNDI pour l interface de création distante. <jboss> <enterprise-beans> <entity> <ejb-name>participant</ejb-name> <local-jndi-name>ejb2/local/participant</local-jndi-name> </entity>... <resource-managers> <resource-manager> <res-name>jdbc/toto</res-name> <res-jndi-name>java:jdbc/bovoyageds</res-jndi-name> </resource-manager> </resource-managers> </jboss> Pour assurer l association entre le nom JNDI utilisé dans l EJB, soit dans l exemple précédent java:comp/env/jdbc/toto, et le nom JNDI de la ressource telle qu elle a été enregistrée par JBoss, soit java:jdbc/bovoyageds, il nous faut ajouter les lignes suivantes au fichier jboss.xml. <jboss>... <resource-managers> <resource-manager> <res-name>jdbc/toto</res-name> <res-jndi-name>java:jdbc/bovoyageds</res-jndi-name> </resource-manager> </resource-managers>... </jboss> Ces lignes sont situées en fin de fichier. Les différents alias sont décrits au sein des balises <resource-manager> qui ont, comme élément parent, <resource-managers> ENI Editions - All rigths reserved - Kaiss Tag

163 <res-name> contient le nom de la ressource dans le fichier ejb jar. Dans le fichier ejb jar.xml, ce nom est contenu dans la balise <res-ref-name> ; <res-jndi-name> contient le nom JNDI de la ressource tel qu il a été monté dans le contexte JNDI par JBoss. Vérifiez que JBoss est bien en cours d exécution et que l archive BovoyageEJB2_EAR est déployée, ouvrez un navigateur et tapez l URL de la console JMX : console. Retrouvez le service d affichage de l annuaire de nommage JNDI, c est à dire le lien service=jndiview dans la rubrique jboss. Cliquez sur le lien. Cliquez sur le bouton Invoke de l opération list() du service. Vous devez retrouvez le contexte de nommage pour le BMP Participant. java:comp namespace of the Participant bean: +- env (class: org.jnp.interfaces.namingcontext) +- jdbc (class: org.jnp.interfaces.namingcontext) +- toto[link -> java:jdbc/bovoyageds] (class: javax.naming.linkref) Nous voyons que le contexte java:comp/env/jdbc/toto est lié au contexte java:jdbc/bovoyageds. Retrouvez le contexte de nommage java: : java: Namespace +- XAConnectionFactory (class: org.jboss.mq.spyxaconnectionfactory) +- DefaultDS (class: org.jboss.resource.adapter.jdbc.wrapperdatasource) +- SecurityProxyFactory (class: org.jboss.security.subjectsecurityproxyfactory) +- DefaultJMSProvider (class: org.jboss.jms.jndi.jndiprovideradapter) +- comp (class: javax.naming.context) +- jdbc (class: org.jnp.interfaces.namingcontext) +- BovoyageDS (class: org.jboss.resource.adapter.jdbc.wrapperdatasource) +- JmsXA (class: org.jboss.resource.adapter.jms.jmsconnectionfactoryimpl) +- ConnectionFactory (class: org.jboss.mq.spyconnectionfactory) Le lien est effectif. Lorsque l EJB recherchera dans son contexte de nommage la ressource référencée par java:comp/env/jdbc/toto, il recevra la ressource qui y est liée : java:jdbc/bovoyageds. L implémentation de l EJB est devenu indépendante des nommages des ressources. 6. EJB2 orienté message Si vous n êtes pas familier avec les services de messagerie JMS, reportez vous au chapitre Architecture de JBoss. Les EJB orientés message, MDB pour Message Driven Bean, sont simples. Ils n ont pas d interface d exposition de méthodes métier ou de création, donc par de Home, LocalHome, Object, LocalObject. Ils disposent d une méthode onmessage(). Ils sont sans état. Les MDB peuvent être des abonnés permanents ou non. Si le MDB est un abonné durable au service de messagerie, il recevra tous les messages, même si l EJB orienté message est inactif. Si le MDB n est pas un abonné permanent, les messages seront perdus si le l EJB est inactif. L intérêt des MDB est de pouvoir envoyer ou recevoir des messages asynchrones vers ou provenant d applications tiers, sans qu il y ait de gros impact sur le reste de l application. D autres modes de communications avec des applications tiers sont, bien entendu, envisageables, comme les web services par exemple. Cycle de vie ENI Editions - All rigths reserved - Kaiss Tag

164 Comme l EJB session sans état, le cycle de vie du MDB est très simple. Méthodes du cycle de vie L implémentation de ces méthodes est ici triviale, le cycle de vie de ce type d EJB étant très simple. public class ReceptionConfirmationBean implements javax.ejb.messagedrivenbean, javax.jms.messagelistener private javax.ejb.messagedrivencontext messagecontext = null; public void setmessagedrivencontext(messagedrivencontext messagecontext) throws javax.ejb.ejbexception this.messagecontext = messagecontext;... public void ejbcreate() public void ejbremove() messagecontext = null; Ici, nous avons juste initialisé la propriété messagecontext, de type javax.ejb.messagedrivencontext. C est en fait, l outil XDoclet qui s est chargé de la tâche. Méthode métier La méthode onmessage(...) présentée ici est triviale : un simple affichage dans la console du message reçu. Elle sera invoquée par le conteneur d EJB lors de la réception d un message. public class ReceptionConfirmationBean implements javax.ejb.messagedrivenbean, javax.jms.messagelistener... public void onmessage(javax.jms.message message) // begin-user-code System.out.println("Message Driven Bean got message " + message); // TODO: do business logic here ENI Editions - All rigths reserved - Kaiss Tag

165 ... // end-user-code L envoi du message est assuré, pour cet exemple, par une application Java indépendante. Cet envoi de message peut être effectué par toute application d entreprise orientée message, sans lien avec le langage Java et les platesformes Sun. public class ConfirmationSejour private QueueConnectionFactory factory = null; private InitialContext ctx = null; public static final String JNDI_QUEUE = "queue/b"; public static final String JNDI_QUEUE_FACTORY = "QueueConnectionFactory"; private Queue queue = null; public ConfirmationSejour() try ctx = new InitialContext(); factory = (QueueConnectionFactory) ctx.lookup (JNDI_QUEUE_FACTORY); queue = (Queue) ctx.lookup(jndi_queue); catch (NamingException e) System.out.println("ERREUR SUR CONSTRUCTEUR : " + e); public void envoyermessage(int numerosejour) QueueConnection con = null; try con = factory.createqueueconnection(); QueueSession session = con.createqueuesession(false, Session.AUTO_ACKNOWLEDGE); QueueSender sender = session.createsender(queue); MapMessage message = session.createmapmessage(); Message.setInt("numeroSejour", numerosejour); message.setstring("action", "confirmation"); sender.send(message); System.out.println(">>> MESSAGE ENVOYE : " + message + " "); catch (JMSException jmse) System.out.println("Erreur lors de l envoi des messages : " + jmse.getmessage()); finally if (con!= null) try con.close(); catch (JMSException jmse) ENI Editions - All rigths reserved - Kaiss Tag

166 public static void main(string[] args) ConfirmationSejour cl = new ConfirmationSejour(); cl.envoyermessage(12); Le descripteur de déploiement ejb jar.xml Le descripteur de déploiement précise le nom de l EJB, la classe utilisée et le mode de gestion par le conteneur. Une seule classe est précisée puisqu un EJB orienté message ne possède pas d interface d exposition des méthodes métier ou de cycle de vie. Attention, il y a des différences notables sur le descripteur d un EJB orienté message entre les spécifications EJB 2.0 et EJB 2.1. Nous avons ici un descripteur aux spécifications EJB <message-driven id="messagedriven_1"> <ejb-name>receptionconfirmation</ejb-name> <ejb-class>org.bovoyage.ejb2.mdb.receptionconfirmationmdb</ejb-class> <messaging-type>javax.jms.messagelistener</messaging-type> <transaction-type>container</transaction-type> <message-destination-type> javax.jms.queue </message-destination-type> <activation-config> <activation-config-property> <activation-config-property-name> destinationtype </activation-config-property-name> <activation-config-property-value> javax.jms.queue </activation-config-property-value> </activation-config-property> <activation-config-property> <activation-config-property-name> acknowledgemode </activation-config-property-name> <activation-config-property-value> Auto-acknowledge </activation-config-property-value> </activation-config-property> </activation-config> </message-driven>... L élément <message-driver> permet d assembler l EJB et contient, entre autres, les éléments fils suivants : <ejb-name> : nom de l EJB ; <ejb-class> : classe d implémentation de l EJB ; <messaging-type> : définit la classe fournisseur de message ; <transaction-type> : transaction gérée par le conteneur ou le bean ; <message-destination-type> : destination utilisée par l EJB : sujet (topic) ou file d attente (queue) ; <activation-config> ENI Editions - All rigths reserved - Kaiss Tag

167 L élément <activation-config> a été introduit dans la spécification EJB 2.1. Il remplace les éléments <acknowledgemode> et <message-selector> de la spécification EJB 2.0. Cet élément est constitué d une suite d éléments fils <activation-property> qui permet de définir une propriété. Le nom de cette propriété est défini dans l élément <activation-config-property-name> et sa valeur dans l élément <activation-config-property-value>. Les noms des propriétés supportées pour les EJB MDB sont : acknowledgemode qui spécifie le mode d accusé de réception. Remplace la balise <acknowledge-mode>. messageselector qui permet de filtrer les messages reçus. Si aucun filtre n est précisé, l EJB reçoit tous les messages. Remplace l élément <message-selector>. destinationtype précise la destination utilisée par le MDB : sujet (topic) ou file d attente (queue) en indiquant l interface qui devra être implémentée par la destination concrète. Les interfaces possibles sont : javax.jms.queue et javax.jms.topic. Remplace l élément fils <destination-type> de l élément <messagedriven-destination>. subscriptiondurability précise l abonnement à un sujet, il est permanent (Durable) ou on (NonDurable, par défaut). Remplace l élément fils <subscription-durability> de l élément <message-driven-destination>. Le descripteur de déploiement jboss.xml Le descripteur jboss.xlm est très simple, il précise le nom JNDI de la destination utilisée par l EJB. De manière classique, le nom de l EJB est celui défini dans le descripteur ejb jar.xml.... <message-driven> <ejb-name>receptionconfirmation</ejb-name> <destination-jndi-name>queue/b</destination-jndi-name> </message-driven>... ENI Editions - All rigths reserved - Kaiss Tag

168 Déploiement des EJB 3 La spécification des EJB 3 a nettement simplifié la tâche du développeur. Les points d amélioration les plus spectaculaires sont : La simplification du déploiement car le descripteur de déploiement standard ejb jar.xml a été remplacé par la configuration effectuée par annotation. Le fichier persistence.xml contient le paramétrage des contextes de persistance. Contrairement aux EJB 2, un paramétrage par défaut est mis en place. Par exemple pour les EJB 2 entité, il fallait déclarer toutes les propriétés à associer aux champs des tables, en EJB 3 les associations existent par défaut. Écriture des classes facilitées, puisque les EJB 3 s appuient sur des classes POJO et qu il n est plus nécessaire d utiliser toutes les interfaces du cycle de vie des EJB 2. Un EJB 3 simple peut être écrit avec une seule classe!!! Utilisation des annotations pour faire de l injection de dépendance, ce qui permet de faciliter le couplage avec les ressources ou entre les EJB. Attention, l injection de dépendance du conteneur Web ne fonctionne qu à partir de Tomcat 6. Le déploiement des EJB est effectué dans un fichier JAR. Les fichiers de déploiements ejb jar.xml et jboss.xml peuvent toujours être utilisés. Attention, les noms des méthodes des EJB ne doivent pas commencer par ejb. Comme pour les EJB 2, il ne s agit pas ici de traiter toutes les spécifications se rapportant aux EJB 3, mais de montrer les principes de fonctionnement et de déploiement sous JBoss. 1. Utilisation des annotations Les annotations utilisées dans les classes des EJB 3 correspondent aux éléments des fichiers de configurations des EJB. Il y a deux sortes d annotations : les annotations standard, qui sont définies, pour la plupart, dans le package javax.ejb. Ces annotations sont portables d un serveur à l autre. les annotations spécifiques, qui sont propres à un serveur. Pour JBoss, ces annotations sont dans le package ENI Editions - All rigths reserved - Kaiss Tag - 1 -

169 org.jboss.annotation.ejb. Les annotations spécifiques à un serveur ne sont pas prises en compte par les @RemoteBinding(jndiBinding="ejb3/Calculette/remote") public class CalculetteBean implements CalculetteLocal, CalculetteRemote est une annotation standard qui indique que la classe est un EJB session sans état, et les sont des annotations spécifiques à JBoss qui indiquent les noms JNDI sous lesquels sera monté l EJB. 2. EJB3 de session La définition d un EJB de session reste la même que celle que nous avons vu pour les EJB 2. Il s agit d un objet qui sera utilisé par un client local ou distant et dont les états ne sont pas persistés en base de données. Un EJB de session avec état est lié à une session client, il y a une instance d EJB par client. Un EJB sans état n est pas lié à un client spécifique. Les exemples, qui sont présentés dans cette section, sont issus des projets Bovoyage_EJB3 et BovoyageWeb_EJB3 que vous trouverez dans l archive téléchargeable sur le site ENI. a. stateless L EDB sans état CommandeFacade est ici constitué d une interface et d une classe d implémentation. L interface IDestinationFacade ne fait qu exposer les méthodes public interface IdestinationFacade public List<Destination> getdestinations(); public Destination getdestination(long id); public Sejour getsejour(long id); L permet de préciser que cette interface a seulement une visibilité locale seulement. Une visibilité distante est exprimée par la mise en place de l Si deux interfaces différentes sont utilisées pour l accessibilité des méthodes en local et à distance, il est alors possible d avoir des méthodes différentes selon le type d accès. La classe d implémentation doit évidemment implémenter les deux interfaces. Les peuvent aussi être mises dans la classe d implémentation. Il faudra, alors, préciser la valeur de l interface d exposition des méthodes métier La classe d implémentation code l public class DestinationFacade implements EntityManager public List<Destination> getdestinations() Query query = em.createnamedquery("findall"); List<Destination> destinations = query.getresultlist(); return ENI Editions - All rigths reserved - Kaiss Tag

170 public Destination getdestination(long id) Destination destination = em.find(destination.class, id); return public Sejour getsejour(long id) Sejour sejour = em.find(sejour.class, id); return sejour; L marque la classe comme un EJB sans état. L annotation permet le paramétrage du nom JNDI sous lequel sera déployé l EJB. Nous reviendrons plus loin sur le code des méthodes qui utilisent l unité de persistance. Cycle de vie Le cycle de vie de l EJB sans état reste très simple. Des méthodes callback peuvent être appelées par le conteneur. Ces méthodes sont marquées par les annotations : la méthode sera invoquée après l injection de dépendance : la méthode est invoquée lors de la suppression de l EJB. Ces méthodes peuvent être mises en place directement dans la classe d implémentation, ou dans une classe intercepteur. Implémentation dans la @Local(value=ICalculatrice.class) public class Calculatrice implements public int additionner(int a, int b) return public void debutcalculatrice() ENI Editions - All rigths reserved - Kaiss Tag - 3 -

171 System.out.println(">>> METHODE public void fincalculatrice() System.out.println(">>> METHODE PRE_DESTROY"); Mais, mélanger ainsi le code métier avec les méthodes du cycle de vie peut être dommageable pour la lisibilité et donc la maintenance de la classe. Il est donc possible de créer des classes spécifiques qui seront chargées de gérer le cycle de vie : les classes dites Interceptor. Utilisation d une classe d interception : public class public void debutcalculatrice(invocationcontext ctx) throws Exception System.out.println(">>> AVANT METHODE POST_CONSTRUCT DANS INTERCEPTEUR"); ctx.proceed(); System.out.println(">>> APRES METHODE POST_CONSTRUCT DANS public void fincalculatrice(invocationcontext ctx) throws Exception System.out.println(">>> AVANT METHODE PRE_DESTROY DANS INTERCEPTEUR"); ctx.proceed(); System.out.println(">>> APRES METHODE PRE_DESTROY DANS public Object appelmethode(invocationcontext ctx) throws Exception System.out.println(("INVOCATION DE LA METHODE "+ctx.getmethod().getname())); return ctx.proceed(); Les méthodes reçoivent un objet de type InvocationContext qui permet d exécuter la méthode liée au contexte. Ainsi, il sera possible de mettre en place un comportement adapté, avant et après l appel. Une permet aussi de réagir à l invocation des méthodes métier, en plus des méthodes du cycle de vie. Il faut dans ce cas renvoyer le résultat de l invocation. La classe d implémentation doit indiquer sa classe Interceptor au moyen de @Interceptors(IntercepteurCalculatrice.class) public class CalculatriceAvecIntercepteur implements public int additionner(int a, int b) return a+b; ENI Editions - All rigths reserved - Kaiss Tag

172 Cette annotation peut recevoir une collection de classes, ce qui justifie les accolades. Il est toujours possible d utiliser les méthodes ejbcreate(), ejbremove(). Ces méthodes seront alors traitées par le conteneur, comme si elles avaient été marquées par les b. statefull L EJB Caddie est, dans notre exemple, un EJB avec état. C est lui qui conservera les commandes de séjours durant la session avec le client. L interface présente ici les méthodes métier accessibles en public interface Icaddie public void add(sejour sejour); public void remove(sejour sejour); public double getprix(); public List<Sejour> getsejours(); public Sejour getsejour(long idsejour); public Sejour getsejour(string idsejour); public boolean getvide(); La classe d implémentation code l interface. L indique qu il s agit d un EJB de session public class Caddie implements Icaddie List<Sejour> sejours = new ArrayList<Sejour>(); public void add(sejour sejour) if(!sejours.contains(sejour)) sejours.add(sejour); public void remove(sejour sejour) if(sejours.contains(sejour)) sejours.remove(sejour); public double getprix() double prix=0; for(sejour s : sejours) prix += s.getprix(); return prix; public List getsejours() return sejours; ENI Editions - All rigths reserved - Kaiss Tag - 5 -

173 public Sejour getsejour(long idsejour) Sejour sejour = null; for(sejour s : sejours) if(s.getid()==idsejour) sejour = s; break; return sejour; public Sejour getsejour(string idsejour) return this.getsejour(long.parselong(idsejour)); public boolean getvide() return this.sejours.size()==0; Cycle de vie Les méthodes callback pouvant être invoquées par le conteneur sont plus nombreuses : la méthode sera invoquée après l injection de dépendance : la méthode est invoquée lors de la suppression de l EJB : la méthode est appelée avant la passivation de l EJB, lorsque le conteneur détermine que ce bean peut être sérialisé pour libérer de la mémoire : la méthode est appelée lorsque l EJB est activé, lorsqu il revient en mémoire après avoir été passivé ENI Editions - All rigths reserved - Kaiss Tag

174 3. EJB3 entité Les EJB 3 représentent une révolution par rapport aux EJB 2 entité. Les frameworks tels Hibernate, ibatis ou Toplink ont largement contribué à l essor de cette spécification. La gestion de la persistance est gérée par l API Persistence 1.0 (JSR 220). L entité est représentée par une classe de type POJO annotée, qui sera ensuite persistée au sein d une unité de persistance. Un aspect important dans cette nouvelle spécification est le support de l héritage entre entités, ce qui implique des associations avec la base de données telles que : une table unique pour la hiérarchie de classes ; une table par type concret de classe ; une table pour les propriétés communes, et une table spécifique pour les propriétés suplémentaires de la classe fille. a. Mapping avec la base de données Le mapping des propriétés de la classe avec la base de données est effectué par défaut. Toutes les propriétés sont par défaut persistées. Si la propriété à persister possède le même nom que le champ de la table en base de données, aucune annotation n d FROM Destination as d") ) public class Destination implements Serializable private static final long serialversionuid @Column(name="kp_destination") private long id; private String pays; private String cascade=cascadetype.persist, fetch=fetchtype.eager) private List<Sejour> sejours; public Destination() public Destination(String pays, String description) this.pays = pays; this.description = description; // SUIVENT LES GETTERS ET SETTERS... Au niveau de la classe, nous y trouvons les annotations suivantes : indique qu il s agit d une entité pouvant être prise en charge par l unité de persistance : dont l attribut name indique sur quelle table de la base de données est associée l entité ; ENI Editions - All rigths reserved - Kaiss Tag - 7 -

175 @NamedQuery : qui décrit une requête qui pourra être pré compilée et qui sera utilisable par l unité de persistance. Au niveau des propriétés, nous trouvons les annotations : indique qu il s agit d une clé primaire va préciser le type de stratégie utilisée pour la génération de la clé précise le nom de la colonne dans la table, si le nom de la propriété est différent du nom de la colonne. Toutes les propriétés sont par défaut persistées. Si une propriété ne doit pas être sauvegardée, il faut l annoter Notre destination étant constituée de séjours, nous avons une relation entre les deux entités. Une destination contient une collection de séjours. Un séjour contient une destination. La mise en place de la relation est effectuée avec des annotations relationnelles lie deux entités avec une relation un à un lient une entité unique à une collection, c est ce que nous avons dans notre exemple décrit une relation plusieurs vers plusieurs et nécessite une table de liaisons entre les deux tables des entités. Sur les relations, des opérations en cascade peuvent se produire : PERSIST : les entités liées sont enregistrées avec l entité ; par exemple une entité Personne qui possède une collection d entité Telephone. Les entités Telephone seront enregistrées avec l entité Personne. MERGE : les modifications sont effectuées en cascade ; REMOVE : les suppressions sont effectuées en cascade ; REFRESH : le chargement est effectué en cascade ; ALL : cumul des quatre opérations. Une propriété importante, que nous reverrons dans la partie suivante, est le chargement des objets liés. Notre entité est utilisée dans une servlet, en dehors de l unité de persistance, aussi, nous avons demandé un chargement immédiat par fetch=fetchtype.eager. Côté destination, nous avons la collection de séjour cascade=cascadetype.persist, fetch=fetchtype.eager) private List<Sejour> sejours; Cette collection de séjour est liée à la propriété destination de la classe Sejour : public class Sejour ENI Editions - All rigths reserved - Kaiss Tag

176 @GeneratedValue(strategy=GenerationType.AUTO) private long id; private Date depart; private Date retour; private private Destination destination; // SUIVENT LES GETTERS ET SETTERS... Cette proprété destination est marquée par une (plusieurs séjours pour une destination) et la colonne contenant la clé primaire de la destination dans la table séjour est indiquée (name="ke_destination"). b. Unité de persistance Les entités EJB 3 sont prises en charge par l unité de persistance, qui possède sa propre spécification "Persistence API 1.0". L unité de persistance est caractérisée par : un ensemble d EJB entités ; un fournisseur (provider) de persistance ; une source de données (DataSource) ; un gestionnaire d entités (EntityManager). Le rôle de l unité de persistance est : de retrouver les entités dans la base de données ; d assurer l unicité des instances de chaque entité ; de gérer le cycle de vie des instances via le gestionnaire d entités. Le paramétrage de l unité de persistance est effectué au moyen du fichier persistence.xml, situé dans le répertoire META INF de l archive. Dans notre exemple, ce fichier est très simple : <persistence> <persistence-unit name="bovoyage"> <jta-data-source>java:jdbc/bovoyageds</jta-data-source> </persistence-unit> </persistence> Nous y trouvons : la définition de l unité dans l élément <persistence-unit> à laquelle est donnée un nom unique, ici bovoyage. puis, la liaison avec la source de donnée dans l élément <jta-data-source>. L élément racine <persistence> peut avoir plusieurs éléments fils <persistence-unit>. Voici un résumé des éléments principaux pouvant être contenus dans un élément <persistence-unit> : ENI Editions - All rigths reserved - Kaiss Tag - 9 -

177 <jta-datasource> : nom JNDI de la source de données transactionnelle ; <non-jta-datasource> : nom JNDI de la source de données non transactionnelle ; <mapping-file> : définit un fichier d association XML si les annotations ne sont pas utilisées dans les entités ; <properties> : contient des éléments <property> permettant de configurer le fournisseur de persistance ; <jar-file> : définit les fichiers JAR contenant les entités, par défaut le conteneur analyse l ensemble des classes de l archive qui contient le fichier persistence.xml. Ceci peut être utile si les entités sont dans une autre archive. L interface javax.persistence.entitymanager permet l ajout, la modification, la suppression et la recherche des entités. Pour récupérer un EntityManager, il est possible d utiliser : les annotations, sous JEE ; une fabrique EntityManagerFactory, sous JSE. Les façades de l exemple utilisent public class DestinationFacade implements EntityManager em;... L permet au conteneur d injecter dans la propriété em, l EntityManager qui a été configurée dans le fichier persistence.xml sous le nom bovoyage. Cycle de vie d un EJB entité De nouvelles méthodes callback font leur apparition : PrePersist invoquée avant la méthode persist(...) de l Entitymanager ; PostPersist invoquée après la méthode persist(...) de l Entitymanager ; PostLoad invoquée après le chargement ; PreRemove invoquée avant la méthode remove(...) de l Entitymanager ; PostRemove invoquée après la méthode remove(...) de l Entitymanager ; PreUpdate invoquée avant une mise à jour en base de données ; PostUpdate invoquée après une mise à jour en base de données ENI Editions - All rigths reserved - Kaiss Tag

178 c. Attachement et détachement au contexte de persistance Un concept important, illustré dans ce schéma du cycle de vie, est le fait qu une entité peut être attachée ou détachée du gestionnaire d entités (EntityManager). Pour résumer, tant que l entité est manipulée par des bean contenus dans le conteneur d EJB, l entité est attachée au gestionnaire. Dès que l entité est manipulée en dehors de ce conteneur, elle est détachée. Par exemple, lorsqu une servlet utilise une entité, celle ci est détachée, pour l attacher, il faudra utiliser la méthode merge(...) de l EntityManager. Dans notre exemple, des instances de Passager sont créées par une action dans le conteneur Web, puis ajoutées à une collection. public class AjoutPassagersAction implements public String executer(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException long idsejour = Long.parseLong(request.getParameter("idSejour")); String nb = request.getparameter("nb"); if(nb!=null) int nbpassagers = Integer.parseInt(nb); List<Passager> passagers = new ArrayList(); try InitialContext ctx = new InitialContext(); ICommandeFacade cf = (IcommandeFacade)ctx.lookup("ejb3/local/commandeFacade"); for(int i=1 ; i<=nbpassagers ; i++) String civilite = request.getparameter("civilite_"+i); String nom = ENI Editions - All rigths reserved - Kaiss Tag

179 request.getparameter("nom_"+i); String prenom = request.getparameter("prenom_"+i); String = request.getparameter(" _"+i); String passeport = request.getparameter("passeport_"+i); Passager passager = new Passager(civilite,nom,prenom, ,passeport); passager.setidsejour(idsejour); passagers.add(passager); cf.addpassagers(passagers); catch(exception e) System.out.println("Erreurs sur passagers "+e); return "accueil.jsp"; La classe Passager est une entité, mais elle sera persistée par la façade lors de l appel de la méthode = = "ejb3/local/commandefacade") public class CommandeFacade implements = "bovoyage") EntityManager public boolean addpassagers(list<passager> passagers) boolean ok = true; try for (Passager p : passagers) em.persist(p); catch (Exception e) System.out.println(e); ok = false; return public boolean addpassager(passager passager) boolean ok = true; try em.persist(passager); catch (Exception e) System.out.println(e); ok = false; ENI Editions - All rigths reserved - Kaiss Tag

180 return ok; Pour gérer les entités, nous utilisons les méthodes de l EntityManager : persist(...) permet d enregistrer une entité ; merge(...) permet d attacher une entité ; remove(...) supprime une entité ; find(...) récupère une entité par sa clé primaire. Les modifications de l état de l entité sont synchronisées, si l entité est attachée. Si ce n est pas le cas, il faut rattacher l entité avec la méthode merge(...). Par exemple, une servlet récupère une entité contenant une adresse et l utilisateur modifie l adresse, l enregistrement en base ne sera pas modifié car l entité est détachée. La recherche des entités peut être effectuée par la méthode find(...), mais aussi par public class DestinationFacade implements EntityManager public List<Destination> getdestinations() Query query = em.createnamedquery("findall"); List<Destination> destinations = query.getresultlist(); return public Destination getdestination(long id) Destination destination = em.find(destination.class, id); return public Sejour getsejour(long id) Sejour sejour = em.find(sejour.class, id); return sejour; Dans cet exemple une requête nommée est utilisée, c est la requête qui avait été définie dans l query="select d FROM Destination as d") ) public class Destination implements Serializable... L utilisation de cette requête passe par l utilisation d une instance de Query : ENI Editions - All rigths reserved - Kaiss Tag

181 Query query = em.createnamedquery("findall"); List<Destination> destinations = query.getresultlist(); Le langage EJB QL 3 est plus puissant que le langage EJB QL des EJB 2. Mais nous pouvons aussi utiliser des requêtes natives par la méthode createnativequery() sur l EntityManager. d. Principe du chargement "paresseux" Les propriétés peuvent être chargées en mode paresseux (lazy loading). Ceci permet d optimiser la gestion des temps de réponse et la mémoire, si une propriété est une collection d entités. Dans notre exemple, une instance de Destination contient une collection d instances de Sejour. Lors de l appel de la propriété, celle ci sera chargée, si l entité est attachée. En effet, si l entité est détachée, il se produira une exception. C est pour cette raison que dans notre exemple, nous avons utilisé un autre mode de chargement pour la propriété sejour de la classe cascade=cascadetype.persist, fetch=fetchtype.eager) private List<Sejour> sejours; Ceci nous garantit que les séjours seront chargés en même temps que la destination. Attention, ceci peut être dangereux car la charge mémoire peut devenir importante. 4. EJB3 orienté message Là aussi, la spécification EJB 3 simplifie le codage et le propertyvalue="auto-acknowledge")) public class ReceptionCommande implements private MessageDrivenContext ctx; public void onmessage(message message) System.out.println("<<< Confirmation de commande a reçu " + message); Les annotations remplacent les éléments XML des fichiers de annote la classe comme étant orientée message ; La configuration est une collection d qui reprennent le nom de la propriété et sa valeur. Cet EJB orienté message est activé par la classe suivante, que nous avons déjà vu dans la présentation des MDB en EJB 2 : public class ConfirmationSejour private QueueConnectionFactory factory = null; private InitialContext ctx = null; public static final String JNDI_QUEUE = "queue/b"; ENI Editions - All rigths reserved - Kaiss Tag

182 public static final String JNDI_QUEUE_FACTORY = "QueueConnectionFactory"; private Queue queue = null; public ConfirmationSejour() try ctx = new InitialContext(); factory = (QueueConnectionFactory) ctx.lookup(jndi_queue_factory); queue = (Queue) ctx.lookup(jndi_queue); catch (NamingException e) System.out.println("ERREUR SUR CONSTRUCTEUR : " + e); public void envoyermessage(int numerosejour) QueueConnection con = null; try con = factory.createqueueconnection(); QueueSession session = con.createqueuesession(false, Session.AUTO_ACKNOWLEDGE); QueueSender sender = session.createsender(queue); MapMessage message = session.createmapmessage(); message.setint("numerosejour", numerosejour); message.setstring("action", "confirmation"); sender.send(message); System.out.println(">>> MESSAGE ENVOYE : " + message + " "); catch (JMSException jmse) System.out.println("Erreur lors de l envoi des messages : " + jmse.getmessage()); finally if (con!= null) try con.close(); catch (JMSException jmse) public static void main(string[] args) ConfirmationSejour cl = new ConfirmationSejour(); cl.envoyermessage(12); Le principe reste le même : un message est envoyé dans la file d attente référencée dans le contexte JNDI sous queue/b. Notre MDB implémente l interface javax.jms.messagelistener. Lors de la réception du message dans la file, le conteneur peut invoquer la méthode onmessage(...). ENI Editions - All rigths reserved - Kaiss Tag

183 Cycle de vie Le cycle de vie est toujours aussi simple. Seules les méthodes callback PostConstruct et PreDestroy sont disponibles ENI Editions - All rigths reserved - Kaiss Tag

184 Utilisation des EJB Une fois les EJB déployés, ils sont utilisables en local ou à distance selon le type de client. Comme nous avons pu le voir dans le chapitre sur JNDI, la principale difficulté est de retrouver l objet dans le bon contexte JNDI. 1. Utilisation par une application Web Si l application Web est déployée dans le même serveur que le module EJB, le contexte JNDI est le même. Il faut toujours privilégier cette situation car les appels sont alors locaux. Comme nous avons pu le voir au chapitre Architecture de JBoss, le fichier jboss web.xml de l application web permet de lier le nom JNDI global vers un nommage ENC local à l application : <jboss-web> <context-root>cwc</context-root> <ejb-ref> <ejb-ref-name>service</ejb-ref-name> <jndi-name>ejb2/service-calculette/remote</jndi-name> </ejb-ref> </jboss-web> Le fichier web.xml déclare l EJB et les classes utilisées : <web-app>... <ejb-ref> <ejb-ref-name>service</ejb-ref-name> <ejb-ref-type>session</ejb-ref-type> <home> fr.editions.eni.jboss.chap3.ejb2.servicecalculettehome </home> <remote> fr.editions.eni.jboss.chap3.ejb2.servicecalculette </remote> <ejb-link>chap_3_-_ejb#calculette</ejb-link> </ejb-ref> </web-app> Ensuite, la servlet peut récupérer l instance : InitialContext initctx = new InitialContext(); Context ctx = (Context)initCtx.lookup("java:comp/env"); ServiceCalculetteHome home = (ServiceCalculetteHome)ctx.lookup(calculetteJNDI); Il est préférable d utiliser des noms JNDI dans java:comp/env, plutôt que les noms JNDI globaux, pour des raisons de facilité de maintenance. Si le nom global change, seul le fichier jboss web.xlm est à maintenir. L utilisation des annotations est aussi possible à partir de la version 6 de Tomcat. 2. Utilisation par une application non Web Pour les clients lourds, le principe de recherche reste le même. Il faut ajouter les bibliothèques JBoss adéquates. En général, la librairie jbossall client.jar suffit, vous la trouverez dans le répertoire client du répertoire d installation de JBoss. Ensuite, vous devez avoir un fichier jndi.properties adapté : ENI Editions - All rigths reserved - Bozahi Ali - 1 -

185 java.naming.factory.initial=org.jnp.interfaces.namingcontextfactory java.naming.provider.url=jnp://localhost:1099 java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces Le code de recherche reste ensuite, le même : InitialContext ctx = new InitialContext(); ServiceCalculetteHome home = (ServiceCalculetteHome)ctx.lookup("ejb2/service-calculette/remote"); Le contexte JNDI utilisé ici est évidemment le contexte global, car il est le seul à être accessible en dehors du serveur JBoss ENI Editions - All rigths reserved - Bozahi Ali

186 Introduction Pour illustrer le besoin et le mode de fonctionnement des transactions, nous allons prendre comme exemple, le paiement (simplifié) d un article sur site marchand. Les acteurs sont l acheteur et le fournisseur. Lorsque l acheteur paie son article, les tâches suivantes sont effectuées : 1. le compte de l acheteur est débité du montant du prix de l article ; 2. le compte du fournisseur est crédité du montant du prix de l article ; 3. la quantité d articles en stock est mise à jour. Le diagramme de séquence est le suivant : Le diagramme de séquence peut être codé de la manière suivante :... try... compteacheteur.debiter(article.getprix()); comptefournisseur.crediter(article.getprix()); stock.decrementer(article);... catch(exception e) // gestion de l exception... Ce code est peu sécurisé, il peut être amené à rencontrer plusieurs problèmes. Lors de la levée d une exception sur les opérations debiter(...), crediter(...) ou decrementer(...), le code qui suit la levée de l exception n est pas exécuté. Que se passe t il si l opération qui crédite le compte du fournisseur échoue? Le compte de l acheteur a déjà été débité, mais le processus ayant été interrompu, il ne recevra jamais sa marchandise. Nous voudrions donc, lors d un problème, que toutes les opérations effectuées dans la méthode soient annulées ainsi que les éventuelles modifications en base de données. Il serait possible de songer à gérer par programmation, les états du processus et d annuler les opérations si nécessaire. Les bases de données sont, très certainement, sur des serveurs différents, la gestion de stock fait peutêtre partie d une autre application. Des problèmes réseau, de protocole... seront peut être à gérer. Le développeur va devoir fournir un travail considérable pour gérer les annulations d opérations, avec le risque important de fragiliser le ENI Editions - All rigths reserved - Kaiss Tag - 1 -

187 code, de le rendre illisible et peu maintenable. Heureusement, une solution s offre à nous pour résoudre cette problématique, tout en conservant un code lisible et surtout robuste. Ce sont les transactions. Le code précédent pourrait devenir :... try... transaction.begin(); // début de transaction compteacheteur.debiter(article.getprix()); comptefournisseur.crediter(article.getprix()); stock.decrementer(article); transaction.commit(); // opérations réussies... catch(exception e) // gestion de l exception transaction.rollback(); // annulation des opérations... La tâche à effectuer comprend trois opérations : débiter l acheteur ; créditer le fournisseur ; décrémenter le stock. Ces trois opérations doivent toutes être menées à bien, ou sinon, aucune d entre elle ne sera validée. Cette tâche est souvent appelée unité de travail indivisible, ou unité de travail atomique. La transaction possède des frontières définies : elle démarre (begin) pour commencer une nouvelle transaction ; elle peut être validée (commit) ; elle peut être annulée (rollback). Une transaction se finit de deux manières : elle est validée (commit) ou annulée (rollback). Si une des opérations qui composent la transaction est invalide, l ensemble des opérations qui compose la transaction est annulé. Un acronyme résume les propriétés d une transaction : ACID : ENI Editions - All rigths reserved - Kaiss Tag

188 Atomicité (atomicity) : une transaction doit être atomique, c est à dire qu elle regroupe des tâches qui composent une unité de travail indivisible. Cohérence (consistency) : lorsque la transaction est terminée, elle doit laisser le système dans un état cohérent. Par exemple, les bases de données doivent être cohérentes. C est à dire que les règles d intégrité définies sont valables, qu aucun enregistrement violant l intégrité soit ajouté ou retiré lors d une transaction qui ne se termine pas normalement. Isolation (isolation) : les différentes transactions doivent être isolées les unes des autres. Pour reprendre notre exemple de site marchand, les transactions liées à chaque acte d achat doivent être isolées entre elles, bien que les opérations portent sur les mêmes bases de données. Les bases de données gèrent cette isolation, en mettant en place des mécanismes de verrouillage en lecture/écriture des enregistrements et/ou des tables. Durabilité (durability) : lorsque les changements sont validés, et donc la transaction réussie, les changements doivent être durables, et ceci même en cas de panne serveur, coupure réseau, etc. ENI Editions - All rigths reserved - Kaiss Tag - 3 -

189 Utilisation des transactions Les transactions peuvent être mises en œuvre dans un environnement plus ou moins complexe : Les transactions locales sont mises en œuvre sur un serveur et sur une ressource. les transactions distribuées sont mises en œuvre sur un ou plusieurs serveur(s) et une ou plusieurs ressource (s). Pour reprendre notre exemple, nous pouvons imaginer un bean de type façade encapsulant la transaction, qui effectue les tâches de crédit et débit sur des bases de données différentes. Sur un serveur d application, les transactions peuvent être gérées par le serveur (Container Managed Transactions) ou par le développeur au niveau de l EJB (Bean Managed Transactions). Nous devons connaître le vocabulaire employé dans les API, et le rôle de chacun des objets. L API dédiée aux transactions est JTA, pour Java Transaction API. Une transaction est contrôlée par le gestionnaire de transaction (TransactionManager). Des ressources sont impliquées dans les transactions, il s agit de bases de données ou de files d attente de messages. L accès à ces ressources est effectué via un gestionnaire de ressources. Lorsqu une transaction est initialisée, un contexte transactionnel lui est associé. Ce contexte transactionnel sera propagé par le gestionnaire de transaction aux différents participants de la transaction. ENI Editions - All rigths reserved - Kaiss Tag - 1 -

190 Modèles des transactions Plusieurs modèles transactionnels peuvent être mis en œuvre : gestion des transactions par le bean, BMT pour Bean Management Transaction. Le développeur délimite lui même les transactions par programmation. Ce modèle ne peut être utilisé que sur des EJB de type session ou message, les délimitations des transactions étant toujours effectuées par le conteneur pour les EJB entité. Le développeur utilise une instance de type javax.transaction.usertransaction pour délimiter la transaction. Cette instance est disponible auprès du contexte de session du bean. gestion des transactions par le conteneur, CMT pour Container Management Transaction. C est une gestion déclarative. L EJB n utilise alors aucune méthode de type commit() ou rollback(). Les descriptions et enroulements des EJB dans la transaction sont effectués dans le fichier ejb jar.xml. gestion de la transaction par le client. Dans ce cas, c est le client, une application Web par exemple, qui initie la transaction. Le client récupère un contexte transactionnel auprès de JBoss, via JNDI. Les exemples suivants sont extraits du projet "Chap 7". Une table (banque), très simple en base de données, est constituée de deux champs : un champ pour le numéro de compte, clé primaire : compte ; un champ solde : solde. Une application Web présentant un formulaire, invoquera, via une servlet un EJB façade qui va permettre de créditer le compte d un vendeur, et débiter le compte de l acheteur. La transaction va permettre de gérer le cas où un compte est demandé avec une clé primaire qui n existe pas, ce qui provoque une exception, et donc ne finit pas le traitement. Comme nous l avons vu plus haut, un compte peut alors être crédité, sans que l autre soit débité, si une transaction n est pas mise en place. 1. Gestion programmée des transactions L API JTA (Java Transaction API) permet au développeur de gérer les transactions et leur état. Cette API est utilisable dans les EJB, mais aussi dans les applications clientes, comme les applications Web. Le développeur utilise une instance dérivée de l interface javax.transaction.usertransaction pour contrôler les transactions. Cette interface comporte les méthodes : void begin() : débute la transaction ; void commit() : valide une transaction ; int getstatus() : permet la récupération de l état de la transaction ; void rollback() : annule la transaction ; void setrollbackonly() : met en place une annulation de transaction ; void settransactiontimeout(int) : met à jour le time out de transaction en secondes. La méthode getstatus() renvoie l état de la transaction, qui peut être : STATUS_ACTIVE : transaction en cours et active ; STATUS_NO_TRANSACTION : pas de transaction en cours ; STATUS_MARKED_ROLLBACK : transaction marquée pour être annulée ; STATUS_PREPARING : la transaction est en cours de préparation pour la validation ; ENI Editions - All rigths reserved - Kaiss Tag - 1 -

191 STATUS_PREPARED : transaction prête à être validée ; STATUS_COMMITTING : transaction en cours de validation ; STATUS_COMMITTED : transaction validée ; STATUS_ROLLING_BACK : transaction en cours d annulation ; STATUS_ROLLEDBACK : transaction annulée ; STATUS_UNKNOW : transaction en état indéterminé. a. Gestion programmée des transactions en EJB 2 L URL pour démarrer l exemple est : Le formulaire Web s affiche alors : Dans la base de données, seuls les numéros de compte C1 et C2 existent. L appui sur le bouton Effectuer le virement appelle la servlet EffectuerVirementServlet, dont le code de la méthode doget(...) se résume à : ENI Editions - All rigths reserved - Kaiss Tag

Avant-propos 1. Avant-propos...3 2. Organisation du guide...3 3. À qui s'adresse ce guide?...4

Avant-propos 1. Avant-propos...3 2. Organisation du guide...3 3. À qui s'adresse ce guide?...4 Les exemples cités tout au long de cet ouvrage sont téléchargeables à l'adresse suivante : http://www.editions-eni.fr. Saisissez la référence ENI de l'ouvrage EP5EJAV dans la zone de recherche et validez.

Plus en détail

Remote Method Invocation (RMI)

Remote Method Invocation (RMI) Remote Method Invocation (RMI) TP Réseau Université Paul Sabatier Master Informatique 1 ère Année Année 2006/2007 Plan Objectifs et Inconvénients de RMI Fonctionnement Définitions Architecture et principe

Plus en détail

Apache Tomcat 8 Guide d'administration du serveur Java EE 7 sous Windows et Linux

Apache Tomcat 8 Guide d'administration du serveur Java EE 7 sous Windows et Linux Avant-propos 1. À qui s adresse ce livre? 11 2. Les pré-requis 12 Préambule 1. Rappel sur les architectures Internet/Intranet/Extranet 13 1.1 Le protocole HTTP 14 1.1.1 Les méthodes HTTP 16 1.1.2 Les codes

Plus en détail

JVM. RMI - couche de référence. RMI - couche de transport TCP/IP

JVM. RMI - couche de référence. RMI - couche de transport TCP/IP Chapitre 9 Dans ce chapitre nous abordons le mécanisme RMI (Remote Method Invocation) permettant le développe ment des systèmes répartis. Nous expliquerons comment les classes d un serveur peuvent être

Plus en détail

Java RMI. Programmation des applications réparties. Olivier Flauzac URCA. Master EEAMI-Informatique première année

Java RMI. Programmation des applications réparties. Olivier Flauzac URCA. Master EEAMI-Informatique première année Java RMI Programmation des applications réparties Olivier Flauzac URCA Master EEAMI-Informatique première année Olivier Flauzac (URCA) PAR : Java RMI MSTIC-INFO 1 1 / 30 1 RMI 2 Architecture 3 Développement

Plus en détail

NFP111 Systèmes et Applications Réparties

NFP111 Systèmes et Applications Réparties NFP111 Systèmes et Applications Réparties 1 de 38 NFP111 Systèmes et Applications Réparties Cours 11 - Les Enterprise Java Beans (Introduction aux Enterprise Claude Duvallet Université du Havre UFR Sciences

Plus en détail

Systèmes Distribués Des protocoles client serveur au paradigme objets distribués avec Java

Systèmes Distribués Des protocoles client serveur au paradigme objets distribués avec Java Systèmes Distribués Des protocoles client serveur au paradigme objets distribués avec Java (application avec Java RMI) Éric Leclercq Département IEM / Laboratoire LE2i Décembre 2010 émail : Eric.Leclercq@u-bourgogne.fr

Plus en détail

Institut Supérieur de Gestion. Cours pour 3 ème LFIG. Java Enterprise Edition Introduction Bayoudhi Chaouki

Institut Supérieur de Gestion. Cours pour 3 ème LFIG. Java Enterprise Edition Introduction Bayoudhi Chaouki Institut Supérieur de Gestion Cours pour 3 ème LFIG Java Enterprise Edition Introduction Bayoudhi Chaouki 1 Java EE - Objectifs Faciliter le développement de nouvelles applications à base de composants

Plus en détail

DUT Informatique Module JAVA Apprentis Département Informatique 2008 / 2009. Travaux Pratiques n o 7 : RMI

DUT Informatique Module JAVA Apprentis Département Informatique 2008 / 2009. Travaux Pratiques n o 7 : RMI iut ORSAY DUT Informatique Département Informatique 2008 / 2009 Travaux Pratiques n o 7 : RMI Nom(s) : Groupe : Date : Objectifs : savoir créer des applications client-serveur mettant en jeu des machines

Plus en détail

Programmation par RPC et Java-RMI :

Programmation par RPC et Java-RMI : 2A-SI 3 Prog. réseau et systèmes distribués 3.2 et JavaRMI Stéphane Vialle Stephane.Vialle@supelec.fr http://www.metz.supelec.fr/~vialle Support de cours élaboré avec l aide de l équipe pédagogique du

Plus en détail

Java Remote Method Invocation

Java Remote Method Invocation Java Remote Method Invocation Ce support est très largement inspiré du livre et du cours de S. Krakowiak S. Krakowiak Java Remote Method Invocation 1 / 25 Intérêt des objets pour la construction d applications

Plus en détail

Modèle client-serveur

Modèle client-serveur Modèle client-serveur Daniel Hagimont IRIT/ENSEEIHT 2 rue Charles Camichel - BP 7122 31071 TOULOUSE CEDEX 7 Daniel.Hagimont@enseeiht.fr http://hagimont.perso.enseeiht.fr 1 Plan Principes généraux Modèle

Plus en détail

Java Avancé - Cours 2

Java Avancé - Cours 2 Java avancé - cours 2 1/8 Java Avancé - Cours 2 Plan 1 Communication entre objets 1 1.1 Motivation....................................................... 1 1.2 Relations entre le panier et le rayon.........................................

Plus en détail

RMI (Remote Method Invocation) Client serveur, situation traditionnelle. Client serveur, situation traditionnelle.

RMI (Remote Method Invocation) Client serveur, situation traditionnelle. Client serveur, situation traditionnelle. RMI (Remote Method Invocation) Présentation de RMI Université Française d Egypte Richard Grin Version 0.6 10/10/12 R. Grin RMI page 2 Client serveur, situation traditionnelle Sur la machine A un client

Plus en détail

RMI le langage Java XII-1 JMF

RMI le langage Java XII-1 JMF Remote Method Invocation (RMI) XII-1 Introduction RMI est un ensemble de classes permettant de manipuler des objets sur des machines distantes (objets distants) de manière similaire aux objets sur la machine

Plus en détail

Cours client-serveur Web : Java et RMI (Remote Method Invocation)

Cours client-serveur Web : Java et RMI (Remote Method Invocation) Cours client-serveur Web : Java et RMI (Remote Method Invocation) 1 Java: Rappel sur les threads Cycle de vie d un thread (1) Né -> prêt appel de la méthode start du thread Prêt Exécution Distribution

Plus en détail

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants. RMI Remote Method Invocation: permet d'invoquer des méthodes d'objets distants. Méthode proche de RPC. Outils et classes qui rendent l'implantation d'appels de méthodes d'objets distants aussi simples

Plus en détail

Apache Tomcat 8. Guide d administration du serveur Java EE 7 sous Windows et Linux. Apache Tomcat 8. Apache Tomcat 8

Apache Tomcat 8. Guide d administration du serveur Java EE 7 sous Windows et Linux. Apache Tomcat 8. Apache Tomcat 8 Avant-propos Préambule La plate-forme Java EE Installation et configuration Administration du serveur Déploiement et gestion des applications La sécurité du serveur et des applications Analyse et supervision

Plus en détail

Modèle client-serveur

Modèle client-serveur Modèle client-serveur Daniel Hagimont IRIT/ENSEEIHT 2 rue Charles Camichel - BP 7122 31071 TOULOUSE CEDEX 7 Daniel.Hagimont@enseeiht.fr http://hagimont.perso.enseeiht.fr Remerciements Michel Riveill 1

Plus en détail

Plan. Environnement Client/Serveur. Cours 6 Rappels Java (suite) Appel de méthode à distance. Utilité. static

Plan. Environnement Client/Serveur. Cours 6 Rappels Java (suite) Appel de méthode à distance. Utilité. static Plan Environnement Client/Serveur Cours 6 Rappels Java (suite) Appel de méthode à distance kn@lri.fr http://www.lri.fr/~kn 1 Rappels sur les systèmes d'exploitations / Communication par mémoire partagée

Plus en détail

24/11/2011. Cours EJB/J2EE Copyright Michel Buffa. Plan du cours. EJB : les fondamentaux. Enterprise Java Bean. Enterprise Java Bean.

24/11/2011. Cours EJB/J2EE Copyright Michel Buffa. Plan du cours. EJB : les fondamentaux. Enterprise Java Bean. Enterprise Java Bean. Plan du cours 2 Introduction générale : fondamentaux : les fondamentaux Michel Buffa (buffa@unice.fr), UNSA 2002, modifié par Richard Grin (version 1.1, 21/11/11), avec emprunts aux supports de Maxime

Plus en détail

Sensibilisation à RMI (Remote Method Invocation)

Sensibilisation à RMI (Remote Method Invocation) Jini Sensibilisation à RMI (Remote Method Invocation) Le rêve de tout système distribué L idéal serait d avoir un système distribué utilisant la technologie objet et permettant : 1) d invoquer une méthode

Plus en détail

Table des matières. TP JEE (2) Logic metier et Entreprise Java Beans. IUT Bordeaux 1 - Département Informatique

Table des matières. TP JEE (2) Logic metier et Entreprise Java Beans. IUT Bordeaux 1 - Département Informatique IUT Bordeaux 1 - Département Informatique Semestre 4 JEE 20112012 TP JEE (2) Logic metier et Entreprise Java Beans Les EJB (Enterprise JavaBeans) 3.0 permettent de découpler la logique de présentation

Plus en détail

JAVA PROGRAMMATION. Programme. 1. Java, HTML et World Wide Web

JAVA PROGRAMMATION. Programme. 1. Java, HTML et World Wide Web PROGRAMMATION PUBLIC Professionnels informatiques qui souhaitent développer des applications et «applets» Java DUREE 4 jours 28 heures OBJECTIF Créer divers «applets» à intégrer dans un site Web dynamique,

Plus en détail

Systèmes distribués. Les Sockets

Systèmes distribués. Les Sockets Systèmes distribués Plusieurs technologies existent : Les sockets Les remote procedure call (RPC) Remote Method Invocation (RMI) Les Sockets L'utilisation des Sockets nécessite De gérer le codage et le

Plus en détail

JOnAS Day 5.1. Outils de développements

JOnAS Day 5.1. Outils de développements JOnAS Day 5.1 Outils de développements Agenda Introduction Plugin Eclipse (JOPE) Plugin NetBeans (JOnbAS) Cargo 2 Bull, 2009 JOnAS Day 5.1 Objectifs - Réduire les temps de développement - Construction

Plus en détail

Architecture JEE. Objectifs attendus. Serveurs d applications JEE. Architectures JEE Normes JEE. Systèmes distribués

Architecture JEE. Objectifs attendus. Serveurs d applications JEE. Architectures JEE Normes JEE. Systèmes distribués Architecture JEE. Objectifs attendus Serveurs d applications JEE Systèmes distribués Architectures JEE Normes JEE couches logicielles, n-tiers framework JEE et design patterns 2007/02/28 Eric Hébert.eheb@yahoo.fr

Plus en détail

Cours Serveurs d application. et Java avancé. Introduction au cours Serveurs d application. et Java avancé. Prérequis / Objectifs.

Cours Serveurs d application. et Java avancé. Introduction au cours Serveurs d application. et Java avancé. Prérequis / Objectifs. Cours Serveurs d application et Java avancé Introduction au cours Serveurs d application et Java avancé ITU Université de Nice Richard Grin Version O 1.0.1 12/4/14 20 h de cours et TPs Richard Grin, université

Plus en détail

TP6 EJB : Création d'un EJB3 Entité

TP6 EJB : Création d'un EJB3 Entité TP6 EJB : Création d'un EJB3 Entité Objis : nous allons vous faire aimer JAVA - www.objis.com 1 Table des matières Formation EJB - TP 'Développement EJB3 entity avec Eclipse' Propriété du document...3

Plus en détail

Cahier de charges (Source : "Java EE - Guide de développement d'applications web en Java" par Jérôme Lafosse) Module. Site Web dynamique JSP / Servlet

Cahier de charges (Source : Java EE - Guide de développement d'applications web en Java par Jérôme Lafosse) Module. Site Web dynamique JSP / Servlet Cahier de charges (Source : "Java EE - Guide de développement d'applications web en Java" par Jérôme Lafosse) Module Site Web dynamique JSP / Servlet Sujet : betaboutique Soutenance le 04 / 01 /2013 &

Plus en détail

Spring par la pratique

Spring par la pratique Spring par la pratique 2 e édition Spring 2.5 et 3.0 Arnaud Cogoluègnes Thierry Templier Julien Dubois Jean-Philippe Retaillé avec la contribution de Séverine Templier Roblou et de Olivier Salvatori Groupe

Plus en détail

Programmation Réseau RMI. Jean-Baptiste.Yunes@univ-paris-diderot.fr armand@informatique.univ-paris-diderot.fr. ! UFR Informatique

Programmation Réseau RMI. Jean-Baptiste.Yunes@univ-paris-diderot.fr armand@informatique.univ-paris-diderot.fr. ! UFR Informatique Programmation Réseau RMI Jean-Baptiste.Yunes@univ-paris-diderot.fr armand@informatique.univ-paris-diderot.fr UFR Informatique 2014 Les RMI de Java Les applications RMI sont des applications bâties sur

Plus en détail

Partie 2.2: Servlet et Tomcat

Partie 2.2: Servlet et Tomcat Partie 2.2: Servlet et Tomcat 1 Plan du cours Servlets Présentation Exemple 2 Plan du cours Tomcat Des servlets à Tomcat: pourquoi Tomcat? Architecture Tomcat Installation et configuration de Tomcat Configuration

Plus en détail

Compte Rendu d intégration d application

Compte Rendu d intégration d application ISMA 3EME ANNEE Compte Rendu d intégration d application Compte Rendu Final Maxime ESCOURBIAC Jean-Christophe SEPTIER 19/12/2011 Table des matières Table des matières... 1 Introduction... 3 1. Le SGBD:...

Plus en détail

Java EE Cours 1. Présentation Générale. Cours de 2 e année ingénieur

Java EE Cours 1. Présentation Générale. Cours de 2 e année ingénieur Java EE Cours 1 Présentation Générale Cours de 2 e année ingénieur 1 Présentation du cours Objectifs Développement d applications Web robustes «Ne pas réinventer la roue» utilisation d un framework 1 Apprentissage

Plus en détail

Les architectures N-tiers

Les architectures N-tiers Les architectures N-tiers 1 SOMMAIRE DU COURS XML ET LES ARCHITECTURES N-TIER Introduction aux architectures N-tier Serveurs d applications Déploiement d applications J2EE Tiers applicatif : servlets Tiers

Plus en détail

objectif : plan : Java, CORBA et RMI A. Le Grand,1997 1 JAVA, CORBA et RMI

objectif : plan : Java, CORBA et RMI A. Le Grand,1997 1 JAVA, CORBA et RMI JAVA, CORBA et RMI objectif : développer des applications client/serveur incluant des objets répartis Java / CORBA : client/serveur hétérogènes Java / RMI : client/serveur homogènes plan : l architecture

Plus en détail

JEE - Cours et TP. Mickaël Montassier. 15 février 2007. Institut Universitaire de Technologie Département Informatique

JEE - Cours et TP. Mickaël Montassier. 15 février 2007. Institut Universitaire de Technologie Département Informatique et TP Institut Universitaire de Technologie Département Informatique 15 février 2007 J2EE? J2EE : Java 2 Enterprise Edition Norme prosposée par SUN visant à définir un standard de développement d applications

Plus en détail

Objets distribués et Appel de Méthodes à Distance 2009-2010

Objets distribués et Appel de Méthodes à Distance 2009-2010 Objets distribués et Appel de Méthodes à Distance 2009-2010 1 Objectif : construire une application où différents modules peuvent être situés sur des machines différentes, en utilisant un modèle à objets

Plus en détail

Implementing a simple RMI Application over the. Internet. (using. and

Implementing a simple RMI Application over the. Internet. (using. and Implementing a simple RMI Application over the (using and Internet and comparing HTTP tunneling,, RMI Proxy) Plan de l exposé Introduction Problématique HTTP tunneling Comment RMI «tunnelle» des messages

Plus en détail

Guide Pratique EDI NetBeans

Guide Pratique EDI NetBeans Guide Pratique EDI NetBeans Copyright 2005 Sun Microsystems, Inc. All rights reserved. Table des matières Assistant type de Projet EJB...2 Structure Module EJB...5 Ajout d'ejb, Fichiers et Bibliothèques

Plus en détail

SOA et Services Web. 23 octobre 2011. Evolution des Systèmes d Information

SOA et Services Web. 23 octobre 2011. Evolution des Systèmes d Information SOA et Services Web 23 octobre 2011 1 Evolution des Systèmes d Information 2 Qu est ce qu une application répartie? Il s agit d une application découpée en plusieurs unités Chaque unité peut être placée

Plus en détail

La plate-forme Java RMI

La plate-forme Java RMI La plate-forme Java RMI Frank Singhoff Bureau C-202 Université de Brest, France Lab-STICC/UMR 3192 singhoff@univ-brest.fr UE systèmes à objets répartis, Université de Brest Page 1/25 Sommaire 1. Le modèle

Plus en détail

TP Java RMI. Alexandre Denis Alexandre.Denis@inria.fr. Inria Bordeaux Sud-Ouest France ENSEIRB PG306

TP Java RMI. Alexandre Denis Alexandre.Denis@inria.fr. Inria Bordeaux Sud-Ouest France ENSEIRB PG306 TP Java RMI Alexandre Denis Alexandre.Denis@inria.fr Inria Bordeaux Sud-Ouest France ENSEIRB PG306 Paradigme RMI RMI (Remote Method Invocation) RPC orientés objet (encapsulation, héritage,...) objet :

Plus en détail

Rapport Gestion de projet

Rapport Gestion de projet IN56 Printemps 2008 Rapport Gestion de projet Binôme : Alexandre HAFFNER Nicolas MONNERET Enseignant : Nathanaël COTTIN Sommaire Description du projet... 2 Fonctionnalités... 2 Navigation... 4 Description

Plus en détail

1. QCM (40 points) (1h)

1. QCM (40 points) (1h) Examen 1ère session 2012-2013 page 1 NSY 102 - AISL IPST-CNAM Intranet et Designs patterns NSY 102 Vendredi 26 Avril 2013 Durée : 3 heures Enseignants : LAFORGUE Jacques 1. QCM (40 points) (1h) Mode d'emploi

Plus en détail

Remote Method Invocation en Java (RMI)

Remote Method Invocation en Java (RMI) Remote Method Invocation en Java (RMI) Modélisation et construction des applications réparties (Module M-4102C) J. Christian Attiogbé Fevrier 2015 J. Christian Attiogbé (Fevrier 2015) Remote Method Invocation

Plus en détail

Java EE. Grégory Cuellar, Julien Goullon. 1 er octobre 2007. gregory.cuellar@bull.net. julien.goullon@9business.fr

Java EE. Grégory Cuellar, Julien Goullon. 1 er octobre 2007. gregory.cuellar@bull.net. julien.goullon@9business.fr Grégory Cuellar Julien Goullon gregory.cuellar@bull.net julien.goullon@9business.fr 1 er octobre 2007 1 Généralité 2 / 54 Pourquoi? Historique Les alternatives Les composants 2 Architecture n-tiers 3 JEE

Plus en détail

Système Principal (hôte) 2008 Enterprise x64

Système Principal (hôte) 2008 Enterprise x64 Network Shutdown Module V3 Extension du Manuel Utilisateur pour architecture Virtualisée avec : Hyper-V 6.0 Manager Hyper-V Server (R1&R2) de Microsoft Hyper-V 6.0 Network Shutdown Module Système Principal

Plus en détail

Mise en œuvre des serveurs d application

Mise en œuvre des serveurs d application Nancy-Université Mise en œuvre des serveurs d application UE 203d Master 1 IST-IE Printemps 2008 Master 1 IST-IE : Mise en œuvre des serveurs d application 1/54 Ces transparents, ainsi que les énoncés

Plus en détail

Spécification du profil UML d assemblage cible EJB (version 1)

Spécification du profil UML d assemblage cible EJB (version 1) Spécification du profil UML d assemblage cible EJB (version 1) Auteur : Projet ACCORD (Assemblage de composants par contrats en environnement ouvert et réparti) Référence : Livrable 2.2 Date : 31 mai 2002

Plus en détail

Network Shutdown Module V3 Extension du Manuel Utilisateur pour architecture Virtualisée Virtual Server de Microsoft

Network Shutdown Module V3 Extension du Manuel Utilisateur pour architecture Virtualisée Virtual Server de Microsoft Network Shutdown Module V3 Extension du Manuel Utilisateur pour architecture Virtualisée Virtual Server de Microsoft Virtual Server 2005 R2 Network Shutdown Module Système Principal (hôte) Virtual Server

Plus en détail

Europa. Développement JEE 5. avec Eclipse. K a r i m D j a a f a r. A v e c l a c o n t r i b u t i o n d e O l i v i e r S a l v a t o r i

Europa. Développement JEE 5. avec Eclipse. K a r i m D j a a f a r. A v e c l a c o n t r i b u t i o n d e O l i v i e r S a l v a t o r i Développement JEE 5 avec Eclipse Europa K a r i m D j a a f a r A v e c l a c o n t r i b u t i o n d e O l i v i e r S a l v a t o r i Groupe Eyrolles, 2008, ISBN : 978-2-212-12061-5 5 Le projet WTP (Web

Plus en détail

Développement J2EE. avec Eclipse. et WSAD. Karim Djaafar. Olivier Salvatori. avec la contribution de. Groupe Eyrolles, 2003, ISBN 2-212-11285-8

Développement J2EE. avec Eclipse. et WSAD. Karim Djaafar. Olivier Salvatori. avec la contribution de. Groupe Eyrolles, 2003, ISBN 2-212-11285-8 Développement J2EE avec Eclipse et WSAD Karim Djaafar avec la contribution de Olivier Salvatori Groupe Eyrolles, 2003, ISBN 2-212-11285-8 La plate-forme de développement Eclipse CHAPITRE 5 147 Les vues

Plus en détail

Les formations. Développeur Logiciel. ENI Ecole Informatique

Les formations. Développeur Logiciel. ENI Ecole Informatique page 1/8 Titre professionnel : Inscrit au RNCP de Niveau III (Bac + 2) (J.O. du 19/02/13) 24 semaines + 8 semaines de stage (uniquement en formation continue) Développer une application orientée objet

Plus en détail

1. Installation d'un serveur d'application JBoss:

1. Installation d'un serveur d'application JBoss: EPITA Ala Eddine BEN SALEM App-Ing2 J2EE T.P. 4 EJB3, Serveur d'application JBoss 1. Installation d'un serveur d'application JBoss: télécharger l'archive du serveur JBoss à l'adresse: http://sourceforge.net/projects/jboss/files/jboss/jboss-5.0.0.ga/jboss-5.0.0.ga.zip/download

Plus en détail

Refonte front-office / back-office - Architecture & Conception -

Refonte front-office / back-office - Architecture & Conception - Refonte front-office / back-office - Architecture & Conception - GLG204 - Architectures Logicielles Java 2008/2009 Nom : Cédric Poisson Matricule : 06-49012 Version : 1.0 Jeudi 28 mai 2009 1 / 23 Table

Plus en détail

Introduction au langage Java

Introduction au langage Java Introduction au langage Java 1 / 24 1 Vue générale La technologie Java Le langage Java La machine virtuelle Java Résumé Plan 2 Hello World Prérequis Premier programme : 3 étapes Résumé 3 HelloWorld en

Plus en détail

LANGAGES & DéVELOPPEMENT. Une équipe à vos côtés pour toutes vos montées en compétences

LANGAGES & DéVELOPPEMENT. Une équipe à vos côtés pour toutes vos montées en compétences LANGAGES & DéVELOPPEMENT Une équipe à vos côtés pour toutes vos montées en compétences ASP.NET OPTION VB.NET OU C# 5 jours Permettre aux participants de mieux appréhender ce qu est la programmation pour

Plus en détail

Tour d horizon de Java EE 6

Tour d horizon de Java EE 6 1 Tour d horizon de Java EE 6 De nos jours, les entreprises évoluent dans une compétition à l échelle mondiale. Elles ont besoin pour résoudre leurs besoins métiers d applications qui deviennent de plus

Plus en détail

Programmation orientée objet en langage JAVA

Programmation orientée objet en langage JAVA Programmation orientée objet en langage JAVA Java RMI : Techniques et utilisations avancées de RMI Claude Duvallet Université du Havre UFR Sciences et Techniques 25 rue Philippe Lebon - BP 540 76058 LE

Plus en détail

Objectifs. Comprendre l architecture typique d une application web Exemple: Expérimenter avec:

Objectifs. Comprendre l architecture typique d une application web Exemple: Expérimenter avec: Cedric Dumoulin Objectifs Comprendre l architecture typique d une application web Exemple: Application permettant de lister un catalogue d articles, et de créer des articles Expérimenter avec: EJB, JPA

Plus en détail

Types d applications pour la persistance. Outils de développement. Base de données préexistante? 3 modèles. Variantes avec passerelles

Types d applications pour la persistance. Outils de développement. Base de données préexistante? 3 modèles. Variantes avec passerelles Types d applications pour la persistance Université de Nice Sophia-Antipolis Version 0.9 28/8/07 Richard Grin Toutes les applications n ont pas une complexité qui nécessite une architecture n- tiers Ce

Plus en détail

Familiarisation avec Eclipse / Netbeans

Familiarisation avec Eclipse / Netbeans Institut Galilée LEE Année 011-01 Master T.P. 0 Familiarisation avec Eclipse / Netbeans Lien important contenant le pdf du cours et du TP, et ensuite des sources : http://www-lipn.univ-paris13.fr/~fouquere/mpls

Plus en détail

Site Web de paris sportifs

Site Web de paris sportifs Conception Nom HENAUD Benoît Numéro d auditeur 05-39166 Version V1.1 Date de mise à jour 15/05/2008 1/18 Table des matières 1. Objectif du document... 3 2. Architecture... 4 2.1. Contraintes techniques...

Plus en détail

Java Naming and Directory Interface

Java Naming and Directory Interface Introduction Java Naming and Directory Interface Gaël Thomas gael.thomas@lip6.fr Université Pierre et Marie Curie Master Informatique M2 Spécialité SAR Java Naming and Directory Interface (JNDI) Java Standard

Plus en détail

Formation développement Java, Spring et Hibernate

Formation développement Java, Spring et Hibernate L institut de formation continue des professionnels du Web Formation développement Java, Spring et Hibernate Référence formation : Durée : Prix conseillé : DJSH 10 jours (70 heures) 4 500 HT (hors promotion

Plus en détail

Dr. Djamel Benmerzoug. Email : djamel.benmerzoug@univ-constantine2.dz

Dr. Djamel Benmerzoug. Email : djamel.benmerzoug@univ-constantine2.dz Master 2 SITW Les services Web Dr. Djamel Benmerzoug Email : djamel.benmerzoug@univ-constantine2.dz Maitre de Conférences A, Département TLSI Faculté des NTIC Université Constantine 2 Abdelhamid Mehri

Plus en détail

RMI : Remote Method Invocation Appel de méthodes à distance TD/TP

RMI : Remote Method Invocation Appel de méthodes à distance TD/TP RMI : Remote Method Invocation Appel de méthodes à distance TD/TP Patrice Torguet torguet@irit.fr Université Paul Sabatier But l But du TD/TP : application répartie permettant de gérer des comptes bancaires.

Plus en détail

A. Architecture du serveur Tomcat 6

A. Architecture du serveur Tomcat 6 Administration du serveur A. Architecture du serveur Tomcat 6 La compréhension de l architecture interne du serveur Tomcat 6 est un pré-requis indispensable pour bien en maîtriser l administration et la

Plus en détail

Formation Webase 5. Formation Webase 5. Ses secrets, de l architecture MVC à l application Web. Adrien Grand Centrale Réseaux

Formation Webase 5. Formation Webase 5. Ses secrets, de l architecture MVC à l application Web. Adrien Grand <jpountz@via.ecp.fr> Centrale Réseaux Formation Webase 5 Ses secrets, de l architecture MVC à l application Web Adrien Grand Centrale Réseaux Sommaire 1 Obtenir des informations sur Webase 5 2 Composants de Webase 5 Un

Plus en détail

TD4 : Wikis, Servlets & Projet

TD4 : Wikis, Servlets & Projet Université Bordeaux 1 T.D. License 3 Informatique 2007 2008 TD4 : Wikis, Servlets & Projet L objet de cette séance est de vous familiariser avec les sockets et les servlets, et d introduire le projet.

Plus en détail

Technologies du Web. Créer et héberger un site Web. Pierre Senellart. Page 1 / 26 Licence de droits d usage

Technologies du Web. Créer et héberger un site Web. Pierre Senellart. Page 1 / 26 Licence de droits d usage Technologies du Web Créer et héberger un site Web Page 1 / 26 Plan Planification Choisir une solution d hébergement Administration Développement du site Page 2 / 26 Cahier des charges Objectifs du site

Plus en détail

TP SPRING. https ://lipn.univ-paris13.fr/ fortier/enseignement/spring/tp/

TP SPRING. https ://lipn.univ-paris13.fr/ fortier/enseignement/spring/tp/ Institut Galilée Année 2015-2016 TP SPRING Programmation et Logiciels sûrs Master 2 PLS Résumé L objectif de ce TP est d être capable de réaliser une application Java de gestion de location de véhicules,voiture

Plus en détail

Tsoft et Groupe Eyrolles, 2005, ISBN : 2-212-11623-3

Tsoft et Groupe Eyrolles, 2005, ISBN : 2-212-11623-3 Tsoft et Groupe Eyrolles, 2005, ISBN : 2-212-11623-3 Configuration requise ForestPrep DomainPrep Installation interactive 5 Installation sans surveillance Module 5 : Installation d Exchange Server 2003

Plus en détail

Oracle WebLogic 12c Mise en oeuvre, administration et exploitation du serveur d'applications JEE

Oracle WebLogic 12c Mise en oeuvre, administration et exploitation du serveur d'applications JEE Avant-propos 1. À qui ce livre s'adresse-t-il? 19 2. Prérequis 20 3. Objectifs 20 4. Organisation du livre 21 5. Pour aller plus loin 22 N-tiers, JEE et Oracle WebLogic Server 1. Introduction 23 1.1 Modèle

Plus en détail

Documentation technique

Documentation technique MEEVY Documentation technique Juillet 200 MEEVY a pour but de fournir aux artistes des outils pour promouvoir leur musique sur internet et proposer à l auditeur une plateforme de musique en ligne gratuite

Plus en détail

Etude de cas PLM. Patrice TORGUET IRIT Université Paul Sabatier

Etude de cas PLM. Patrice TORGUET IRIT Université Paul Sabatier Etude de cas PLM Patrice TORGUET IRIT Université Paul Sabatier Plan Exemple PLM Répartition avec Sockets Répartition avec RMI Répartition avec CORBA Répartition avec JMS Répartition avec Java EE Améliorations

Plus en détail

Java c est quoi? Java. Java. Java : Principe de fonctionnement 31/01/2012. 1 - Vue générale 2 - Mon premier programme 3 - Types de Programme Java

Java c est quoi? Java. Java. Java : Principe de fonctionnement 31/01/2012. 1 - Vue générale 2 - Mon premier programme 3 - Types de Programme Java 1 - Vue générale 2 - Mon premier programme 3 - Types de Programme 1 2 c est quoi? Technologie développée par SUN Microsystems lancée en 1995 Dans un des premiers papiers* sur le langage JAVA, SUN le décrit

Plus en détail

TP1 - Entreprise Java Beans

TP1 - Entreprise Java Beans TP1 - Entreprise Java Beans Réseaux Middlewares - Jules Chevalier 1 Configuration Minimale Pour ce TP, vous aurez besoin de outils suivants : Un JDK installé (le JRE est insuffisant) Un IDE édition Java

Plus en détail

Java - RMI Remote Method Invocation. Stéphane Frénot -MID - V.0.2.0 Part I - RMI 1

Java - RMI Remote Method Invocation. Stéphane Frénot -MID - V.0.2.0 Part I - RMI 1 Java - RMI Remote Method Invocation Stéphane Frénot -MID - V.0.2.0 Part I - RMI 1 Répartition d'une application Application de Présentation Middleware Implicite Application de traitement Application de

Plus en détail

Java - RMI Remote Method Invocation

Java - RMI Remote Method Invocation Java - RMI Remote Method Invocation Stéphane Frénot -MID - V.0.2.0 Part I - RMI 1 Répartition d'une application Application de Présentation Système d'exploitation Middleware Implicite Application de traitement

Plus en détail

Architectures à composants

Architectures à composants Interaction requête/réponse Architectures à composants!communication par requête/réponse client requête réponse serveur Gaël Thomas gael.thomas@lip6.fr Université Pierre et Marie Curie Master Informatique

Plus en détail

Les Systèmes et Applications Réparties et leur Programmation

Les Systèmes et Applications Réparties et leur Programmation Les Systèmes et Applications Réparties et leur Programmation Samia Bouzefrane Maître de Conférences Laboratoire CEDRIC Conservatoire National des Arts et Métiers 292 rue Saint Martin 75141 Paris Cédex

Plus en détail

Spring IDE. Mise en œuvre. Eclipse

Spring IDE. Mise en œuvre. Eclipse A Spring IDE Bien que Spring mette à disposition d intéressants mécanismes afin d améliorer l architecture des applications Java EE en se fondant sur l injection de dépendances et la programmation orientée

Plus en détail

TD2: Servlets et bases de données; initiation aux EJB3 avec Eclipse

TD2: Servlets et bases de données; initiation aux EJB3 avec Eclipse TD2: Servlets et bases de données; initiation aux EJB3 avec Eclipse 1. Sérialisation de requêtes Nous allons étudier ici les possibilités offertes par les servlets en tant que services offerts à un programme

Plus en détail

SQL Server Installation Center et SQL Server Management Studio

SQL Server Installation Center et SQL Server Management Studio SQL Server Installation Center et SQL Server Management Studio Version 1.0 Grégory CASANOVA 2 SQL Server Installation Center et SQL Server Management Studio [03/07/09] Sommaire 1 Installation de SQL Server

Plus en détail

Java pour le Web. Cours Java - F. Michel

Java pour le Web. Cours Java - F. Michel Java pour le Web Cours Java - F. Michel Introduction à JEE 6 (ex J2EE) Historique Qu'est-ce que JEE JEE : Java Entreprise Edition (ex J2EE) 1. Une technologie outils liés au langage Java + des spécifications

Plus en détail

Manuel d'utilisation de la console de supervision

Manuel d'utilisation de la console de supervision Manuel d'utilisation de la console de supervision Ce document décrit la mise en route et l'utilisation de la console d'administration web de PEtALS. EBM WebSourcing (MarieSauvage) - Mai 2007 - (CC) EBM

Plus en détail

Java EE Approfondi - Cours 2. Cours de 2 e année ingénieur Spécialisation «Génie Informatique»

Java EE Approfondi - Cours 2. Cours de 2 e année ingénieur Spécialisation «Génie Informatique» Java EE Approfondi - Cours 2 Cours de 2 e année ingénieur Spécialisation «Génie Informatique» Présentation Lier l'orienté objet et la base de données relationnelle peut être lourd et consommateur en temps.

Plus en détail

Cours en ligne Développement Java pour le web

Cours en ligne Développement Java pour le web Cours en ligne Développement Java pour le web We TrainFrance info@wetrainfrance Programme général du cours Développement Java pour le web Module 1 - Programmation J2ee A) Bases de programmation Java Unité

Plus en détail

Urbanisation et architecture des systèmes d information

Urbanisation et architecture des systèmes d information Urbanisation et architecture des systèmes d information Plate forme pour le composant logiciel 2/2 JAVA, JEE et les EJB David Eudeline eudeline.david@free.fr JAVA Qu'est ce que JAVA? Un langage très jeune

Plus en détail

PROGRAMMATION DISTRIBUÉE TUTORIEL RMI

PROGRAMMATION DISTRIBUÉE TUTORIEL RMI PROGRAMMATION DISTRIBUÉE TUTORIEL RMI PUBLIC CONCERNÉ : formation initiale, 2 e année. NOM DE L AUTEUR : V. Thomas DATE 2012/2013 UNIVERSITÉ DE LORRAINE IUT NANCY CHARLEMAGNE 2 ter boulevard Charlemagne

Plus en détail

Mise en œuvre des serveurs d application

Mise en œuvre des serveurs d application Nancy-Université Mise en œuvre des serveurs d application UE 203d Master 1 IST-IE Printemps 2008 Master 1 IST-IE : Mise en œuvre des serveurs d application 1/57 Ces transparents, ainsi que les énoncés

Plus en détail

Traitement et navigation

Traitement et navigation 12 Traitement et navigation Au chapitre précédent, nous avons vu comment créer des pages web avec différentes technologies (HTML, JSP, JSTL, etc.) en insistant sur le fait que JSF est la spécification

Plus en détail

J2EE. A.-E. Ben Salem. 09 Octobre 2011. LRDE and LIP6 1 / 15

J2EE. A.-E. Ben Salem. 09 Octobre 2011. LRDE and LIP6 1 / 15 J2EE A.-E. Ben Salem LRDE and LIP6 09 Octobre 2011 1 / 15 Plan 1 J2EE 2 Architecture Client/Serveur HTTP 3 Différence entre Web Statique et Web Dynamique 4 Web Dynamique avec un Serveur d applications

Plus en détail

TP JEE Développement Web en Java. Dans ce TP nous commencerons la programmation JEE par le premier niveau d une application JEE : l application web.

TP JEE Développement Web en Java. Dans ce TP nous commencerons la programmation JEE par le premier niveau d une application JEE : l application web. ASTRIUM - Toulouse JEE Formation 2013 TP JEE Développement Web en Java Dans ce TP nous commencerons la programmation JEE par le premier niveau d une application JEE : l application web. Figure 1 Architecture

Plus en détail

Chapitre 1 Windows Server 2008 11

Chapitre 1 Windows Server 2008 11 Chapitre 1 Windows Server 2008 11 1.1. Les fondations du système... 15 1.2. La virtualisation... 16 1.3. La sécurité... 18 1.4. Le Web... 20 1.5. Fonctionnalité disponible dans Windows Server 2008... 21

Plus en détail

Création d une application JEE

Création d une application JEE Création d une application JEE Rédacteurs : Alexandre Baillif, Philippe Lacomme, Raksmey Phan et Michaël PLAN Date : juillet 2010 Mise à jour : Michaël PLAN Date : octobre 2014 Avertissement : - ce document

Plus en détail

TP 2 : programmation côté serveur À rendre pour le mardi 6 mai 2008

TP 2 : programmation côté serveur À rendre pour le mardi 6 mai 2008 Université Claude Bernard Lyon 1 UFR d informatique avril 2006 MIAG soir Systèmes d Information Méthodes Avancées TP 2 : programmation côté serveur À rendre pour le mardi 6 mai 2008 Introduction Dans ce

Plus en détail