【发布时间】:2014-02-07 17:06:27
【问题描述】:
我开发并测试了一个作为 War 文件的应用程序,并且在游戏后期,DevOps 公司规定我正在开发的应用程序将部署为一个共享的 Jar 文件。部署环境为 Windows Server 2008R2 上的 Tomcat6。
Web 应用程序的多个 (~100) 实例作为单独的 Tomcat 实例运行。我试图解决的问题是,一旦应用程序 jar 从实例库移动到 tomcat 库,应用程序就无法找到我的日志记录配置文件 logback.xml。看起来有点像这样:
/root/tomcat6/
bin/
lib/
myapp.jar
conf/
...
myapp_inst1/
myapp.properties <-- yes, this is an odd place for props
bin/
installmyapp.bat <-- custom scripts to install and run as win service
startmyapp.bat and set catalina home and work
stopmyapp.bat
conf/
web.xml
server.xml <-- port, etc., changed for instance
webapp/
ROOT/
WEB-INF/
lib/ <-- empty!
classes/
logback.xml
web.xml <-- refers to servlet class in myapp.jar
myapp_inst2/
...
myapp_inst3/
...
我的理解是我使用的logger,Slf4j下的Logback,只是简单的使用classpath来定位logback.xml配置文件(来自http://logback.qos.ch/manual/configuration.html)。
我的理解也是,Tomcat 会构建自己的类路径,这些路径应该包括应用程序lib/、应用程序classes/ 和tomcat/lib/ 目录(http://www.mulesoft.com/tcat/tomcat-classpath)。但是,当我将应用程序 jar 文件移到应用程序 lib/ 目录之外时,我在 logback.xml 中设置的 logback 设置不再生效。
有谁知道为什么应用程序不再找到配置文件,更重要的是,如何解决这个问题?我唯一能想到的是 Tomcat 应用上下文类加载器可以使用 Tomcat 通用类加载器,但反之不行(但是你如何解决这个问题?)
对我来说,一个很大的要求是应用程序日志文件必须是独立的,并且允许在每个实例的基础上进行自定义,所以我认为将其复制到 tomcat/lib 不会让我到达那里。有什么想法吗?
- 编辑-
我的问题的根源似乎是 tomcat 类路径。由于 web 应用程序入口点是 tomcat 的公共类加载器中的 servlet,因此它在应用程序上下文类加载器中找到的任何内容都不适用于应用程序。无赖。
我正在想办法解决这个问题。你怎么看?
1) 将 servlet 实例重构为非常非常通用的东西,以便在产品的生命周期内永远不需要更改它。我说的是servlet的裸壳。然后,此类将由应用程序上下文加载器加载,并可以在共享位置的 jar 中“找到”应用程序的其余部分,这些部分可以维护。
2) 创建一个 servlet 生命周期对象的实例,而不是 servlet,例如 ServletContextListener,它将获取一个 logger 对象。同样,这将被编码为最低限度,其目的是永远不会改变。使用上下文侦听器而不是 servlet 本身,这可能更容易。原则上这会强制应用程序上下文进入范围吗?
【问题讨论】:
-
您的应用程序 jar 应位于 WEB-INF/lib 下。不在 Tomcat 的类路径中。
-
您已经回答了问题的第一部分。标准类加载器层次结构委托父方向的工作,而不是相反。如果你想这样做,你必须使用你自己的自定义类加载器。请查看this article 以了解类似情况。
-
@Ralf 我想问的是它是否真的是一个层次结构并且只在一个方向上起作用——我想你刚刚回答了这个问题。我不确定。现在我必须弄清楚如何解决这个问题。
-
@jb-nizet 我原则上同意应用程序 jar 应该在 WEB-INF/lib 中,但正如我所说,我对此别无选择。该应用程序确实可以使用 tomcat/lib 中的 jar,但这个日志文件配置是我必须弄清楚的最后一件事。