web-dev-qa-db-fra.com

Puis-je créer un chemin de classe personnalisé par application dans Tomcat

Pour certaines applications, j'utilise ZK, d'autres Hibernate, d'autres Apache Commons, etc.

Je ne veux pas déployer un fichier war de 75 Mo, simplement parce qu'il utilise beaucoup de bibliothèques.

Je ne veux pas ajouter les bibliothèques à mon dossier lib Tomcat, ni le chemin de classe à sa configuration car je peux avoir une ancienne application utilisant la bibliothèque x.1 et une autre application utilisant la bibliothèque x.2

Pour cette raison, ce serait bien d'avoir quelque chose dans le web.xml ou le context.xml où je dis quelque chose comme:

<classpath>/usr/local/Tomcat/custom-libs/zk-5.0.4</classpath>

Remarque: Ce qui précède est un pseudo-code

32
Spider

Depuis Tomcat 7, il n'est pas fait mention de l'impossibilité d'utiliser VirtualWebappLoader en production. Je l'ai essayé et ça marche comme un rêve. Ajoutez simplement ce qui suit à META-INF/context.xml:

<?xml version="1.0" encoding="UTF-8"?>

<Context antiJARLocking="true" path="/websandbox">
    <Loader className="org.Apache.catalina.loader.VirtualWebappLoader"
          virtualClasspath="/usr/.../*.jar;/usr/.../*.jar"/>
</Context>

Dans Netbeans, sous l'empaquetage, je décoche juste tous les paquets, réduisant la taille .war à rien, m'assure que les dépendances sont dans les bons dossiers sur le serveur et télécharge. Ouais! Plus de fichier WAR de 100 Mo.

36
Spider

Ajout d'une réponse @Spider.

Tomcat Context hold Loader élément. Selon docs descripteur de déploiement (quoi dans <Context> tag) peut être placé dans:

  • $CATALINA_BASE/conf/server.xml - mauvais - nécessite un redémarrage du serveur pour relire la configuration
  • $CATALINA_BASE/conf/context.xml - mauvais - partagé entre toutes les applications
  • $CATALINA_BASE/work/$APP.war:/META-INF/context.xml - mauvais - nécessite un reconditionnement pour changer la configuration
  • $CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml - Nice, mais voir la dernière option !!
  • $CATALINA_BASE/webapps/$APP/META-INF/context.xml - Nice, mais voir la dernière option !!
  • $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml - meilleur - complètement hors application et automatiquement scanné pour les changements !!!

Voici ma configuration qui montre comment utiliser la version de développement des fichiers de projet à partir de $CATALINA_BASE hiérarchie (notez que je place ce fichier dans src/test/resources dir et inciter Maven à prétraiter ${basedir} espaces réservés via pom.xml<filtering>true</filtering> donc après la construction dans un nouvel environnement, je le copie dans $CATALINA_BASE/conf/Catalina/localhost/$APP.xml):

<Context docBase="${basedir}/src/main/webapp"
         reloadable="true">
    <!-- http://Tomcat.Apache.org/Tomcat-7.0-doc/config/context.html -->
    <Resources className="org.Apache.naming.resources.VirtualDirContext"
               extraResourcePaths="/WEB-INF/classes=${basedir}/target/classes,/WEB-INF/lib=${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
    <Loader className="org.Apache.catalina.loader.VirtualWebappLoader"
            virtualClasspath="${basedir}/target/classes;${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
    <JarScanner scanAllDirectories="true"/>

    <!-- Use development version of JS/CSS files. -->
    <Parameter name="min" value="dev"/>
    <Environment name="app.devel.ldap" value="USER" type="Java.lang.String" override="true"/>
    <Environment name="app.devel.permitAll" value="true" type="Java.lang.String" override="true"/>
</Context>

[~ # ~] mise à jour [~ # ~] Tomcat 8 change la syntaxe pour<Resources> et <Loader> éléments, la partie correspondante ressemble maintenant à:

<Resources>
    <PostResources className="org.Apache.catalina.webresources.DirResourceSet"
                   webAppMount="/WEB-INF/classes" base="${basedir}/target/classes" />
    <PostResources className="org.Apache.catalina.webresources.DirResourceSet"
                   webAppMount="/WEB-INF/lib" base="${basedir}/target/${project.build.finalName}/WEB-INF/lib" />
</Resources>
20
gavenkoa

Une autre alternative un peu hacky.

Vous pouvez écrire un chargeur de classe personnalisé de 5-6 lignes qui dérive de rlclassloader , et ajoute simplement vos pots de chemin de classe en utilisant la méthode addUrl () .

Ensuite, définissez-le comme chargeur de classe de contexte du thread dans votre code d'application.

Thread.setContextClassLoader(new CustomClassloader(path, parentClassLoader)

où le chargeur de classe parent est généralement

Thread.getContextClassloader()
7
Fakrudeen

C'est à cela que le fichier META-INF/context.xml peut être utilisé. Vous avez défini votre propre WebappLoader, qui charge les classes pour votre webapp particulière. Voici la référence que j'ai utilisée: http://Tomcat.Apache.org/Tomcat-5.5-doc/config/loader.html (Edit: pour Tomcat 6: http: // Tomcat.Apache.org/Tomcat-6.0-doc/config/loader.html , pour Tomcat 7: http://Tomcat.Apache.org/Tomcat-7.0-doc/config/loader.html )

Cet homme semble également publier une solution à votre problème exact (exemple inclus): http://Java.dzone.com/articles/extending-Tomcat-webapploader

7
Nick