IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Penser en Java 2nde édition - Sommaire |  Préface |  Avant-propos | Chapitre : 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15 |  Annexe : A B C D  | Tables des matières - Thinking in Java

  Chapitre 15 - Informatique distribuée

pages : 1 2 3 4 5 6 7 8 9 10 11 12 

Activation du processus du service de nommage

Nous avons enfin un serveur et un client prêts à interopérer. Nous avons pu voir que tous deux ont besoin du service de nommage pour associer et résoudre les références alphanumériques. Le processus du service de nommage doit être démarré avant de faire fonctionner aussi bien le serveur que le client. Dans JavaIDL, le service de nommage est une application Java fournie avec le produit, mais qui peut être différente dans d'autres produits. Le service de nommage de JavaIDL fonctionne dans une JVM et écoute par défaut le port réseau 900.

Activation du serveur et du client

Vos applications serveur et client sont prêtes à démarrer (dans cet ordre, puisque votre serveur est transient (temporaire)). Si tout est bien en place, vous obtiendrez une simple ligne de sortie dans la fenêtre console de votre client, indiquant l'heure courante. Bien sûr, cela ne semble pas très excitant en soit, mais vous devriez prendre en compte une chose : même si ils sont physiquement sur la même machine, les applications client et serveur fonctionnent dans des machines virtuelles différents et peuvent communiquer à travers une couche de l'intégration sous-jacente, l'ORB et le service de nommage.

Ceci constitue un exemple simple, destiné à fonctionner sans réseau, mais un ORB est généralement configuré pour qu'il rende les localisations transparentes. Lorsque le serveur et le client sont sur des machines différentes, l'ORB peut résoudre des références alphanumériques en utilisant un composant désigné Implementation Repository. Bien que le Implementation Repository fasse partie de CORBA, il n'y a quasiment pas de spécification, et donc il est différent d'un fabricant à l'autre.

Ainsi que vous vous en doutez, CORBA représente davantage que ce qui est montré ici, mais ainsi vous aurez compris l'idée de base. Si vous souhaitez plus d'informations à propos de CORBA, le premier endroit à visiter est le site Web de l'OMG : http://www.omg.org. Vous y trouverez la documentation, les white papers et les références vers les autres sources et produits pour CORBA.

Les Applets Java et CORBA

Les applets Java peuvent se comporter comme des clients CORBA. Par ce biais, une applet peut accéder à des informations et des services distants publiés sous la forme d'objets CORBA. Mais une applet ne peut se connecter qu'au serveur depuis lequel elle a été téléchargée, aussi tous les objets CORBA avec lesquels l'applet interagit doivent être situés sur ce serveur. C'est l'opposé de ce que CORBA essaye de faire : vous offrir une totale transparence de localisation.

C'est une question de sécurité réseau. Si vous êtes sur un intranet, la solution est d'éliminer les restrictions de sécurité du navigateur. Ou, de mettre en place une politique de firewall pour la connexion vers des serveurs externes.

Certains produits proposant des ORBs Java offrent des solutions propriétaires à ce problème. Par exemple, certains implémentent ce qui s'appelle un HTTP Tunneling, alors que d'autres ont des fonctionnalités firewall spécifiques.

C'est un point trop complexe pour être exposé dans une annexe, mais c'est quelque chose que vous devriez approfondir.

CORBA face à RMI

Vous avez vu que la principale fonctionnalité de CORBA est le support de RPC, qui permet à vos objets locaux d'appeler des méthodes d'objets distants. Bien sûr, il y a déjà une fonctionnalité native à Java qui réalise exactement la même chose : RMI (voir Chapitre 15). Là où RMI rend possible RPC entre des objets Java, CORBA rend possible RPC entre des objets implémentés dans n'importe quel langage.

Toutefois, RMI peut être utilisé pour appeler des services auprès de code distant non-Java. Tout ce dont vous avez besoin est d'une sorte d'objet Java adaptateur autour du code non-Java sur la partie serveur. L'objet adapteur est connecté à l'extérieur aux objets clients par RMI, et en interne il se connecte au code non-Java en utilisant l'une des techniques vues précédemment, comme JNI ou J/Direct.

Cette approche nécessite que vous écriviez une sorte de couche d'intégration, exactement ce que CORBA fait pour vous, mais vous n'avez pas besoin ici d'un ORB venu de l'extérieur.

