我可以在Tomcat中基于每个应用程序创建自定义类路径

Spi*_*der 32 java configuration tomcat classpath

对于某些应用程序,我使用ZK,其他Hibernate,其他Apache Commons等.

我不想部署一个75MB的war文件,因为它使用了大量的库.

我不想将库添加到我的tomcat lib文件夹中,也不想将其添加到其配置的类路径中,因为我可能有一个使用库x.1的旧应用程序和另一个使用库x.2的应用程序

出于这个原因,在web.xml或context.xml中有一些东西会很棒,我会说:

<classpath>/usr/local/tomcat/custom-libs/zk-5.0.4</classpath>
Run Code Online (Sandbox Code Playgroud)

注意:以上是伪代码

Spi*_*der 36

从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>
Run Code Online (Sandbox Code Playgroud)

在Netbeans中,在打包时,我只是解开所有软件包,将.war大小降为零,确保依赖项位于服务器上的正确文件夹中并上传.Yey!不再有100 MB WAR文件.

  • 因为我在unix上,所以我试图聪明地将半冒号改为冒号,并且想知道错误花了一个小时 (5认同)

gav*_*koa 20

添加@Spider答案.

Tomcat Context hold Loader元素.根据docs部署描述符(<Context>标签中的内容)可以放在:

  • $CATALINA_BASE/conf/server.xml - 糟糕 - 需要服务器重启才能重新读取配置
  • $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/resourcesdir和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>
Run Code Online (Sandbox Code Playgroud)

更新 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>
Run Code Online (Sandbox Code Playgroud)

  • @Chad:你找到了更好的解决方案吗? (2认同)

Nic*_*ick 7

这是META-INF/context.xml文件可用于的内容.您定义了自己的WebappLoader,它为您的特定Web应用程序加载类.这是我使用的参考:http://tomcat.apache.org/tomcat-5.5-doc/config/loader.html(编辑:for 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

  • 不需要创建自己的`WebAppLoader`,因为Tomcat 7带有`VirtualWebappLoader`,它通过`virtualClasspath`属性提供所需的功能. (3认同)

Fak*_*een 7

另一个有点hacky替代品.

你可以编写一个派生自urlclassloader的5-6行自定义类加载器,只需使用addUrl()方法添加你的类路径jar .

然后将其设置为应用程序代码中线程的上下文类加载器.

Thread.setContextClassLoader(new CustomClassloader(path, parentClassLoader)
Run Code Online (Sandbox Code Playgroud)

父类加载器通常在哪里

Thread.getContextClassloader()
Run Code Online (Sandbox Code Playgroud)