Java & le web
x Le web dynamique
x Java & le web

Intro à Tomcat
x Serveur d'applications
x Présentation Tomcat
x Installation
x Arborescence

Configuration
x Introduction
x Server
x Service
x Engine
x Host
x Context
x DefaultContext
x Logger
x Loader
x Realm
x Valve

Connecteurs
x Balise Connector
x Coyote HTTP/1.1

Sécurisation accès
x La balise Realm
x Memory Based
x JDBC Database
x Protéger ressources
x Cryptage password

Les Valve
x La balise Valve
x Access Log
x Single Sign-On

Fonctionnalités
x Déploiement auto.
x Class loaders

Eclipse & Tomcat
x Plug-in pour Eclipse
x Projet Tomcat
x Debugger des JSP

Créer une appli web
x Présentation
x Architecture
x Fichier web.xml
x Déploiement

Tomcat 5
x Nouveautés

Tomcat's Corner
x Crédits
x Liens
 
             
Les class loaders de Tomcat

 

Principe des class loaders

Les spécifications officielles des Servlets, que Tomcat suit, demandent que le moteur de servlet (également appelé conteneur de servlet) et les applications web exécutées sur le serveur aient accès à différentes ressources Java, dont certaines sont privées, et d'autres communes.

C'est pourquoi Tomcat utilise plusieurs class loaders (littéralement, chargeurs de classe) pendant son exécution. Un class loader est, dans l'absolu, un objet Java destiné à charger les ressources Java (classes ou archives JAR contenant des ... classes). Cette notion n'est pas introduite par Tomcat. Il s'agit d'un élément essentiel de l'architecture Java. Un class loader hérite de la classe java.lang.ClassLoader.

 

Modèle de délégation

Dans Java 2, les class loaders suivent le modèle de délégation. Cela signifie que, lorsque l'on demande à un class loader de charger une classe, il demande d'abord à son parent de le faire. Si celui-ci n'en est pas capable (il ne peut pas atteindre la ressource par exemple), le class loader interrogé cherche alors parmi ses propres ressources. Les class loaders de Tomcat suivent également un modèle arborescent, et utilisent ce modèle de délégation. A l'exception notable du class loader nommé webapp (voir plus bas), permettant l'accès aux ressources d'une application web. Si on lui demande une ressource, il effectue d'abord la recherche dans ses ressources accessibles, avant de déléguer à son parent en cas d'échec. Ce comportement peut être modifié dans la configuration, en définissant un Loader personnel pour une application web, en jouant sur l'attribut delegate.

Lorsqu'une instance de Tomcat démarre, un certain nombre de class loaders sont créés, organisés selon l'arborescence suivante :

 

Nous allons à présent détailler ces différents class loaders et les ressources auxquelles ils peuvent accéder.

 

Class Loader Bootstrap

Il accède aux classes de base de la JVM (Java Virtual Machine) et à ses extensions (répertoire JAVA_HOME/jre/lib/ext). Donc, si dans une application web, vous instanciez un objet de la classe java.lang.String (une chaîne de caractères, objet de base de Java), c'est ce class loader qui chargera cette classe.

 

Class Loader System

Il accède à l'archive TOMCAT_HOME/bin/bootstrap.jar, qui contient notamment la méthode d'initialisation du serveur. Il accède également à l'archive JAVA_HOME/lib/tools.jar, qui contient notamment le compilateur javac. Celui-ci est utilisé par Tomcat pour compiler les JSP.

Notons que, normalement, le class loader System devrait accéder aux ressources situées dans le CLASSPATH. Mais le script de démarrage de Tomcat modifie ce comportement pour celui décrit juste au-dessus.

 

Class Loader Common

Celui-ci est le dernier à fournir des ressources communes au serveur et aux applications qu'il héberge. C'est surtout le seul avec lequel on puisse, en tant qu'utilisateur, partager des ressources à ce niveau. Il accède aux répertoires TOMCAT_HOME/common/classes (pour les classes à partager) et TOMCAT_HOME/common/lib (pour les librairies à partager). Ce qui signifie que les ressources que vous mettrez dans ces répertoires seront accessibles par toutes les applications web du serveur et par le serveur lui-même !

