IllegalStateException : Web app root system property already set to different value问题详解
一、问题描述
最近公司有了一个新项目,这个项目最近部署到测试服务器上的时候出现了一个问题。
严重: 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问题详解的更多相关文章
- java.lang.IllegalStateException:Web app root system property already set to different value 错误原因及解决 Log4j
Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口 服务器.NT的事件记录器.UNIX Syslog守护进程等: ...
- 解决tomcat部署多个虚拟机时报IllegalStateException: Web app root system property already set to 的问题
解决tomcat部署多个虚拟机时报IllegalStateException: Web app root system property already set to 的问题 在web.xml中添加如 ...
- java.lang.IllegalStateException: Web app root system property already set to different value
webAppRootKey是在java web项目的web.xml配置文件中表示项目的唯一标示,在Eclipse调试Web项目时,项目的路径是一个临时路径,不在真正的路径下,可以通过log4j日志的方 ...
- Web app root system property already set to different value 错误原因及解决
http://yzxqml.iteye.com/blog/1761540 ——————————————————————————————————————————————————————————————— ...
- 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 ...
- 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下面不行的处理方法 ...
- Web Api 接口返回值不困惑:返回值类型详解
前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 WebApi 接口参数:传参详解,这篇博文内容本身很基础 ...
- 安装mysql8.0.11及修改root密码、连接navicat for mysql的思路详解
1.1. 下载: 官网下载zip包,我下载的是64位的: 下载地址:https://dev.mysql.com/downloads/mysql/ 下载zip的包: 下载后解压:(解压在哪个盘都可以的) ...
- html 5 本地数据库(Web Sql Database)核心方法openDatabase、transaction、executeSql 详解
Web SQL数据库API实际上不是HTML5规范的组成部分,而是单独的规范.它通过一套API来操纵客户端的数据库.Safari.Chrome. Firefox.Opera等主流浏览器都已经支持Web ...
随机推荐
- Mac OS 系统工具使用
1. 截屏的处理 Command + Shift + 4
- Oracle 两个表之间更新的实现
Oracle 两个表之间更新的实现 来源:互联网 作者:佚名 时间:2014-04-23 21:39 Oracle中,如果跨两个表进行更新,Sql语句写成这样,Oracle 不会通过.查了资料,S ...
- php面试题及答案收藏(转)
php面试题及答案收藏(这套试题是在网上看到的,不知作者是谁) 基础题 1.表单中 get与post提交方法的区别? 答:get是发送请求HTTP协议通过url参数传递进行接收,而post是实体数据, ...
- JavaScript + HTML 虚拟键盘效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Spring对Quartz的封装实现简单需注意事项
前段时间在项目中一直使用正常的Quartz突然出现了任务漏跑的情况,由于我以前看过Quartz的内部实现,凭借记忆我觉得是由于Quartz的线程池的使用出现问题导致了故障的发生.为了搞清问题的真相,我 ...
- Zabbix日志监视的汇总报警(更新发送邮件脚本)
Zabbix的用户一定会碰到这种情况: 日志报警一般设置的是multiple模式,有错误大量写入的时候,每写入一行就会触发一次action,导致出现大量的报警邮件. 特别是ora的报警,经常一出就是上 ...
- .NET转Java学习规则
做一个个人Blog(博客) 过程分3个大阶段: 使用servlet/jsp和jdbc,mysql完成第一阶段Blog 项目修改为Spring(IOC+MVC)+SpringJdbc+MyBatis模式 ...
- Lock-Free 编程
文章索引 Lock-Free 编程是什么? Lock-Free 编程技术 读改写原子操作(Atomic Read-Modify-Write Operations) Compare-And-Swap 循 ...
- 十进制数转化成二进制后包含一的数量(c++)
#include <iostream> using namespace std;int func(int x){ int count=0; while(x){ ...
- 虚拟化平台cloudstack(8)——从UI开始
UI ucloudstack采用的是前后端分离的架构,就是说前端可以选择使用web.swing甚至其它的界面,都可以. 我们来看cloudstack的UI信息吧,所有的cloudstack的UI都在{ ...