logback + spring的webRootKey 多專案同時部署衝突問題
阿新 • • 發佈:2019-01-28
一次部署專案後出現下面的異常:
Java程式碼
網上很多都說是跟日誌有關
開啟logback/log4j相關的spring監聽類,比如LogbackConfigListener,初始化呼叫WebLogbackConfigurer的initLogging方法:
Java程式碼
追蹤到WebUtils這個類中,開啟這個類140行檢視setWebAppRootSystemProperty方法,如下
Java程式碼
原因很明顯了:
Web 容器啟動的時候會獲取webAppRootKey引數的值,然後以此值為可以key 把ROOT的絕對路徑寫到系統變數裡,
如果不定義webAppRootKey引數,那麼webAppRootKey就是預設的"webapp.root",但如果多個專案都使用預設或相同的引數這裡就會報錯了
解決方法:
在web.xml中新增如下配置
Xml程式碼
這樣在logback/log4j的配置檔案中使用${ysxj.root }會用來表示Web目錄的絕對路徑
Java程式碼
-
java.lang.IllegalStateException: Web app root system property already set to different value: 'webapp.root' = [/usr/local/webserver/tomcat/webapps/naruto-manager/] instead of [/usr/local/webserver/tomcat/webapps/ysxj-manager/] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files!
網上很多都說是跟日誌有關
開啟logback/log4j相關的spring監聽類,比如LogbackConfigListener,初始化呼叫WebLogbackConfigurer的initLogging方法:
Java程式碼
- publicstaticvoid initLogging(ServletContext servletContext) {
- // Expose the web app root system property.
- if (exposeWebAppRoot(servletContext)) {
-
WebUtils.setWebAppRootSystemProperty(servletContext);
- }
- ...
- }
追蹤到WebUtils這個類中,開啟這個類140行檢視setWebAppRootSystemProperty方法,如下
Java程式碼
- publicstaticvoid setWebAppRootSystemProperty(ServletContext servletContext) throws IllegalStateException {
- Assert.notNull(servletContext, "ServletContext must not be null");
-
String root = servletContext.getRealPath("/"
- if (root == null) {
- thrownew 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)) {
- thrownew 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 + "]");
- }
原因很明顯了:
Web 容器啟動的時候會獲取webAppRootKey引數的值,然後以此值為可以key 把ROOT的絕對路徑寫到系統變數裡,
如果不定義webAppRootKey引數,那麼webAppRootKey就是預設的"webapp.root",但如果多個專案都使用預設或相同的引數這裡就會報錯了
解決方法:
在web.xml中新增如下配置
Xml程式碼
- <context-param>
- <param-name>webAppRootKey</param-name><!--如果放兩個專案例項此屬性要設定,而且兩個專案param-value值的不能相同,log4j和logback都要設定,這點很容易忽略 -->
- <param-value>ysxj.root</param-value>
- </context-param>
這樣在logback/log4j的配置檔案中使用${ysxj.root }會用來表示Web目錄的絕對路徑