Jboss7默认采用容器自己的log4j module,应用自己配置的log4j不起作用,需要应用做一些设置:

以springMVC项目为例:

1> 在WEB-INF下新建文件jboss-deployment-structure.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<jboss-deployment-structure>

   <deployment>

     <exclusions>

       <module name="org.apache.log4j" />

     </exclusions>

   </deployment>

</jboss-deployment-structure> 

2> 在web.xml里配置

<context-param>
		<param-name>log4jConfigLocation</param-name>
		<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>

<context-param>
	<param-name>log4jRefreshInterval</param-name>
	<param-value>60000</param-value>
</context-param>

<listener>
		<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>


如果想使用外部的log4j配置文件,比如jboss stanalone/configuration下面的配置文件:

<context-param>
	<param-name>log4jConfigLocation</param-name>
	<param-value>file://${jboss.server.config.dir}/log4j.properties</param-value>
</context-param>
	
<context-param>
	<param-name>log4jRefreshInterval</param-name>
	<param-value>60000</param-value>
</context-param>
	
<listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

如果部署多个web项目,还需要指定webAppRootKey,否则会报错。
<context-param>
	<param-name>webAppRootKey</param-name>
	<param-value>app2.root</param-value>
</context-param>

3> 在WEB-INF下新建log4j.properties(引用外部的log4j.properties不需要在此创建)

# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
log4j.rootLogger=INFO,logfile

#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=${jboss.server.log.dir}/YOURAPP.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


4> pom添加依赖

<dependency> 
       		<groupId>log4j</groupId> 
      		 <artifactId>log4j</artifactId> 
       		<version>1.2.17</version> 
</dependency>

常见问题:

ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/app2]] (MSC service thread 1-7) Exception sending context initialized event to listener instance of class org.springframework.web.util.Log4jConfigListener: java.lang.IllegalStateException: Web app root system property already set to different value: 'webapp.root' = [E:\jboss-as-7.1.1.Final\standalone\tmp\vfs\tempe7424b5081976d9e\app1.war-6877981a77798c66\] instead of [E:\jboss-as-7.1.1.Final\standalone\tmp\vfs\tempe7424b5081976d9e\app2.war-81d75a6298df23d1\] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files!
	at org.springframework.web.util.WebUtils.setWebAppRootSystemProperty(WebUtils.java:150) [spring-web-3.2.8.RELEASE.jar:3.2.8.RELEASE]
	at org.springframework.web.util.Log4jWebConfigurer.initLogging(Log4jWebConfigurer.java:116) [spring-web-3.2.8.RELEASE.jar:3.2.8.RELEASE]
	at org.springframework.web.util.Log4jConfigListener.contextInitialized(Log4jConfigListener.java:45) [spring-web-3.2.8.RELEASE.jar:3.2.8.RELEASE]
	at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3392) [jbossweb-7.0.13.Final.jar:]

原因:

同时部署了两个web应用,都在web.xml中配置了org.springframework.web.util.Log4jConfigListener。

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 + "]");
  }

可见,部署app1以后,由于初始时param为空,所以key被设置成webapp.root, 对应的value设置成servletContext.getRealPath("/"), 即webapp.root指向了app1的根目录。

当部署app2的时候,执行

 String oldValue = System.getProperty(key);
以后oldValues是app1的根目录,因此报错。

解决方案:

每个应用设置自己的app root,

比如:

<context-param>
	<param-name>webAppRootKey</param-name>
	<param-value>app2.root</param-value>
</context-param>

而且这样设置以后,app2.root可以作为环境变量使用

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