Enterprise Java Beans

[70]A partir de maintenant, vous avez été présenté à CORBA et à RMI. Mais pourriez-vous imaginer de tenter le développement d'une application à grande échelle en utilisant CORBA et/ou RMI ? Votre patron vous a demandé de développer une application multi-tiers pour consulter et mettre à jour des enregistrements dans une base de données, le tout à travers une interface Web. Vous vous assoyez et pensez à ce que cela veut vraiment dire. Sûr, vous pouvez écrire une application qui utilise JDBC, une interface Web qui utilise JSP et des Servlets, et un système distribué qui utilise CORBA/RMI. Mais quelles autres considérations devez-vous prendre en compte lorsque vous développez un système basé sur des objets distribués plutôt qu'avec des APIs classiques ? Voici les problèmes :

Performance : Les nouveaux objets distribués que vous avez créé devront être performants puisque ils devront potentiellement répondre à plusieurs clients en même temps. Donc vous allez vouloir mettre en place des techniques d'optimisation comme l'utilisation de cache, la mise en commun des ressources (comme les connexions à des bases de données par JDBC). Vous devrez aussi gérer le cycle de vie de votre objet distribué.

Adaptation à la charge : Les objets distribués doivent aussi s'adapter à l'augmentation de la charge. La scalabilité dans une application distribuée signifie que le nombre d'instances de votre objet distribué peut augmenter et passer sur une autre machine sans la modification du moindre code. Prenez par exemple un système que vous développez en interne comme une petite recherche de clients dans votre organisation depuis une base de données. L'application fonctionne bien quand vous l'utilisez, mais votre patron l'a vue et a dit : "Robert, c'est un excellent système, mettez ça sur notre site Web public maintenant !!!". Est-ce que mon objet distribué est capable de supporter la charge d'une demande potentiellement illimitée.

Sécurité : Mon objet distribué contrôle-t-il l'accès des clients ? Puis-je ajouter de nouveaux utilisateurs et des rôles sans tout recompiler ?

Transactions distribuées : Mon objet distribué peut-il utiliser de manière transparente des transactions distribuées ? Puis-je mettre à jour ma base de données Oracle et Sybase simultanément au sein de la même transaction et les annuler ensemble si un certain critère n'est pas respecté ?

Réutilisation : Ai-je créé mon objet distribué de telle sorte que je puisse le passer d'une application serveur d'un fournisseur à une autre ? Puis-je revendre mon objet distribué (composant) à quelqu'un d'autre ? Puis-je acheter un composant de quelqu'un d'autre et l'utiliser sans avoir à recompiler et à tailler dans son code ?

Disponibilité : Si l'une des machines de mon système tombe en panne, mes clients sont-ils capables de basculer des copies de sauvegarde de mes objets fonctionnant sur d'autres machines ?

Comme vous avez pu le voir ci-dessus, les considérations qu'un développeur doit prendre en compte lorsqu'il développe un système distribué sont complexes, et nous n'avons même pas parlé de la solution du problème qui nous essayons de résoudre à l'origine !

Donc maintenant vous avez une liste de problèmes supplémentaires que vous devez résoudre. Alors comme allez-vous vous y prendre ? Quelqu'un l'a certainement déjà fait ? Ne pourrais-je pas utiliser des modèles de conception bien connus pour m'aider à résoudre ces problèmes ? Soudain, une idée vous vient à l'esprit... « Je pourrais créer un framework qui prend en charge toutes ces contraintes et écrire mes composants en m'appuyant sur ce framework ! »... C'est là que les Entreprise JavaBeans rentrent en jeu.

Sun, avec d'autres fournisseurs d'objets distribués a compris que tôt ou tard toute équipe de développement serait en train de réinventer la roue. Ils ont donc créé la spécification des Entreprise JavaBeans (EJB). Les EJB sont une spécification d'un modèle de composant côté serveur qui prend en compte toutes les considérations mentionnées plus haut utilisant une approche standard et définie qui permet aux développeurs de créer des composants (qui sont appelés des Entreprise JavaBeans), qui sont isolés du code de la 'machinerie' bas-niveau et focalisés seulement sur la mise en place de la logique métier. Et puisque les EJBs sont définis sur un standard, ils peuvent être utilisés sans être dépendant d'un fournisseur.

