Webstore
Dans ce projet, nous avons réalisé un magasin sur Internet en utilisant un Application Server fournit par Sun : Java 2 Enterprise Edition. Nous avons choisi cette forme de serveur car elle utilise une technologie récente de Java : les Enterprise Java Beans. Cela nous a permis donc non seulement d’améliorer notre connaissance des technologies Internet (Jsp, Servlet, JavaMail, Problèmes de sécurité,Configurations d’un serveur web), mais aussi de découvrir des technologies fondées sur la programmation distribuée très populaires au sein des entreprises (EJB, JNDI …).

Entreprise JavaBeans

Les Enterprise JavaBeans (EJB) font partie d'un projet plus vaste : Java 2, Enterprise Edition (J2EE). Il s'agit d'une architecture pour développer, déployer et exécuter des applications dans un environnement distribué. La plate-forme J2EE fournit des services tels que gestion de transaction, sécurité, connexion avec les clients, accès à une base de données, ce qui permet au programmeur de se focaliser sur la logique de l’application elle-même et non sur ce qui est de plus bas niveau. Cette application est codée dans les enterprise beans, des composants réutilisables qui peuvent être accédés par les programmes clients. Les enterprise beans fonctionnent sur un serveur J2EE, qui sert de serveur middle-tier dans une application client/serveur 3-tier.

1. Architecture J2EE

Le diagramme suivant montre l’organisation de des principaux éléments de l’architecture J2EE :

2. Serveur J2EE

