一、问题描述

    最近公司有了一个新项目,这个项目最近部署到测试服务器上的时候出现了一个问题。

严重: 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' = [ ] instead of [ ] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files! 

在eclipse下面启动是没问题的,打包的时候也没有报错。唯一的区别是测试服务器上tomcat里起了多个项目。

二、解决方法

从网上找了各种资料,解决方法是在web.xml中加一段代码

<context-param>
<param-name>webAppRootKey</param-name>
<param-value>projectName.root</param-value> <!-- 建议用"工程名字.root"-->
</context-param>

加了之后,果然解决了。

三、具体原因

    我是那种不找到具体原因就不甘心的人。

首先,这个项目用到了log4j(貌似现在大部分项目都在用)。log4j启动时,默认会寻找source folder(src)下的log4j.xml配置文件,若没有,会寻找log4j.properties文件。如果log4j放到别的位置,则需要在web.xml中配置。通过log4jConfigLocation指定文件的位置。

  <context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:config/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>6000</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

问题来了,问题就出在这个org.springframework.web.util.Log4jConfigListener类里面,点进去看这个class。

public class Log4jConfigListener implements ServletContextListener {

    @Override
public void contextInitialized(ServletContextEvent event) {
Log4jWebConfigurer.initLogging(event.getServletContext());
} @Override
public void contextDestroyed(ServletContextEvent event) {
Log4jWebConfigurer.shutdownLogging(event.getServletContext());
} }

再点进去initLogging这个方法。

public static void initLogging(ServletContext servletContext) {
// Expose the web app root system property.
if (exposeWebAppRoot(servletContext)) {
WebUtils.setWebAppRootSystemProperty(servletContext);
} // Only perform custom log4j initialization in case of a config file.
String location = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
if (location != null) {
// Perform actual log4j initialization; else rely on log4j's default initialization.
try {
// Resolve property placeholders before potentially resolving a real path.
location = ServletContextPropertyUtils.resolvePlaceholders(location, servletContext); // Leave a URL (e.g. "classpath:" or "file:") as-is.........
      .........

再点进去setWebAppRootSystemProperty这个方法。

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(WEB_APP_ROOT_KEY_PARAM);
String key = (param != null ? param : DEFAULT_WEB_APP_ROOT_KEY);
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 + "]");
}

在这个类里面就能看到拋异常的语句以及拋异常之前处理的逻辑了。

如果两个工程都不配webAppRootKey,第一个工程启动运行到这个ok,但是第二个工程启动的时候运行到这里,if那里就报错了。

其实归根究底不是log4j的原因,只要涉及到这个方法,并且没有设置webAppRootKey都会报错。当启动多个工程的时候,应该要配置一下这个webAppRootKey。

IllegalStateException : Web app root system property already set to different value问题详解的更多相关文章

  1. java.lang.IllegalStateException:Web app root system property already set to different value 错误原因及解决 Log4j

    Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口 服务器.NT的事件记录器.UNIX Syslog守护进程等: ...

  2. 解决tomcat部署多个虚拟机时报IllegalStateException: Web app root system property already set to 的问题

    解决tomcat部署多个虚拟机时报IllegalStateException: Web app root system property already set to 的问题 在web.xml中添加如 ...

  3. java.lang.IllegalStateException: Web app root system property already set to different value

    webAppRootKey是在java web项目的web.xml配置文件中表示项目的唯一标示,在Eclipse调试Web项目时,项目的路径是一个临时路径,不在真正的路径下,可以通过log4j日志的方 ...

  4. Web app root system property already set to different value 错误原因及解决

    http://yzxqml.iteye.com/blog/1761540 ——————————————————————————————————————————————————————————————— ...

  5. Web app root system property already set to different value: 'webapp.root'

    java.lang.IllegalStateException: Web app root system property already set to different value: 'webap ...

  6. Cannot set web app root system property when WAR file is not expanded

    Cannot set web app root system property when WAR file is not expanded 在tomcat下面可以,在weblogic下面不行的处理方法 ...

  7. Web Api 接口返回值不困惑:返回值类型详解

    前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 WebApi 接口参数:传参详解,这篇博文内容本身很基础 ...

  8. 安装mysql8.0.11及修改root密码、连接navicat for mysql的思路详解

    1.1. 下载: 官网下载zip包,我下载的是64位的: 下载地址:https://dev.mysql.com/downloads/mysql/ 下载zip的包: 下载后解压:(解压在哪个盘都可以的) ...

  9. html 5 本地数据库(Web Sql Database)核心方法openDatabase、transaction、executeSql 详解

    Web SQL数据库API实际上不是HTML5规范的组成部分,而是单独的规范.它通过一套API来操纵客户端的数据库.Safari.Chrome. Firefox.Opera等主流浏览器都已经支持Web ...

随机推荐

  1. Mac OS 系统工具使用

    1. 截屏的处理 Command + Shift + 4

  2. Oracle 两个表之间更新的实现

    Oracle 两个表之间更新的实现   来源:互联网 作者:佚名 时间:2014-04-23 21:39 Oracle中,如果跨两个表进行更新,Sql语句写成这样,Oracle 不会通过.查了资料,S ...

  3. php面试题及答案收藏(转)

    php面试题及答案收藏(这套试题是在网上看到的,不知作者是谁) 基础题 1.表单中 get与post提交方法的区别? 答:get是发送请求HTTP协议通过url参数传递进行接收,而post是实体数据, ...

  4. JavaScript + HTML 虚拟键盘效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. Spring对Quartz的封装实现简单需注意事项

    前段时间在项目中一直使用正常的Quartz突然出现了任务漏跑的情况,由于我以前看过Quartz的内部实现,凭借记忆我觉得是由于Quartz的线程池的使用出现问题导致了故障的发生.为了搞清问题的真相,我 ...

  6. Zabbix日志监视的汇总报警(更新发送邮件脚本)

    Zabbix的用户一定会碰到这种情况: 日志报警一般设置的是multiple模式,有错误大量写入的时候,每写入一行就会触发一次action,导致出现大量的报警邮件. 特别是ora的报警,经常一出就是上 ...

  7. .NET转Java学习规则

    做一个个人Blog(博客) 过程分3个大阶段: 使用servlet/jsp和jdbc,mysql完成第一阶段Blog 项目修改为Spring(IOC+MVC)+SpringJdbc+MyBatis模式 ...

  8. Lock-Free 编程

    文章索引 Lock-Free 编程是什么? Lock-Free 编程技术 读改写原子操作(Atomic Read-Modify-Write Operations) Compare-And-Swap 循 ...

  9. 十进制数转化成二进制后包含一的数量(c++)

    #include <iostream> using namespace std;int func(int x){    int count=0;    while(x){          ...

  10. 虚拟化平台cloudstack(8)——从UI开始

    UI ucloudstack采用的是前后端分离的架构,就是说前端可以选择使用web.swing甚至其它的界面,都可以. 我们来看cloudstack的UI信息吧,所有的cloudstack的UI都在{ ...