Могу ли я создать собственный путь к классам для каждого приложения в 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>
Примечание: вышеприведенный псевдокод
4 ответа
В 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-файла.
Дополнение @Spider answer.
Контекст Tomcat содержит элемент Loader. Согласно дескриптору развертывания документов (что в <Context>
тег) может быть размещен в:
$CATALINA_BASE/conf/server.xml
- bad - требуется перезапуск сервера для перечитывания конфигурации$CATALINA_BASE/conf/context.xml
- плохо - используется всеми приложениями$CATALINA_BASE/work/$APP.war:/META-INF/context.xml
- плохо - требуется переупаковка для изменения конфигурации$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 и Intruct 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>
ОБНОВЛЕНИЕ 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>
Еще одна хакерская альтернатива.
Вы можете написать пользовательский загрузчик классов из 5-6 строк, который происходит от urlclassloader и просто добавляет ваши файлы пути к классам, используя метод addUrl().
Затем установите его как загрузчик класса контекста потока в коде вашего приложения.
Thread.setContextClassLoader(new CustomClassloader(path, parentClassLoader)
где обычно загружается родительский класс
Thread.getContextClassloader()
Для этого можно использовать файл META-INF/context.xml. Вы определили свой собственный WebappLoader, который загружает классы для вашего конкретного веб-приложения. Это ссылка, которую я использовал: 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