EJB 3

formation interne pour CLIO S.A.

Cédric BOTTERO Michaël MATHIEU Genève, le 30 juin 2009

Plan
• • • • • • • Introduction 3 types d’EJB (Session, Entity, Message-Driven) Injection et JNDI Intercepteurs et callbacks Transactions (CMT, BMT) Sécurité Persistance avec JPA

Introduction
• Permet d’éviter au développeur d’avoir à se préoccuper de tout ce qui a trait au système :
– – – – – – – – – Transactions Sécurité Evolutivité Concurrence Communications Gestion des ressources Persistance Gestion des erreurs Etc.

3 types d’EJB • Session – Stateless – Stateful • Entity (depuis la version 3. est un simple POJO) • Message-Driven .

Session • Sont conçus pour encapsuler la logique métier • Les plus utilisés • 2 types d’EJB session : – Stateless – Stateful .

puis. une instance de ce dernier sert le client.Session -> Stateless • Stateless (sans état) => les attributs de l’EJB sont réinitialisées entre chaque appel même s’il s’agit du même client • Sont spécialement pensés pour être robustes et fiables lorsqu’il y a beaucoup d’appels en concurrence • Lorsqu’un client appelle l’EJB. retourne dans le pool d’EJB (cette dernière est donc prête a être réutilisée pour un autre client) • A utiliser le plus souvent possible (par rapport aux Stateful) => cycle de vie .

3 • Pour les EJB session stateless. l’utilisation du javax.PortableRemoteObject.EJB 2 vs. nous commencerons par présenter leur utilisation avec les EJB 2. puis avec les 3 • Le but est de montrer les améliorations et simplifications amenées avec la version 3 • Cela permettra également de mieux comprendre le principe de fonctionnement des EJB (par exemple.nar row(…)) .rmi.

Structure d’un EJB • Avec les EJB 2.xml • Avec les EJB 3. la configuration des EJB se fait dans le fichier META-INF/ejb-jar. le fichier de configuration n’est plus nécessaire: la configuration se fait dans le code au moyen des annotations .

Session -> Stateless EJB 2 .

Session -> Stateless EJB 2 • Par convention. les méthodes métier ne doivent pas commencer par « ejb » . et ce afin d’éviter des malentendus.

Session -> Stateless EJB 2 META-INF/ejb-jar.xml .

Session -> Stateless EJB 2 .

Session -> Stateless EJB 3 .

Session -> Stateless EJB 3 .

Cette instance sera détruite à la fin de la session (timeout ou appel à une méthode portant l’annotation @Remove) • S’il y a trop d’instances d’un EJB en mémoire. Cette instance reste disponible pour les futurs appels de ce client uniquement.Session -> Stateful • Stateful (avec état) => les attributs de l’EJB sont sauvegardés durant toute la session • Lorsqu’un client appelle l’EJB. ces dernières peuvent être sorties de la mémoire de travail. une instance de ce dernier est créée. Elles passent ainsi en mode passif (= sauvées sur disque => tous les attributs doivent être sérialisables = types implémentant l’interface Serializable) . puis sert le client.

le destinataire vérifie que le serialVersionUID de l’objet reçu correspond à celui de la classe qu’il a chargé. S’il diffère. dans le cas où on ajoute un nouvel attribut à un objet. une InvalidClassException est lancée • Ce mécanisme permet de s’assurer que l’émetteur et le destinataire travaillent avec la même version de l’objet • Cette solution a une faiblesse: lors d’une modification.Sérialisation • Le type des attributs et le type de retour de chaque méthode doivent être Serializable (sauf dans le cas d’une méthode d’un EJB stateless local) • Par précaution. alors que cela n’est pas forcément nécessaire. En effet. nous tâcherons de veiller à ce que tous les types que nous utilisons soient Serializable • Le serialVersionUID permet de faire la distinction entre des objets de même type. elle nécessite que toutes les applications qui utilisent cette classe doivent être mis à jour. mais d’une version différente • Lorsque qu’un objet est reçu. cela ne signifie pas forcément que toutes les applications ont l’utilité de ce nouvel attribut… => on donne une valeur arbitraire par défaut au serialVersionUID et on ne la modifie pas .

