在将java web应用程序的日志框架从log4j 1.x升级到log4j 2.x(例如,从log4j-1.2.15.jar迁移到log4j v2.17.1)后,部署在tomcat 9上的应用程序遇到了一个异常行为。尽管web.xml中为自定义servlet过滤器(例如com.demo.custom.filter.newsession)配置了初始化参数(init-param),但在过滤器init()方法中通过filterconfig.getinitparameter()获取这些参数时,却返回了null值。
例如,以下web.xml配置:
newsession newsession newsession com.demo.custom.filter.NewSession DomainName .testlab.com DomConfigFile /opt/tomcat/webapp/demoapp/WEB-INF/classes/NAM_log4j.xml customPropFile /opt/tomcat/webapp/demoapp/WEB-INF/classes/custom_resources.properties newsession /idff/sso
在过滤器NewSession的init方法中,尝试获取参数:
public void init(FilterConfig fConfig) throws ServletException {
try{
domainName = fConfig.getInitParameter("DomainName");
domConfigFile=fConfig.getInitParameter("DomConfigFile");
custom_resources=fConfig.getInitParameter("customPropFile");
}catch(Exception e){
myLogger.error(e.getMessage());
}
// ... 后续对null值的处理
if(domConfigFile==null){
myLogger.error("domConfigFile got null from web.xml, setting hardcoded value");
// ...
}
if(custom_resources==null){
myLogger.error("custom_resources got null from web.xml, setting hardcoded value");
// ...
}
}日志中会打印出类似以下错误信息:
ERROR com.demo.custom.filter.NewSession - domConfigFile got null from web.xml, setting hardcoded value ERROR com.demo.custom.filter.NewSession - custom_resources got null from web.xml, setting hardcoded value main ERROR Error processing element category ([Configuration: null]): CLASS_NOT_FOUND main ERROR Unknown object "root" of type org.apache.logging.log4j.core.config.LoggerConfig is ignored: try nesting it inside one of: ["Appenders", "Loggers", "Properties", "Scripts", "CustomLevels"]
这些错误表明,虽然过滤器本身被加载,但其初始化参数未能正确传递。更重要的是,日志中还出现了Log4j 2.x配置相关的错误,暗示问题的根源可能在于Log4j 2.x的配置不当。
表面上看,问题是过滤器参数获取失败,但结合Log4j 2.x的错误日志,可以推断出更深层次的原因:Log4j 2.x的配置文件存在语法错误或使用了Log4j 1.x的配置元素,导致Log4j 2.x初始化失败,进而影响了整个应用程序的启动流程,包括Servlet容器对web.xml中过滤器参数的正确解析和传递。
具体的错误提示Error processing element category ([Configuration: null]): CLASS_NOT_FOUND和Unknown object "root" of type org.apache.logging.log4j.core.config.LoggerConfig is ignored: try nesting it inside one of: ["Appenders", "Loggers", "Properties", "Scripts", "CustomLevels"]清晰地指出了以下两点:
这些Log4j配置错误可能导致日志系统无法正常初始化,甚至可能中断Tomcat的Web应用部署过程,从而影响到其他组件(如Servlet过滤器)的正常初始化。当Log4j 1.x的JAR包被移除后,Log4j 2.x成为唯一的日志实现,其配置的正确性变得至关重要。
解决此问题的关键在于提供一个符合Log4j 2.x规范的、结构正确的XML配置文件。通过修正Log4j 2.x的配置文件,确保其能够正确解析和初始化,从而使应用程序能够顺利启动,并让Tomcat正确加载并传递过滤器初始化参数。
以下是一个修正后的Log4j 2.x配置示例(假设文件名为log4j2.xml或TEST_log4j.xml,并放置在classpath中):
%d{MM/dd HH:mm:ss} %-5p %30.30c %x - %m%n %d{MM/dd HH:mm:ss} %-5p %30.30c %x - %m%n
通过以上修正,Log4j 2.x配置将符合其规范,能够正确初始化日志系统。一旦日志系统正常工作,Tomcat在部署Web应用时将不再因Log4j配置错误而中断,从而确保过滤器能够正确获取其初始化参数。
ib目录中彻底移除所有Log4j 1.x相关的JAR包(如log4j-1.2.x.jar、log4j-extras.jar等),以避免类路径冲突。当Tomcat过滤器在Log4j 2.x迁移后无法获取web.xml中的初始化参数时,应首先检查Log4j 2.x的配置文件。这类问题往往不是过滤器本身的配置错误,而是日志框架初始化失败导致的连锁反应。通过仔细检查并修正Log4j 2.x XML配置中的语法错误和Log4j 1.x遗留元素,确保日志系统能够正常启动,即可解决此类问题,保证Web应用程序的稳定运行。