JavaBeans contre EJBs

La similitude entre les deux noms amène souvent une confusion entre le modèle de composants JavaBeans et la spécification des Enterprise JavaBeans. Bien que les spécifications des JavaBeans et des Enterprise JavaBeans partagent toutes deux les même objectifs (comme la mise en avant de la réutilisation et la portabilité du code Java entre développements, comme aussi des outils de déploiement qui utilise des modèles de conception standards), les motivations derrière chaque spécification ont pour but de résoudre des problèmes différents.

Les standards définis dans le modèle de composants JavaBeans sont conçus pour créer des composants réutilisables qui sont typiquement utilisés dans des outils de développement IDE et sont communément, mais pas exclusivement, des composants visuels.

La spécification des Enterprise JavaBeans définit un modèle de composants pour développer du code Java côté serveur. Comme les EJBs peuvent potentiellement fonctionner sur différentes plate-formes serveurs (incluant des systèmes qui n'ont pas d'affichage visuel), un EJB ne peut pas utiliser de librairies graphiques tels que AWT ou Swing.

Que définit la spécification des EJBs ?

La spécification des EJBs, actuellement la version 1.1 (public release 2) définit un modèle de composant côté serveur. Elle définit six rôles qui sont utilisés pour réaliser les tâches de développement et de déploiement ainsi que la définition des composants du système.

Les rôles

La spécification des EJBs définit des rôles qui sont utilisés durant le développement, le déploiement et le fonctionnement d'un système distribué. Les fabricants, les administrateurs et les développeurs jouent des rôles variés. Ils permettent la séparation du savoir-faire technique, de celui propre au domaine. Ceci permet au fabricant de proposer un framework technique et aux développeurs de créer des composants spécifiques au domaine comme par exemple un composant de compte bancaire. Un même intervenant peut jouer un ou plusieurs rôles. Les rôles définis dans la spécification des EJBs sont résumés dans la table suivante :

Rôle Responsabilité
Fournisseur d'Enterprise Bean Le développeur qui est responsable de la création des composants EJB réutilisables. Ces composants sont regroupés dans un fichier jar spécial (fichier ejb-jar).
Assembleur d'Application Crée et assemble des applications à partir d'une collection de fichiers ejb-jar. Ceci inclut la réalisation d'applications mettant en oeuvre la collection d'EJB (comme des Servlets, JSP, Swing, etc.).
Déployeur Le rôle du déployeur est de prendre la collection de fichiers ejb-jar de l'Assembleur et/ou du Fournisseur d'EJB et de déployer ceux-ci dans un environnement d'exécution (un ou plusieurs Conteneurs d'EJBs).
Fournisseur de Conteneurs/Serveurs d'EJB Fournit un environnement d'exécution et les outils qui sont utilisés pour déployer, administrer et faire fonctionner les composants EJB.
Administrateur Système Par dessus tout, le rôle le plus important de l'ensemble du système : mettre en place et faire fonctionner. La gestion d'une application distribuée consiste à ce que les composants et les services soient tous configurés et interagissent ensemble correctement.

Composants EJB

Les composants EJB sont de la logique métier réutilisable. Les composants EJB suivent strictement les standards et les modèles de conception définis dans la spécification des EJBs. Cela permet à ces composants d'être portables et aussi à tous les autres services tels que la sécurité, la mise en cache et les transactions distribuées, d'être mis en oeuvre sur ces composants eux-mêmes. Un fournisseur d'Entreprise Bean est responsable du développement des composants EJB. Les entrailles d'un composant EJB sont traités dans Qu'est-ce qui compose un composant EJB ?

Conteneur d'EJB

Le conteneur d'EJB est un environnement d'exécution qui contient et fait fonctionner les composants EJB tout en leur fournissant un ensemble de services. Les responsabilités des conteneurs d'EJB sont définies précisément par la spécification pour permettre une neutralité vis-à-vis du fournisseur. Les conteneurs d'EJB fournissent la machinerie bas-niveau des EJBs, incluant les transactions distribuées, la sécurité, la gestion du cycle de vie des beans, la mise en cache, la gestion de la concurrence et des sessions. Le fournisseur de conteneur d'EJB est responsable de la mise à disposition d'un conteneur d'EJB.

Serveur EJB

