Docker中Tomcat7升級Tomcat8中遇到的問題及解決辦法
最近應用需要升級Tomcat版本,啟動時遇到的一些問題,記錄一下。
背景:使用的docker容器,專門的運維人員幫忙升級了新的映象。
問題:
1. 升級後直接重啟了應用,發現不能訪問。檢視日誌發現拋異常找不到配置檔案,檢視發現docker裡面配置的配置檔案都在原來的tomcat7的conf目錄下,更改後重啟。重啟後仍然不成功,檢視日誌一步一步來。
2. 修改context.xml,報錯:無法載入資源工廠類dbcp
[ERROR][org.springframework.web.context.ContextLoader] Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name'xxx' defined in ServletContext resource [/WEB-INF/applicationContext-beans.xml] Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/applicationContext-dataSource.xml : Invocation of init method failed; nested exception is javax.naming.NamingException: 無法載入資源工廠類 [Root exception is java.lang.ClassNotFoundException:org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory]
搜尋後發現tomcat7 和 tomcat8的工廠類名稱發生了變化,所以找不到了,解決方法很簡單,將conf目錄下context.xml檔案修改,
factory改為:
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
同時 tomcat7中一些引數名在Tomcat8中也發生了變化,比如:maxActive需改寫為maxTotal,maxWait需改寫為maxWaitMillis,還有一些可自行對照了改。
3. 修改server.xml,上述配置檔案修改後,日誌仍然報錯:找不到JapperListener類,
java.lang.ClassNotFoundException: org.apache.catalina.core.JasperListener
對比tomcat7 與 tomcat 8 的 server.xml檔案發現8裡面沒有這個類,直接註釋掉。
啟動後又報錯:
The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid.
原來8版本的tomcat有個屬性secretRequired需要給設定值:
<Connector port=
"8009"
protocol=
"AJP/1.3"
redirectPort=
"8443"
/>
設定成""就可以了,也就是下面的設定結果:
<Connector port=
"8009"
protocol=
"AJP/1.3"
redirectPort=
"8443"
secretRequired=
""
/>
4. 修改web.xml檔案
報錯:
org.apache.tomcat.util.descriptor.web.SecurityConstraint.findUncoveredHttpMethodsForsecurityconstraintswithURLpattern[/*]
onlytheHTTPmethods[TRACEHEADDELETEOPTIONSPUT]arecovered.Allothermethodsareuncovered
修改方式類似下面這種改法:
<security-constraint>
<web-resource-collection>
<url-pattern>/bg/c/portal/protected</url-pattern>
<http-method>POST</http-method>
<http-method>GET</http-method>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>...</transport-guarantee>
</user-data-constraint>
</security-constraint>
改成下面這種,再增加一個安全配置,使所有的請求通過:
<security-constraint> <web-resource-collection> <url-pattern>/bg/c/portal/protected</url-pattern> <http-method>POST</http-method> <http-method>GET</http-method> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-constraint> <web-resource-collection> <url-pattern>/bg/c/portal/protected</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint>
後來還有登入頁面出來了,但是登入不上去,可能使資料來源的加密方式改了,需要重新加密使用者名稱密碼吧。因為是測試環境,直接使用了明文username/password。