Могу ли я создать собственный путь к классам для каждого приложения в Tomcat

Для некоторых приложений я использую ZK, другие Hibernate, другие Apache Commons и т.д.

Я не хочу разворачивать военный файл 75 МБ, просто потому, что он использует множество библиотек.

Я не хочу добавлять библиотеки в мою папку tomcat lib или в путь к нему, поскольку у меня может быть старое приложение, использующее библиотеку x.1 и другое приложение, использующее библиотеку x.2

По этой причине было бы здорово иметь что-то в файле web.xml или context.xml, где я говорю что-то вроде:

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

Примечание: Вышеприведенный псевдокод

Ответы

Ответ 1

Из Tomcat 7 нет упоминания о невозможности использования VirtualWebappLoader в производстве. Я попробовал, и это работает как сон. Просто добавьте следующее в 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>

В Netbeans, под упаковкой, я просто отключаю все пакеты, беря размер .war до нуля, убедитесь, что зависимости находятся в правильных папках на сервере и загружаются. Yey! Не более 100 МБ файла WAR.

Ответ 2

Дополните ответ @Spider.

Tomcat Context удерживать элемент Loader. В соответствии с docs дескриптор развертывания (что в теге <Context>) можно поместить в:

  • $CATALINA_BASE/conf/server.xml - bad - требуется перезагрузка сервера для перезаписи config
  • $CATALINA_BASE/conf/context.xml - плохой общий доступ во всех приложениях
  • $CATALINA_BASE/work/$APP.war:/META-INF/context.xml - bad - требуется переупаковка, чтобы изменить конфигурацию
  • $CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml - хорошо, но см. последний вариант!
  • $CATALINA_BASE/webapps/$APP/META-INF/context.xml - хорошо, но см. последний вариант!
  • $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml - лучший - полностью из приложения и автоматически проверяется на изменения!!!

Здесь моя конфигурация, которая демонстрирует, как использовать версию проекта файлов проекта из $CATALINA_BASE иерархии (обратите внимание, что я помещаю этот файл в каталог src/test/resources dir и наследую Maven для препроцессора ${basedir} заполнителей через pom.xml <filtering>true</filtering> поэтому после сборки в новой среде я скопирую его в $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>

UPDATE Синтаксис изменения Tomcat 8 для элементов <Resources> и <Loader>, теперь соответствующая часть выглядит следующим образом:

<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>

Ответ 3

Это файл META-INF/context.xml. Вы определили свой собственный WebappLoader, который загружает классы для вашего конкретного webapp. Это ссылка, которую я использовал: http://tomcat.apache.org/tomcat-5.5-doc/config/loader.html (Изменить: для Tomcat 6: http://tomcat.apache.org/tomcat-6.0-doc/config/loader.html, для Tomcat 7: http://tomcat.apache.org/tomcat-7.0-doc/config/loader.html)

Также этот человек, кажется, отправляет решение вашей конкретной проблемы (пример включен): http://java.dzone.com/articles/extending-tomcat-webapploader

Ответ 4

Еще одна небольшая хакерская альтернатива.

Вы можете написать 5-6-строчный пользовательский загрузчик классов, который происходит от urlclassloader и просто добавляет ваши кластеры пути к классам с помощью метод addUrl().

Затем установите его как загрузчик контекстного класса потока в коде приложения.

Thread.setContextClassLoader(new CustomClassloader(path, parentClassLoader)

где загрузчик родительского класса обычно

Thread.getContextClassloader()