Différentes ressources sont par défaut dans ces répertoires. C'est le cas de xerces.jar, le parseur XML réputé, utilisé notamment pour la lecture des fichiers de configuration Tomcat. Ou encore servlet.jar, librairie indispensable pour que le serveur puisse exécuter des servlets. Mais également les ressources dédiées au nommage : jndi.jar, naming-common.jar et naming-resources.jar.

 

Class Loader Catalina

Le schéma indique ici une division dans l'arborescence des class loaders. Si, jusque là, les ressources des différents chargeurs (System, Bootstrap et Common) étaient accessibles par le serveur et par les applications web tournant dessus, il en va maintenant autrement. Les ressources du class loader Catalina ne sont accessibles qu'aux classes internes du serveur. Les applications web n'y auront en aucun cas accès.

Les ressources sont situées dans les répertoires TOMCAT_HOME/server/classes (pour les classes) et TOMCAT_HOME/server/lib (pour les librairies). On trouve notamment l'archive catalina.jar contenant ni plus ni moins que le moteur de servlet de Tomcat (nommé Catalina). C'est également ici que l'on trouvera les connecteurs de Tomcat. Bref, toute la mécanique interne du serveur.

 

Class Loader Shared

On se trouve ici sur l'autre branche de l'arborescence présentée plus haut. Les ressources de ce class loader sont accessibles à toutes les applications web exécutées par ce serveur. C'est donc l'endroit idéal pour partager des ressources entre toutes les applications.

Le répertoire TOMCAT_HOME/shared/classes est destiné à contenir les classes, et TOMCAT_HOME/shared/lib à contenir les librairies. On trouve notamment les librairies Jasper, utilisées pour la compilation des JSP.

 

Class Loader Webapp

Il ne s'agit pas ici d'un seul class loader, mais d'un par application web hébergée par ce serveur. Chacune peut donc posséder ses ressources, qui ne seront pas visibles par les autres applications, ni même par le serveur. C'est donc ici que l'on stockera les classes de l'application en elle-même (les classes qui font son fonctionnement), et les librairies utiles uniquement à elle.

Les classes seront stockées dans le répertoire WEB_INF/classes de l'application, et les librairies dans WEB_INF/lib.

 

Chargement d'une ressource pour une application web

A partir de ce que nous avons dit concernant le modèle de délégation suivi ou non par les class loaders de Tomcat (voir plus haut), nous pouvons déterminer quels class loaders seront mis en jeu, et dans quel ordre, pour charger une ressource demandée. Prenons l'exemple d'une ressource demandée par une application web :

  • Elle sera tout d'abord cherchée dans le class loader webapp, soit les répertoires WEB-INF/classes puis WEB-INF/lib de l'application.
  • En cas d'échec, le modèle de délégation reprend le dessus. La requête est déléguée au parent, récursivement. Ce qui aboutit à l'interrogation du premier class loader, bootsrap, qui interroge donc les classes de base de la JVM.
  • En cas d'échec, la délégation renvoie la requête au requéreur. Le class loader System doit alors effectuer la recherche dans ses ressources.
  • En cas d'échec, c'est au class loader common que revient la requête. Il cherche dans les répertoires TOMCAT_HOME/common/classes, TOMCAT_HOME/common/endorsed, puis TOMCAT_HOME/common/lib.
  • En cas d'échec, retour à l'envoyeur, le class loader shared (qui, on l'a compris, est celui qui a émis la délégation après l'appel par le class loader webapp). Il cherche dans les répertoires TOMCAT_HOME/shared/classes puis TOMCAT_HOME/shared/lib.

Un exemple concret, pour finir. Lorsque la classe javax.servlet.http.HttpServlet (classe indispensable à une application web) sera nécessitée par une application web (à la première servlet instanciée, donc), le class loader common répondra avec succès à la demande de chargement. C'est en effet lui, on l'a dit, qui peut accéder à la librairie servlet.jar. Le class loader shared ne sera donc pas sollicité ici...