不少人都使用tomcat來做爲java web項目的服務器,特別是在開發階段,選擇的人更多。本文所說的問題針對tomcat的開發環境,在正式環境中不會出現這個問題。html
前段時間,在進行項目運行的時候出現了一件怪事:一個類明明就有,可是tomcat在啓動的時候就是要反覆報「java.lang.ClassNotFoundException」,通過不斷檢查,上網查詢,終於找到了緣由並解決之,下面作一些說明,但願對其餘人有所幫助。java
要重現這個問題,須要知足一些條件:在開發的IDE中進行部署(如eclipse,這是很常見的),項目中有用戶登陸的操做,連續的直接重啓服務器(這在開發中也是很常見的)。web
這個問題並非每次都會出現,只不過出現的機率也是挺大的,出現的時候報的錯誤就是說的用於在session中保存用戶登陸的那個類找不到,服務器也啓動成功,可是看到有異常總感受不舒坦,就想解決了她。apache
出現這個問題的緣由就是tomcat在關閉的時候會保存當前存在的session對象,而後在啓動的時候恢復,這個的具體過程沒有去研究過,不過關於這個的例子你們能夠試一試——就是在正式環境(不是在IDE中部署)中,用戶登陸以後不關閉瀏覽器,使用tomcat的shutdown腳本關閉服務器,而後在啓動服務器,就能夠看到瀏覽器的session仍是有效的。瀏覽器
這個功能默認都是開啓的,可是在開發環境中服務器關閉的時候保存的用戶對象對應的類有可能已經改變了(部署的時候從新編譯有可能會形成這種狀況),等到服務器啓動的時候恢復session就找不到類了,因此就報了那個錯誤。tomcat
再出現這個錯誤以後咱們就會去找,發現這個類真真正正是存在的,而後就會很疑惑,不知因此。服務器
下面就來解決這個問題。session
既然前面已經說過,這個問題的緣由是由於tomcat要試圖恢復關閉時保存的session形成成的,那麼咱們就關閉這個功能吧,這樣服務器啓動還會快速一些呢。app
說幹就幹,下載就以使用eclipse的java ee版中關聯的tomcat爲例子進行說明。eclipse
注:使用eclipse關聯tomcat的方法想必你們已經知道了,不然不會看到這裏了,即便你們真的不知道,也能夠查看個人另外的文章,那裏面有關於如何關聯的介紹。
使用eclipse關聯好tomcat以後,會在項目視圖中產生一個「Servers」的文件夾裏面又有一個文件夾對應新建的服務器,裏面就是一些服務器的配置,仔細觀察和對比這些配置,其實就是tomcat的conf目錄下面的配置文件拷貝了一份過來,徹底就是同樣的。
咱們比較關心的是其中一個叫作「server.xml」的文件,這裏面配置有服務器的監聽端口、部署狀況等等,這個文件比較長,這裏就不完整的貼出來了,只貼出咱們要關心的部分(大約在114-127行):
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html --> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <!-- Access log processes all example. Documentation at: /docs/config/valve.html Note: The pattern used is equivalent to using pattern="common" --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log" suffix=".txt"/> </Host>
這就是配置服務器的部署狀況的。
咱們經過servers視圖部署項目:
在添加了部署以後原先的關於部署的配置已經自動變動爲了:
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html --> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <!-- Access log processes all example. Documentation at: /docs/config/valve.html Note: The pattern used is equivalent to using pattern="common" --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log" suffix=".txt"/> <Context docBase="PMS" path="/ROOT" reloadable="true" source="org.eclipse.jst.jee.server:PMS"/> </Host>
這個時候服務器已經能夠啓動了,日常時候咱們也差很少就是這麼作的,固然有些人(好比我)還會把自動從新加載關閉,而後就變成了這樣:
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html --> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <!-- Access log processes all example. Documentation at: /docs/config/valve.html Note: The pattern used is equivalent to using pattern="common" --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log" suffix=".txt"/> <Context docBase="PMS" path="/ROOT" reloadable="false" source="org.eclipse.jst.jee.server:PMS"/> </Host>
這樣,當咱們在服務器啓動以後修改了java類文件服務器就不會自動地加載這個修改了的類對應的class文件了,這樣作主要是它的自動從新加載不只消耗機器的性能,並且還多數時候很差用,仍是要手動的重啓服務器。
直接修改關於部署的配置爲下面這個樣子(刪去了註釋):
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log" suffix=".txt" /> <Context docBase="PMS" path="/ROOT" reloadable="false" source="org.eclipse.jst.jee.server:PMS"> <Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="false" /> </Context> </Host>
這樣配置以後,就把對應部署的tomcat的session自動保存關閉了,原先的問題就沒有再出現過了。
根據解決以後的配置能夠看出來,其實出現這個問題的緣由就是tomcat默認開啓了對session在重啓時候的自動持久化,咱們須要作的就是關閉它,關閉的操做就是在對應應用的上下文(也就是<Context />)中添加:
<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="false" />
只不過因爲該標籤在添加完「部署」配置以後是默認本身關閉的,咱們須要讓它使用單獨的關閉標籤,那樣才能配置。
其實就是一句話的事兒。
本文介紹了一個在使用tomcat做爲開發調試用服務器時候啓動過程當中出現的問題的緣由和詳細的解決方法。
關於描述的這個問題,不少人都不知道究竟是怎麼一回事,網上關於這個問題的文章也不是不少,我以前尋找的時候就是找了好久以後纔看到的,本着作筆記和幫助他人的原則,寫下這篇文章,但願對你們有所幫助。
enjoy!!