La pièce centrale de l’architecture fournit les services suivants :

  • Naming and Directory – permet aux programmes de localiser les services et composants grâce à l’API Java Naming and Directory Interface (JNDI).
  • Authentification – renforce la sécurité en demandant à l’utilisateur de s’enregistrer.
  • HTTP – permet aux navigateurs Web d’accéder aux servlets et aux Java Server Pages (JSP).
  • EJB – permet aux clients d’invoquer des méthodes sur les enterprise beans.
  • 3. EJB Container

    Les instances d’enterprise beans sont intégrées dans un EJB Container qui les contrôlent, et leurs fournit des services importants :

  • Gestion des transactions – Lorsqu’un client invoque une méthode dans un enterprise bean, le container intervient pour gérer cette transaction. Le programmeur n’a donc pas besoin de fournir de code pour contrôler les transactions distribuées.
  • Sécurité – Le container ne permet qu’aux clients autorisés d’invoquer des méthodes sur des enterprise beans.
  • Connexion aux clients distants – Le container s’occupent des communications entre clients et enterprise beans de manière à ce qu’un client invoque des méthodes comme si l’enterprise bean était dans la même machine virtuelle.
  • Gestion du cycle de vie – Le container s’occupe de la création d’un bean, de la destruction d’un bean, et de tout ce qui se situe entre (changement d’état …).
  • Gestion des connexions aux bases de données – Les connexions pouvant être coûteuses, le container se constitue un pool de connexion pour qu’un enterprise bean puissent en récupéré une rapidement.
  • 4. Web Container

    Les clients peuvent être de plusieurs sortes :

  • Page HTML – Les clients peuvent accéder aux enterprise beans par l’intermédiaire des Java Server Pages (JSP), qui combinent Java et HTML.
  • Applet – Dans ce cas, on peut utiliser une communication sur le protocole HTTP entre l’applet et des servlets par le moyen de documents XML. Pour éviter des incompatibilités, J2EE propose un support pour le chargement automatique de Plug-in dans le navigateur (Java Runtime Environment …).
  • Intranet – On peut utiliser les services précités aussi bien sur Internet que sur un intranet.
  • Autres clients – Le but de J2EE, même s’il est très orientés sur Internet, est de faciliter la communication avec n’importe quel client (Visual Basic, Office 2000 …). C’est pourquoi elle utilise le standard CORBA pour les communications, plus précisément elle utilise RMI/IIOP. Les services J2EE sont donc accessible par n’importe quels clients CORBA.
  • 5. Enterprise Beans

    Les enterprise beans sont des composants serveur écrit en Java. Cependant, ils sont relativement différents des composants JavaBean. Les composants JavaBean définissent une convention pour permettre la personnalisation des instances de classes Java par l’intermédiaire d’outils graphiques. Les enterprise beans implémentent des services de transactions multi-utilisateurs. Chaque Bean comporte au moins trois classes :

  • Une interface Remote définissant ces méthodes distribuées.
  • Une interface Home définissant les procédures de création, destruction et recherche d’instance du Bean. Il s’agît de l’interface du Container qui correspond à un objet " factory ".
  • L’implémentation du Bean.
  • Ils peuvent être de deux types :
  • Session Bean – Il représente un client dans le serveur J2EE. Un client communique avec le serveur J2EE en invoquant des méthodes sur ce bean. Chaque session bean ne peut être associé qu’avec un client. Quand le client termine, son session bean termine aussi, il est donc non-persistant. Il existe deux formes de Session Bean: les Session Bean stateless, qui ne comportent pas d’états et qui peuvent donc être partagés par plusieurs clients, et les Session Bean, qui comportent des états (variable d’instance) et qui sont donc propre à un client.
  • Entity Bean – Il représente une donnée persistante (dans une base de données par exemple). Sa persistance peut être gérée par lui-même (qui devra définir la commande SQL pour y accéder) ou par le EJB Container (qui sauvegarde l’état du bean automatiquementdans une base de données relationnelle par l’utilisation de JDBC).
  • Bien sûr, dans le but d’éviter des conflits avec l’EJB Container, un enterprise bean ont certaines restrictions : ne pas utiliser de threads, utiliser une bibliothèque native …

    6. L’outil de déploiement

    Une fois les enterprise beans et autres fichiers de bases (JSP, servlets …) créés, tout le reste de l’application est géré par un unique utilitaire graphique : deploytool. Cet outil permet de générer les différents deployment descriptor (fichiers codés en XML qui permettent la sélection et configuration des services fournis) au moyen de différents formulaires et de déployer le serveur (ainsi que de permettre son administration).

    7. Etat d’Avancement

    Dans la version disponible actuellement, J2EE présente plusieurs différence par rapport au modèle décrit dans la documentation. Dans le cadre de ce projet, nous avons opté pour le modèle de persistance des Entity Beans géré par le container. Cette fonctionnalité permet théoriquement de faire abstraction de notions propres à une base de donnée particulière, il suffit à l’utilisateur de spécifier les attributs de l’objet à sauvegarder (ainsi que celui qui tient lieux de clé primaire) et le container génère les requêtes SQL correspondantes. Cependant, de nombreux problèmes (sans doute propre à l’outil deploytool) limitent l’utilisation de ce modèle de persistance.

    Dans la documentation, il est possible d’utiliser une clé multiple comme clé primaire en définissant une classe comportant les champs composants cette clé et redéfinissant les fonctions hashcode() et equals(), cette manipulation entraîne une erreur lors du déploiement, nous avons donc été contraint d’utiliser une clé primaire simple " bidon " dans ce cas précis. Deuxièmement, lorsque l’on référence un Entity Bean dans un autre Entity Bean, l’outil actuel ne détecte pas la nature de l’objet et essaie de le sérialiser plutôt que de référencer la clé primaire de ces Entity Beans, cela entraînera forcément un problème dans la maintenance de l’intégrité du système. Une solution à ce problème est de référencer directement les clés primaires des Entity Beans et de gérer les problèmes d’intégrité " à la main " (on peut utiliser pour cela la fonction ejbRemove(…) appeler avant la destruction d’un objet). Enfin, un autre problème qui n’est pas, contrairement aux deux exemples précédent, un bug de deploytool, mais une limitation du modèle et l’incapacité de modifier le comportement des requêtes de recherche d’instances d’Entity Bean autrement que par la modification de la requête SQL elle-même.

    Nous avons donc pu nous apercevoir que dans l’état actuel des choses, l’utilisation du modèle de persistance géré par le bean (c’est à dire par la formulation de requête SQL à l’intérieur du code de l’objet) est plus raisonnable, et finalement plus rapide.

    Un autre des bugs de la version actuelle de deploytool est sa mauvaise gestion de l’héritage, ainsi si on essaie de donner deux interfaces Remote pour un même objet, l’une héritant de l’autre, l’outil refuse de considérer l’interface fille comme une interface Remote valide. Une solution est de fournir une seule interface comportant toutes les signatures de méthodes et de spécifier des permissions différentes suivant le rôle de l’utilisateur (le rôle est un identifiant de groupe d’utilisateur définit au niveau du container).

    8. Architecture du webstore

    Le webstore comporte plusieurs utilisateurs :

  • Les clients ou customers accèdent au services par le biais de Jsp et sont représentés sur le serveur par des Session Beans : Catalog par le biais duquel ils peuvent naviguer dans les produits présents et Cart où ils stockent les produits qui les intéressent, celui-ci permet de construire une commande (Order) qui enverra un accusé de réception par le Session Bean Stateless Mailer (qui utilise l’API JavaMail incluse dans J2EE).
  • L’utilisateur en charge de la gestion du stock ou shipper connaît la quantité disponible de chaque produit et peut les réapprovisionner, il peut affecter au produit une quantité critique de manière à y accéder plus facilement lorsqu’un réapprovisionnement est urgent.
  • L’administrateur qui possède les droits pour créer de nouveaux produits et en retirer d’autres.
  • Les deux dernières formes d’utilisateur étant internes à la société, on peut envisager de les faire communiquer avec le serveur autrement que par un navigateur Internet, par exemple par une application cliente écrite en Java (où dans un autre langage puisque l’on peut communiquer avec le serveur par CORBA).

    Le mode de persistance géré par le container limite chaque classe d’Entity Bean à une représentation d’une table de la base de donnée (chaque instance représentant une ligne). Dans un soucis de performance, nous avons séparé les commandes en deux Entity Beans, le premier, Order, spécifie la commande elle-même et ces attributs généraux (adresse de livraison …), le deuxième OrderLine correspond à une ligne de la commande (produit + quantité) : on peut donc consulter certaines lignes de la commande sans avoir à charger toute la commande. Bien entendu, cela est transparent pour l’utilisateur de l’EJB Order.

    9. La base de donnée

    Pour l'instant, seul les drivers JDBC de oracle8, ODBC et cloudscape (une base de donnée écrite totlement en Java) sont reconnus. Nous avons utiliser cloudscape pour plusieurs raisons:

  • Il est fourni avec J2EE. Nous n'avons donc pas eu à installer une base assez lourde comme oracle8.
  • Les drivers sont déjà configuré.
  • Il utilise une syntaxe de SQL améliorée pour Java: "SQL-J".
  • 9. Sécurité

    J2EE fournit deux systèmes de sécurité : un système d’authentification et un système d’autorisation.

    Le mécanisme d’authentification permet deux formes d’identification :

  • Une forme basique associant des utilisateurs à un ou plusieurs groupes en utilisant un password. Cette identification utilise l’API JavaSecurity, on ajoute des utilisateurs par le biais d’un outil realmtool.
  • Une forme utilisant la technologie des certificats X509, qui permet d’ajouter un certificat à son browser web pour permettre son identification.
  • Dans ce projet, faute de temps, nous nous sommes orientés sur la première forme d’authentification. Une page web ne demandera un mot de passe que si elle est une ressource protégée, une application client le demandera au démarrage. Au niveau des pages web l’authentification peut être demandée par le biais d’une page spécifique, d’une pop-up window standard ou par reconnaissance du certificat X509 attaché au browser web.

    Le mécanisme d’autorisation est étroitement lié au mécanisme d’authentification. En effet, on peut préciser des rôles pour définir les droits d’accès sur les méthodes des EJB, où sur des pages web particulières. On mappera ensuite des identifiants de groupe ou d’utilisateurs à ces rôles. On peut gérer la sécurité directement dans le code par le biais de méthode spéciales.

    Dans notre projet, nous protégeons évidemment les accès aux méthodes des Entity Beans (ceux quisont persistants). Nous protégeons aussi les jsp shipper (qui correspond à la gestion du stock, et qui est réservé à la personne qui en a la charge) et adder (qui est le seul jsp d’administration pour l’instant, il est réservé à l’administrateur et permet d’ajouter un produit). Nous protégeons enfin le jsp order car nous souhaitons que seul un utilisateur enregistré puisse commander.

    10. Ce qu’il reste à faire

    Nous n’avons pas pu finir la création d’un nouvel utilisateur pour deux raisons : premièrement par manque de temps, deuxièmement à cause d’une limitation de la version actuelle de J2EE (encore une …). En effet, créer l’Entity Bean Customer pour représenter un utilisateur ne pose pas de problèmes majeurs, mais il faut enregistrer l’utilisateur créé au moyen de l’utilitaire realmtool, ce qui est faisable mais rend le code non portable.

    Il faudrait aussi rendre le magasin plus présentable. Durant ce projet, nous nous sommes attachés sur le fond (fonctionnalités et sécurité) et pas trop à la forme (jolies images…).

    L’envoi de mail à la suite d’une commande ne s’effectue pas correctement car le programme essaie de l’envoyer à partir de localhost. Lorsque la machine courante n’est pas serveur SMTP, cela ne marche pas. Il faudrait trouver un moyen de spécifier un serveur SMTP au programme, ce que nous n’avons pas trouver dans la doc de JavaMail. Cela dit cela n’est pas un problème majeur, l’envoi de mails n’étant pas une fonctionnalité primordiale du système.

    11. Utilisation

    Pour utiliser notre webstore, il faut tout d’abord installer J2EE et la jdk1.2.2 (tous deux disponibles chez Sun).

    Si vous utilisez Win9x et non WinNT, les fichiers batch ne marcheront pas. Voici des batch modifiés pour fonctionner sur les deux environnements : custom.zip.

    Il faut spécifier deux variable d’environnements :

  • J2EE_HOME : le chemin où vous avez installé j2ee.
  • JAVA_HOME : le chemin où vous avez installé jdk1.2.2.
  • Il faut ensuite lancer le serveur de base de donnée (cloudscape.start.bat) et le serveur en mode bavard (j2ee.verbose.bat) ou non (j2ee.bat). Enfin, vous devez lancer l’outil de déploiement (deploytool.bat).

    Créez les utilisateurs de base avec les commandes :

    realmtool –addGroup admin

    realmtool –addGroup customer

    realmtool –add root mot_de_passe admin

    realmtool –add stock mot_de_passe admin

    Choisissez open application, dans le navigateur, sélectionnez webstore.ear. Cliquez sur deploy application. Cliquez sur Next jusqu’à ce que le bouton Finish se libère. Appuyez dessus. Le reste devrait aller tout seul.

    Pour remplir la base de donnée avec quelques valeurs (histoire de browser quelquechose), voici quelques batchs bien sympathiques : fillers.zip

    Sur un browser, allez à l’url http://localhost :8000/webstore/ (remplacer localhost par le nom de votre machine si vous consultez à distance) et voilà, vous êtes sur le webstore.

    Si vous voulez vous en servir, il faudra créer un utilisateur avec sign up now. (Puisque cela ne crée que l’objet persistant Customer, vous devez ajouter aussi l’utilisateur avec la commande : realmtool –add nom_utilisateur mot_de_passe customer).

    Pour accéder au pages adder.jsp et shipper.jsp, vous devez les taper explicitement dans l’url (http://localhost :8000/webstore/adder.jsp et http://localhost :8000/webstore/shipper.jsp).

    Pour finir voici les sources : webstore_src.zip.

    12. Conclusion
    En conclusion, on peut dire que la technologie de J2EE est encore un peu jeune. Pour une utilisation commerciale, on pourrait tout de même utiliser les EJB mais avec un autre application server tel websphere d'IBM. Il peut toutefois être utilisé en n'utilisant pas certaines fonctionnalités encore assez "bancale" (comme le modèle de persistance gérée par le container).

    13. Quelques Screenshots

    L'outil de déploiement
    Le déploiement du serveur

    Navigation dans le magasin
    Un caddie bien rempli
    Accès à une page protégée

    Outil d'administration: ajouter un produit
    On passe une commande
    L'outil de gestion du stock


    Projet Internet 2000 DESS ISI - Christophe Truc, Gabriel Odorici.