Remote • Permet de spécifier la manière d’accéder à l’EJB => l’implémentation des services est identique • Local ≠ appel à un EJB se trouvant sur la même machine = appel à un EJB se trouvant dans la même JVM • Remote – utilise RMI (Remote Method Invocation) (=> plus lent qu’un appel local) et JNDI (Java Naming and Directory Interface) – utilisé dans la majorité des cas .Local vs.

Local EJB 2 .

Local EJB 2 .

Local EJB 2 META-INF/jboss.xml .

Local EJB 2 .

xml .Local EJB 2 META-INF/jboss.

Local EJB 2 .

Local EJB 3 .

cfg. mais directement dans le code avec des annotations (@Id.Entity • Permet de gérer la persistance comme le ferait Hibernate sur le concept de object-relational mapping (ORM) => illusion de travailler avec une base de données objet • Le mapping ne se fait plus forcément dans un fichier XML (comme hibernate. @Column. etc.xml).) • D’avantage de détails dans le dernier chapitre de ce cours « Persistance avec JPA » .

Message-Driven • Permet à des applications de communiquer entre elles.Queue pub-sub (publish-subscribe) javax. PTP (point-to-point) javax. etc.jms.jms.Topic . JBoss Messaging (qui remplacera JBoss MQ). et de manière asynchrones • Ce concept est connu sous le nom de Message-oriented middleware (MOM) • Les produits implémentant ce mécanisme sont nombreux comme IBM WebSphere MQ (anciennement MQSeries). en étant faiblement couplées.

