【问题标题】:Path problems when deploying servlet as a shared jar lib on Tomcat在 Tomcat 上将 servlet 部署为共享 jar 库时的路径问题
【发布时间】: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,但这个日志文件配置是我必须弄清楚的最后一件事。

标签: tomcat servlets logback


【解决方案1】:

将您的 web 应用程序部署为共享 jar 听起来是个坏主意。其背后的原理是什么?

你可以做的是将它分成两个罐子。一个 jar 用于存放您放在 tomcat/lib 下的公共库内容,另一个用于存放应用程序特定内容(例如 logback.xml 文件)的存放在 webapp 的 WEB-INF/lib 下的内容。

另见this question(哦,我刚刚注意到它也是来自你的:)。

【讨论】:

  • 这令人抓狂,但这是由 DevOps 推动的,这似乎是我公司唯一听取意见的团队。我们有一个服务器,它运行着这个应用程序的一百多个实例,每个实例都在它自己的 tomcat 实例中。 DevOps 希望能够换出机器上的单个 jar 文件以同时更新所有 100 多个实例。我们确实想要 100 多个 logback.xml 副本,但它不在 jar 中 - 看起来是我的漂亮图表 :)
  • 大声笑,是的,我不得不问一次以了解发生了什么,但让自己对“移动罐子”的答案和类似的结构变化持开放态度。在这一点上,我的结构被刻在石头上,我必须具体找出如何使这些属性可见。我希望类路径有一些 tomcat 的魔力(tomcat 似乎有很多极端情况的配置选项)或者(呃)滚动我自己的类加载器。
  • 啊,我明白了,logback.xml 不在罐子里。为什么我建议在WEB-INF/lib 下创建指向常见 jar 的符号链接不起作用(我的其他答案)?
  • 这实际上也是我们对其他应用程序的“标准”部署模型。我对这家公司还很陌生,并且在这种思维方式上遇到了困难,但基本上,主要的 DevOp 成功地与我们的 CTO 争辩说,将符号链接到 Web 应用程序容器将是“糟糕的工程”。我尽量不被讽刺而窒息。
  • 也许您可以尝试使用上下文选择器,如下所述:logback.qos.ch/manual/loggingSeparation.html 我自己从未尝试过。您也可以要求您的 DevOp 解决问题,因为他非常擅长“工程”;)
猜你喜欢
  • 1970-01-01
  • 2014-03-01
  • 1970-01-01
  • 2018-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
相关资源
最近更新 更多