Un serveur d'EJB est défini comme un Serveur d'Applications et comporte un ou plusieurs conteneurs d'EJBs. Le fournisseur de serveur EJB est responsable de la mise à disposition d'un serveur EJB. Vous pouvez généralement considérer que le conteneur d'EJB et le serveur EJB sont une seule et même chose.

Java Naming and Directory Interface (JNDI)

Java Naming and Directory Interface (JNDI) est utilisé dans les Entreprise JavaBeans comme le service de nommage pour les composants EJB sur le réseau et pour les autres services du conteneur comme les transactions. JNDI ressemble fort aux autres standards de nommage et de répertoires tels que CORBA CosNaming et peut être implémenté comme un adaptateur de celui-ci.

Java Transaction API / Java Transaction Service (JTA/JTS)

JTA/JTS est utilisé dans les Enterprise JavaBeans comme API transactionnelle. Un fournisseur d'Entreprise Bean peut utiliser le JTS pour créer un code transactionnel bien que le conteneur d'EJB implémente généralement les transactions dans les EJBs sur les composants EJBs eux-mêmes. Le déployeur peut définir les attributs transactionnels d'un composant EJB au moment du déploiement. Le conteneur d'EJB est responsable de la prise en charge de la transaction qu'elle soit locale ou distribuée. La spécification du JTS est la version Java de CORBA OTS (Object Transaction Service).

CORBA et RMI/IIOP

La spécification des EJBs définit l'interopérabilité avec CORBA. La spécification 1.1 précise que L'architecture des Entreprise JavaBeans sera compatible avec les protocoles CORBA. L'interopérabilité avec CORBA passe par l'adaptation des services EJB comme JTS et JNDI aux services CORBA et l'implémentation de RMI à travers le protocole CORBA IIOP.

L'utilisation de CORBA et de RMI/IIOP dans les Entreprise JavaBeans est implémentée dans le conteneur EJB et est sous la responsabilité du fournisseur du conteneur d'EJB. L'utilisation de CORBA et de RMI/IIOP dans le conteneur EJB est invisible pour le composant EJB lui-même. Cela signifie que le fournisseur d'Entreprise Bean peut écrire ses composants EJBs et les déployer dans un conteneur EJB sans s'inquiéter du protocole de communication qui est utilisé.

Qu'est-ce qui compose un composant EJB ?

Un EJB se décompose en un ensemble de pièce, dont le Bean lui-même, l'implémentation d'interfaces et un fichier d'informations. Le tout est rassemblé dans un fichier jar spécial.

Enterprise Bean

L'Enterprise Bean est une classe Java que le fournisseur d'Enterprise Bean développe. Elle implémente une interface EnterpriseBean (pour plus de détails, voir la section qui suit) et fournit l'implémentation des méthodes métier que le composant supporte. La classe n'implémente aucun mécanisme d'autorisation ou d'authentification, de concurrence ou transactionnel.

Interface Home

Chaque Enterprise Bean créé doit être associé à une interface Home. L'interface Home est utilisée comme une Factory de votre EJB. Les clients utilisent l'interface Home pour trouver une instance de votre EJB ou pour créer une nouvelle instance de votre EJB.

Interface Remote

L'interface Remote est l'interface Java qui reflète les méthodes de l'Enterprise Bean que l'on souhaite rendre disponible au monde extérieur. L'interface Remote joue un rôle similaire à celui de l'interface IDL de CORBA.

Descripteur de Déploiement

Le descripteur de Déploiement est un fichier XML qui contient les informations relatives à l'EJB. L'utilisation d'XML permet au Déployeur de facilement changer les attributs propres à l'EJB. Les attributs configurables définis dans le descripteur de déploiement incluent :

  • Les noms des interfaces Home et Remote que nécessite l'EJB ;
  • Le nom avec lequel sera publiée dans JNDI l'interface Home de l'EJB ;
  • Les attributs transactionnels pour chaque méthode de l'EJB ;
  • Les listes de contrôle d'accès (Access Control Lists) pour l'authentification.

Fichier EJB-Jar

Le fichier EJB-Jar est un fichier jar Java normal qui contient un EJB, les interface Home et Remote ainsi que le descripteur de déploiement.

Comment travaille un EJB ?