Ici.Message-Driven • Nous devons configurer le produit qui implémente le mécanisme JMS.5-GA) • Le fichier de configuration doit être déposé dans le répertoire <jboss-install>/server/<configurationname>/deploy/jms. il s’agit de JBoss MQ qui est intégré à notre version de JBoss (4.0. et son nom doit se terminer par – service.xml .

Message-Driven EJB 3 .

Message-Driven EJB 3 .

Message-Driven EJB 3 .

Message-Driven • Il y a la possibilité de mettre un filtre sur les messages qui peuvent être traités par un MDB. Manning . 2007. Dans le cas d’un Topic (pubsub). cela permet surtout de ne pas avoir à tester si le message reçu peut être traité par le MDB • Pour d’avantage de précisions sur la propriété messageSelector. Cette propriété est surtout intéressante dans le cas d’une Queue (PTP). car le message n’est envoyé qu’à un seul MDB. Cela permet de ne pas recevoir certains messages. nous vous renvoyons à la page 131 du livre « EJB 3 in Action ».

Byte. JMS. Par exemple. il faudra alors donner son nom JNDI (@Resource(name="jdbc/myDB")avec les EJB 2. Integer. Si une ressource n’est pas trouvée lors du déploiement.). Double ou Float) qui ont été préalablement déclarées dans le descripteur de déploiement : • Lors du déploiement. dans le cas d’une DataSource. etc. s’il y en a plusieurs définies sur le serveur. Short.Injection et JNDI • L’annotation @Resource permet d’injecter un objet référencé (au sens large: DataSource. Il est possible de spécifier le nom JNDI de l’objet pour lever une ambiguïté. dans le descripteur de déploiement. le conteneur résout les références JNDI et relie les ressources en question. EJB. l’EJB est alors inutilisable . Boolean. Context. le conteneur lance une RuntimeException. Character. on utilisait la balise <res-ref-name>) • Il est également possible d’injecter des variables d’environnement (de type String. Long.

• Exemple pour vérifier le rôle de l’appelant : . les intercepteurs permettent d’exécuter des méthodes avant que la méthode métier ne soit exécutée • Les intercepteurs peuvent être utiles dans plusieurs situations: pour mettre des logs sans avoir à surcharger le code.Intercepteurs • Lorsqu’une méthode métier est appelée. pour gérer la sécurité séparément du code métier. etc.

Intercepteurs
EJB 3

• Les intercepteurs peuvent être défini au niveau du descripteur de déploiement, de la classe, de la méthode (ordre dans lequel ils sont appelés)

Callbacks
• Les callbacks permettent d’exécuter des méthodes lorsque certains événements liés au cycle de vie de l’EJB interviennent (création, suppression, hibernation, réveil) • Après la création (@PostConstruct) (Stateless, Stateful, Message-Driven) • Avant la suppression (@PreDestroy) (Stateless, Stateful, Message-Driven) • Avant l’hibernation (@PrePassivate) (Stateful) • Après le réveil (@PostActivate) (Stateful)

Intercepteurs et callbacks
• Session -> Stateless

Intercepteurs et callbacks • Session -> Stateful .

Intercepteurs et callbacks • Entity .

Intercepteurs et callbacks • Message-Driven .

le résultat de cette dernière est durable : que la transaction ait été annulée ou qu’elle se soit terminée correctement.Transactions ACID • Atomicité Pour atteindre un but donné. les opérations qu’elle a effectué ne doivent pas disparaître Exemple : transfert bancaire • • • . le base de données ou le système doit se trouver dans un état cohérent Isolation Une transaction doit se réaliser sans dépendre des autres transactions qui peuvent avoir lieu en même temps Durabilité Lorsqu’une transaction s’est terminée. une transaction est composée de plusieurs opérations qui sont indispensables => soit toutes les opérations sont effectuées. soit aucune ! • Cohérence Après qu’une transaction se soit réalisée.

le conteneur gère les transactions • JPA (Java Persistance API) ne dépend pas du mode de gestion des transactions => n’influe que sur les EJB Session et les Message-Driven.BEAN) – CMT (Container-Managed Transactions) => @TransactionManagement(TransactionManagementTyp e. et non sur les Entity .Transactions • JTA (Java Transaction API) fournit un API permettant de gérer les transactions : – BMT (Bean-Managed Transactions) => @TransactionManagement(TransactionManagementTyp e.CONTAINER) – Par défaut.

valide ou annule la transaction.ejb.ejb. La transaction commence au début de l’exécution de la méthode métier appelée et se termine à la fin de cette dernière Transaction @TransactionAttribute existante lors de l'appel ? REQUIRED (par défaut) REQUIRED_NEW Non Oui Non Oui Non Oui Non Oui Non Oui Non Oui Résultat Le conteneur crée une nouvelle transaction La méthode rejoint la transaction existante Le conteneur crée une nouvelle transaction Le conteneur crée une nouvelle transaction et la transaction existante est suspendue Aucune transaction n'est utilisée La méthode rejoint la transaction existante Lève une javax.EJBTransactionRequiredException La méthode rejoint la transaction existante Aucune transaction n'est utilisée La transaction existante est suspendue et la méthode est appelée sans transaction Aucune transaction n'est utilisée Lève une javax.CMT • Le conteneur démarre.EJBException SUPPORTS MANDATORY NOT_SUPPORTED NEVER .

CMT • On peut forcer le fait que la transaction soit annulée (context.setRollBackOnly()) • Les méthodes setRollbackOnly() et getRollbackOnly() ne peuvent être appelées que depuis un EJB dont les transactions sont gérées par le conteneur (CMT) et ayant comme attribut de transaction REQUIRED. la transaction sera automatiquement annulée . REQUIRED_NEW ou MANDATORY Sinon une IllegalStateException est levée ! • Si le conteneur détecte une exception système (principalement les RuntimeException) comme une ArrayIndexOutOfBoundsException ou une NullPointerException.

ejb. nous n’avons pas le contrôle sur le moment où la transaction est démarrée.SessionSynchronization – void afterBegin() — Est appelé juste après que le conteneur ait créé une nouvelle transaction et avant que la méthode métier soit appelée – void beforeCompletion() — Est appelé lorsque la méthode métier s’est terminée et juste avant que le conteneur termine la transaction – void afterCompletion(boolean committed) — Est appelé après que la transaction soit terminée. Le flag committed indique si la transaction a été validée (true) ou si elle a été annulée (false) . validée ou annulée • Il est possible d’être informé de ces évènements grâce à des callbacks • L’EJB doit implémenter l’interface javax.CMT • Avec CMT.

.begin(). • La UserTransaction ne peut être utilisée que dans le cas où les transactions sont gérées par l’EJB (BMT). dans le cas où c’est le conteneur (CMT) une IllegalStateException est levée . UserTransaction userTransaction = context..commit(). OU – @Resource private SessionContext context..BMT • On utilise la UserTransaction – @Resource private UserTransaction userTransaction. • userTransaction. OU userTransaction.getUserTransaction()..rollback().. userTransaction. .

il faut que les drivers des bases de données soient de type XA • L’architecture XA définit un protocole de validation en 2 phases et un API pour la communication entre un transaction manager et un resource manager • Dans le cas d’une transaction où l’on doit enregistrer des données dans 2 bases de données. dans un contexte où les sources de données sont distribués.Transactions distribuées XA (eXtended Architecture) • Afin de garantir les propriétés ACID vues précédemment. que faire si lors de la validation une se déroule avec succès et l’autre non ? L’application se trouvera alors dans un état inconsistant et les propriétés ACID ne seront plus respectées ! => utilisation du protocole de validation en 2 phases .

la technique la plus simple.SECURITY_CREDENTIAL) sont transmis avant le lookup au contexte JNDI . mais aussi la plus ancienne et la plus limitée : le username (Context.SECURITY_PRINCIPAL) et le password (Context. JAAS authentifie (valide l'identité du client) – Puis gère les autorisations (valide les droits d'accès pour un client authentifié) – Les identités sont regroupées en rôles et les autorisations accordées par rôle • Côté client.Sécurité • JAAS (Java Authentication and Authorization Service) est une API standard de Java permettant de gérer les identifications et les droits associés (par rôles) au niveau du client et du serveur d'application • Principe de fonctionnement : – Dans un premier temps.

.. @PermitAll.Sécurité • L’authentification est réalisée par une application web qui ensuite appelle l’EJB en lui passant le Principal • Pour sécuriser une méthode. il existe 2 possibilités : – Avec les annotations (@RolesAllowed(.).) . @DenyAll) – Avec la méthode isCallerInRole(...

nous utiliserons la méthode d’authentification SimpleServerLoginModule : – Si le mot de passe est null. nous devons définir une politique de sécurité dans le fichier <jbossinstall>/server/<configuration-name>/conf/loginconfig.Sécurité • Dans un premier temps.xml . alors l’utilisateur est authentifié avec les rôles guest et user – Sinon l’authentification échoue • Pour cela. alors l’utilisateur est authentifié avec le rôle guest – Si le nom d’utilisateur est égal au mot de passe. il faut configurer la sécurité JAAS sur le serveur • Pour nous simplifier la tâche.

on déclare le domaine de sécurité par l’annotation @SecurityDomain(.jboss. nous aurions plutôt utilisé la méthode d’authentification DatabaseServerLoginModule qui effectue une requête dans une base de données qui contiendrait les noms d’utilisateurs.aspects.SecurityDoma in et non org. les mots de passe.jboss.Sécurité • Remarque : dans le cadre d’une vraie application.. ainsi que les rôles associés aux utilisateurs • Dans les 2 exemples qui suivent..security.security.) ATTENTION utiliser l’interface org.annotation.SecurityDomain .

Sécurité • Avec les annotations .

..Sécurité • Avec la méthode isCallerInRole(.) .

Sécurité • Pour pouvoir accéder aux méthodes précédemment sécurisées. il faut que l’appelant soit correctement identifié avec JAAS • Prenons le cas d’une application web .

xml (contenu sur le slide suivant) .xml • Définir ce qui sera sécurisé. et quelle sera la page d’authentification et la forme de celle-ci : fichier <yourweb-app>/WEF-INF/web.Sécurité • Définir le domaine de sécurité : fichier <your-webapp>/WEB-INF/jboss-web. comment.

.

Sécurité • Page JSP qui permet d’appeler l’authentification JAAS : fichier <your-web-app>/WEB-INF/jsp/login.jsp .

Sécurité • Appel de l’EJB depuis la Servlet : .

0. l’utilisation de son successeur ne demanderait que peu d’adaptation • Pour cette partie.Persistance avec JPA • Intérêt de JPA: permet d’être indépendant du framework gérant la persistance => si Hibernate venait à disparaître. Eyrolles . nous profitons pour vous indiquer une excellente référence : Hibernate 3. nous partons du principe que vous êtes déjà familiarisé avec Hibernate et avec le concept d’ORM (ObjectRelational Mapping) • Au passage. 2005.

xml) – many-to-many => .xml) <set name="bookmarks" table="WEBSITE_USER"> <key column="ID_USER" /> <many-to-many class="WebSite" column="ID_WEBSITE" /> </set> (User.xml) <set name="users" inverse="true"> <key column="NATIONALITY" /> <one-to-many class="User" /> </set> (Country.hbm.hbm.xml) <many-to-one column="NATIONALITY" name="nationality“ class="Country" /> (User.hbm.hbm.Persistance avec Hibernate • Un petit rappel sera tout de même le bienvenu ! • Les différents types de relations : – – – one-to-one many-to-one one-to-many => => => <one-to-one name="user" class="User" constrained="true" /> (Email.

