控制servlet中的类路径

时间:2008-11-05 10:52:32

标签: java tomcat servlets classpath

我的servlet应用程序包含许多库.jars,其中一些包含嵌入的log4j.xml或log4j.properties文件。我想确保log4j首先找到我的log4j.xml!我已经尝试在servlet中搜索各种类路径元素的优先级的一些规范(例如,WEB-INF / classes总是在WEB-INF / lib之前吗?),或者某种方式来配置或调整servlet的类加载器,以便给定的资源目录出现在类路径的早期。到目前为止,我已经画了一个空白。有关确保servlet .war文件通过类加载器加载正确的log4j.xml的任何建议吗?

6 个答案:

答案 0 :(得分:15)

Tomcat 8.5

Ditto Tomcat 8.0。

请参阅文档:Class Loader HOW-TO

Tomcat 8.0

答案很简单,取自Tomcat文档页面Class Loader HOW-TO。特别注意使用/WEB-INF/目录/文件夹。

  

因此,从Web应用程序的角度来看,类或资源加载按以下顺序查找以下存储库:

     
      
  • JVM的Bootstrap类
  •   
  • /WEB-INF/classes您的网络应用
  •   
  • /WEB-INF/lib/*.jar您的网络应用
  •   
  • 系统类加载器类(如上所述)
  •   
  • 常见的类加载器类(如上所述)
  •   
     

如果Web应用程序类加载器为configured<Loader delegate="true"/>,则订单变为:

     
      
  • JVM的Bootstrap类
  •   
  • 系统类加载器类(如上所述)
  •   
  • 常见的类加载器类(如上所述)
  •   
  • /WEB-INF/classes您的网络应用
  •   
  • /WEB-INF/lib/*.jar您的网络应用
  •   

Tomcat 6

摘自Tomcat 6页面Class Loader HOW-TO

  

因此,从Web应用程序的角度来看,类或资源加载按以下顺序查找以下存储库:

     
      
  • JVM的Bootstrap类
  •   
  • 系统类加载器类(如上所述)
  •   
  • /WEB-INF/classes您的网络应用
  •   
  • /WEB-INF/lib/*.jar您的网络应用
  •   
  • $CATALINA_HOME/lib
  •   
  • $CATALINA_HOME/lib/*.jar
  •   

答案 1 :(得分:4)

据我所知,类路径中的资源选择是非确定性的(从应用程序开发人员的角度来看)。即使一致地加载相同的文件,行为也可能会改变:  1.升级当前容器的版本时。  2.如果你换容器。

最简单的解决方案是从库jar中删除嵌入式log4j配置文件。嵌入log4j配置几乎不是一个好主意,因为它会导致你在这里看到的问题......

他们是你开发的第三方罐子还是罐子?

答案 2 :(得分:3)

我们的web.xml文件中的Spring Log4jConfigListener

您可以指定log4j配置文件的位置作为上下文参数,即您可以将其设置为/WEB-INF/log4j.xml

这会是你的选择吗?如果您没有使用Spring,我知道您可以以编程方式设置Log4j位置,这也可能有效。

答案 3 :(得分:1)

根据我的经验,WEB-INF / classes通常优先于WEB-INF / lib中的jar,但是,这也取决于你使用的servlet容器(例如,我永远无法弄清楚JRun的行为)。如果你能告诉我你正在使用哪个容器,那将会非常有用。

另外,你确定违规的log4j配置是在WEB-INF / lib的jar中吗?通常,当我在servlet容器情况下遇到类路径问题时,这是因为库位于Web应用程序的外部

servlet规范建议 Web代理类加载器在委托给容器的类加载器(SRV.9.7.2)之前加载它们自己的类,但由于这与Java规范相反,并非所有供应商都这样做这默认情况下(实际上Tomcat是我用过的唯一一个默认使用它的容器)。话虽如此,总是可以配置容器的Web应用程序类加载行为。如果你告诉我你正在使用哪个容器,我可以帮助你(具体来说,我之前在WebLogic,WebSphere,Glassfish和JRun上已经成功完成了这项工作)。

答案 4 :(得分:1)

如果您无法控制类路径,因为Tomcat正在为您设置它,您是否至少能够为log4j.configuration设置系统属性?我相信该属性指向的位置可以在类路径之外设置。

如果没有,另一种方法,虽然是一个丑陋的方法,将在您的应用程序代码中自己明确地运行其中一个配置程序。

答案 5 :(得分:-1)

您需要在CLASSPATH中使用log4j.properties。最好的地方是WEB-INF / classes。

您还必须确保使用的是log4j.jar版本。所以,把它放在WEB-INF / lib中,只是为了确保你没有使用tomcat文件夹中的一个,因为它可能会导致奇怪的类加载问题。