前言
使用 spring 开发了一个web的项目。 使用log4j来记录日志。
开发完成后,打成.war 档,部署在Tomcat6 的服务器中, 是正常的;
但是部署到weblogic10.3.X.X 的版本时,部署失败,不能访问。
接下来就具体说一说追踪的历程。
文件配置
1. 在web.xml 中对log4j的配置是:
<!-- begin for log4j -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/config/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>6</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- end for log4j -->
log4jConfigLocation --log4j配置文件的位置, 这里是放在/WEB-INF/config下.(为什么要放在WEB-INF下? 安全性考虑)
log4jRefreshInterval -- 日志文件更新的时间
Log4jConfigListener -- spring 的日志监听
2. log4j.properties 的配置
log4j.rootLogger=INFO,stdout,logfile
log4j.logger.com.classpackage=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=${webapp.root}/config/platform.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files.
log4j.appender.logfile.MaxBackupIndex=3
# Pattern to output: date priority [category] - message
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
${webapp.root} 这个变量就是war 解压后的路径。
3. 在java 中写入日志
private static Log logger = LogFactory.getLog(ClassName.class);
logger.info("info:!");
logger.debug("debug:!");
logger.error("error:!");
以上的配置在Tomcat 中可以产生对应的log 文件,而且日志也能正确的写入, 包含spring 产生的一些日志。(比较奇怪的是好像会覆盖tomcat 自身产生的日志, tomcat server的日志不产生,不知是否和server 本身冲突, 因为tomcat 使用的也是log4j, 尚为验证)。
但是, 同样的war档放入weblogic 中, 安装就会出错, 错误信息:
User defined listener org.springframework.web.util.Log4jConfigListener failed: java.lang.IllegalStateException:
Cannot set web app root system property when WAR file is not expanded.
java.lang.IllegalStateException: Cannot set web app root system property when WAR file is not expanded at
org.springframework.web.util.WebUtils.setWebAppRootSystemProperty(WebUtils.java:144)
at org.springframework.web.util.Log4jWebConfigurer.initLogging(Log4jWebConfigurer.java:116)
at org.springframework.web.util.Log4jConfigListener.contextInitialized(Log4jConfigListener.java:45)
at weblogic.servlet.internal.EventsManager$FireContextListenerAction.run(EventsManager.java:481)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120) at .....
看意思是说, war 档没有展开不能设置web 应用程序的系统属性。 错误出在WebUtils.java 的144行,
看一下144行的代码片段
public static void setWebAppRootSystemProperty(ServletContext servletContext)
throws IllegalStateException
{
Assert.notNull(servletContext, "ServletContext must not be null");
String root = servletContext.getRealPath("/");
if (root == null) {
throw new IllegalStateException("Cannot set web app root system property when WAR file is not expanded");
}
String param = servletContext.getInitParameter("webAppRootKey");
String key = (param != null) ? param : "webapp.root";
String oldValue = System.getProperty(key);
if ((oldValue != null) && (!(StringUtils.pathEquals(oldValue, root)))) {
throw new IllegalStateException("Web app root system property already set to different value: '" + key + "' = [" + oldValue + "] instead of [" + root + "] - " + "Choose unique values for the 'webAppRootKey' context-param in your web.xml files!");
}
System.setProperty(key, root);
servletContext.log("Set web app root system property: '" + key + "' = [" + root + "]");
}
的确,是会读取当前的servlet 的路径。 想想,weblogic 的确没有解压war档, 看来的确是找不到。
配置log4jExposeWebAppRoot 为false, 就不会去找这个路径了。修改web.xml,
<!-- begin for log4j -->
<context-param>
<param-name>log4jExposeWebAppRoot</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/config/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>6</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- end for log4j -->
重新部署。 可以部署成功了, 但在weblogic控制台上回报一个找不到log4j.properties的错误, 没有解压,也就没有这个路径。
虽然, weblogic 不解压war 档,但是在 weblogic 的user_projects\domains\base_domain\servers\AdminServer\tmp\_WL_user 这个路径下, 会有web 项目的一些类型解压后的路径, 这应该是服务端缓存。
既然这样, 是否可以到这个路径下去找,把路径修改为:
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:../config/log4j.properties</param-value>
</context-param>
错误没有了, 可以正常访问。
但是, 查看后发现 配置的 log 文件并没有产生。 是否weblogic 还有其他相关设定。
参考
http://edocs.weblogicfans.net/wls/docs92/logging/config_logs.html weblogic 官方对于log4j 的介绍,有空再研究