Maintenant que l'on a un fichier EJB-Jar contenant un Bean, les interfaces Home et Remote, et un descripteur de déploiement, voyons un peu comment toutes ces pièces vont ensemble, pourquoi les interfaces Home et Remote sont nécessaires et comment le conteneur d'EJB les utilise.

Le conteneur d'EJB implémente les interfaces Home et Remote qui sont dans le fichier EJB-Jar. Comme mentionné précédemment, l'interface Home met à disposition les méthodes pour créer et trouver votre EJB. Cela signifie que le conteneur d'EJB est responsable de la gestion du cycle de vie de votre EJB. Ce niveau d'abstraction permet aux optimisations d'intervenir. Par exemple, cinq clients peuvent demander simultanément la création d'un EJB à travers l'interface Home, le conteneur d'EJB pourrait n'en créer qu'un seule et partager cet EJB entre les cinq clients. Ceci est réalisé à travers l'interface Remote, qui est aussi implémentée par le conteneur d'EJB. L'objet implémentant Remote joue le rôle d'objet proxy vers l'EJB.

Tous les appels de l'EJB sont redirigés à travers le conteneur d'EJB grâce aux interfaces Home et Remote. Cette abstraction explique aussi pourquoi le conteneur d'EJB peut contrôler la sécurité et le comportement transactionnel.

Types d'EJBs

Il doit y avoir une question dans votre tête depuis le dernier paragraphe : partager le même EJB entre les clients peut certainement augmenter les performances, mais qu'en est-il lorsque je souhaite conserver l'état sur le serveur ?

La spécification des Enterprise JavaBeans définissent différents types d'EJBs qui peuvent avoir différentes caractéristiques et adopter un comportement différent. Deux catégories d'EJBs ont été définies dans cette spécification : les Session Beans et les Entity Beans, et chacune de ces catégories a des variantes.

Session Beans

Les Session Beans sont utilisés pour représenter les cas d'utilisations ou des traitements spécifiques du client. Ils représentent les opérations sur les données persistantes, mais non les données persistantes elles-mêmes. Il y a deux types de Session Beans : non-persistant (Stateless) and persistant (Stateful). Tous les Session Beans doivent implémenter l'interface javax.ejb.SessionBean. Le conteneur d'EJB contrôle la vie d'un Session Bean.

Les Session Beans non-persistants

Les Session Beans non-persistants sont le type d'EJB le plus simple à implémenter. Ils ne conservent aucun état de leur conversation avec les clients entre les invocations de méthodes donc ils sont facilement réutilisables dans la partie serveur et puisqu'ils peuvent être mis en cache, ils supportent bien les variations de la demande. Lors de l'utilisation de Session Beans non-persistants, tous les états doivent être stockés à l'extérieur de l'EJB.

Les Session Beans persistants

Les Session Beans persistants conservent un état entre l'invocation de leurs méthodes (comme vous l'aviez probablement compris). Ils ont une association 1-1 avec un client et sont capables de conserver leurs états eux-mêmes. Le conteneur d'EJBs a en charge le partage et la mise en cache des Session Beans persistants, ceux-ci passe par la Passivation et l'Activation.

Entity Beans

Les Entity Beans sont des composants qui représentent une donnée persistante et le comportement de cette donnée. Les Entity Beans peuvent être partagés par plusieurs clients, comme une donnée d'une base. Le conteneur d'EJBs a en charge de mettre en cache les Entity Beans et de maintenir leur intégrité. La vie d'un Entity Bean est supérieur à celle du conteneur d'EJBs, donc si un conteneur tombe en panne, l'Entity Bean est censé être encore disponible lors que le conteneur le devient à nouveau.

Il y a deux types d'Entity Beans, ceux dont la persistence est assurée par le Bean lui-même et ceux dont la persistance est assurée par le conteneur.

Ce livre a été écrit par Bruce Eckel ( télécharger la version anglaise : Thinking in java )
Ce chapitre a été traduit par Jean-Pierre Vidal, Alban Peignier ( groupe de traduction )
télécharger la version francaise (PDF) | Commandez le livre en version anglaise (amazon) | télécharger la version anglaise
pages : 1 2 3 4 5 6 7 8 9 10 11 12 
Penser en Java 2nde édition - Sommaire |  Préface |  Avant-propos | Chapitre : 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15 |  Annexe : A B C D  | Tables des matières - Thinking in Java