题记
之前上学的时候,基本不怎么用这种方法,一个web服务器部署多个项目。但是工作了以后就不一样了,可能经常会遇到自己同时搞多个项目的情况。这样放在你面前的解决方案基本有两种,一种是我们安装多个web服务器,然后修改各个web服务器的默认端口,避免冲突。另外一种就是我们直接在一个web服务器中同时部署多个项目,本篇文章就是围绕第二种方法遇到的问题来讲述的。
场景描述
之前可能没有注意这个问题,最近一次做项目由于是一个单一独立的项目,所以在创建项目的时候web.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5" >
<!-- Spring的log4j监听器 -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- 配置Spring的用于初始化容器对象的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 负责处理由JavaBean Introspector使用而引起的缓冲泄露的监听器 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- 注意applicationContext.xml和下面的springmvc的配置文件都是放在src下的-->
<param-value>classpath*:applicationContext*.xml</param-value>
</context-param>
<!-- 字符集 过滤器 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>com.kcrm.base.common.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>*.do</url-pattern>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!-- 中央控制分发器 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>720</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
一个项目跑的时候没有一点问题,最后由于项目需要做一个后台的管理系统,为了防止和接口的这个系统耦合在一起就重新建了一个项目。紧接着问题就来了,两个系统在同一个web服务器上跑的时候就出了问题,报错信息如下
严重: 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' = [D:\DevelopTools\apache-tomcat-8.0.29-windows-x64\apache-tomcat-8.0.29\webapps\crms\] instead of [D:\DevelopTools\apache-tomcat-8.0.29-windows-x64\apache-tomcat-8.0.29\webapps\kcrm\] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files!
at org.springframework.web.util.WebUtils.setWebAppRootSystemProperty(WebUtils.java:150)
at org.springframework.web.util.Log4jWebConfigurer.initLogging(Log4jWebConfigurer.java:117)
at org.springframework.web.util.Log4jConfigListener.contextInitialized(Log4jConfigListener.java:45)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4793)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5236)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
log4j:WARN No such property [datePattern] in org.apache.log4j.RollingFileAppender.
解决方案
后经过查阅资料发现是没有加如下的配置导致的,由于两个项目都没有设置下面的值,导致两个项目默认的webAppRootKey就是一样的。这样只部署一个项目的时候不会出现问题,但是一个web服务器部署两个同时没有设置webAppRootKey的项目的时候就会有问题。同样的,我们在给webAppRootKey赋值的时候也要注意:防止重名的现象,尽量每个项目设置webAppRootKey值的时候要有一定的意义。
<!-- 区分项目名称,防止默认重名 -->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>project</param-value>
</context-param>