Persistance avec JPA • Activer la persistance JPA (META-INF\persistence.xml) • Au préalable une DataSource a été déclarée sur le serveur (<jboss-install>/ server/ <configuration-name> /deploy) .

Persistance avec JPA @Entity • Cette annotation permet de spécifier qu’une classe doit être persistée par JPA • Cette classe doit posséder un constructeur public ou protected sans argument @Transient • Permet de spécifier qu’il ne faut pas persister un attribut donné .

Manning. 2007 .Persistance avec JPA @Id • Permet de définir quel champ sera utilisé comme clé primaire @IdClass. @Embeddable + @EmbeddedId • Permettent de définir des clés composées • Nous n’allons pas les aborder dans le cadre de ce cours • Nous vous renvoyons à la page 235 du livre « EJB 3 in action ».

ORM • @OneToOne Remarque: fonctionne très bien dans une utilisation « naïve ». comme @PrimaryKeyJoinColumn [http://en. mais cela devient problématique lorsque l’on veut utiliser des fonctionnalités plus intéressantes.wikibooks.org/wiki/Java_Persistence/Identity_and_S equencing#Primary_Keys_through_OneToOne_Relationships] • @OneToMany • @ManyToOne • @ManyToMany .

ORM .

ORM .

ORM .

.

nécessite de recompiler les classes modifiées. surtout dans le cas de la persistance JPA : – Dégrade la lisibilité du code – Perte de la séparation entre Entité et Mapping – En cas de modification.ORM • Inconvénients des annotations. au lieu de juste modifier les fichiers de mapping concernés => à utiliser plutôt dans le cas d’un prototype • Solution plus élégante : utilisation d’un fichier de mapping XML (META-INF\orm.xml) (contenu sur les slides suivant) .

xml (1/2) .orm.

xml (2/2) .orm.

Héritage • Avec JPA.JOINED) – des tables indépendantes (InheritanceType. il est également possible d’avoir une notion d’héritage entre les entités • Le développeur doit choisir la manière dont seront stockées les informations (@Inheritance(strategy= .org/wiki/Java_Persistence/Inheritance ... nous vous renvoyons à la page 284 du livre « EJB 3 in Action ».TABLE_PER_CLASS) • Pour d’avantage de précisions.)): – une seule table (InheritanceType.wikibooks. Manning + http://en.SINGLE_TABLE) – plusieurs tables liées (InheritanceType. 2007.

il existe des callbacks pour le Entity • Avant / après la persistance d’une Entity (@PrePersist / @PostPersist) • Après avoir chargé une Entity lors d’une requête ou d’un refresh (@PostLoad) • Avant / après la mise à jour d’une Entity (@PreUpdate / @PostUpdate) • Avant / après la suppression d’une Entity (@PreRemove / @PostRemove) .Callbacks • Comme pour les EJB session et les Message-Driven.

2005. 2005.sun. SUPINFO [http://www. SUN [http://java. Manning • The J2EE 1.html] • EJB 2. SUPINFO [http://www. 2009.Références • EJB 3 in action. 2006.4/docs/tutorial/doc/index.labo-sun.org/wiki/Java_Persistence] . 2007.com/j2ee/1.4 Tutorial.labo-sun. WIKIBOOKS [http://en.com/resource-fr-essentiels836-0-java-j2ee-ejb-3-les-entreprise-java-bean-version-3-javabeans-.wikibooks.htm] • EJB 3.com/resource-fr-essentiels835-0-java-j2ee-ejb-2-les-entreprise-java-bean-javabeans-.htm] • Java Persistence. Manning • JBoss in action.

FIN Merci pour votre attention ! .

Sign up to vote on this title
UsefulNot useful