關於不重啓Tomcat自動加載改變的class文件

修改server.xml,在Host標籤下加入以下配置

<Context path="" docBase="FileManager" reloadable="true">
</Context>
<Context path="/FileManager" docBase="FileManager" reloadable="true">
</Context>

第一個Context是爲了ip+端口直接指向FileManger這個項目。
path代表的是URL入口,例如第一個代表localhost:8080,第二個則代表localhost:8080/FileManger。

docBase是物理路徑,可以是絕對路徑,也可以是相對Host標籤中appBase的相對路徑,而Host標籤中appBase的默認值是webapps文件夾,所以這裏的FileManger就代表webapps下的FileManager文件夾。

這裏的path+docBase的配置就表示了ip+端口或者ip+端口+/項目名稱都可以指向你的項目。

reloadable就告訴Tomcat需要監控WEB-INF中的class文件,如果有變化了,就需要重新加載。並且是重新加載整個項目的,包括web.xml等等。

但是這樣修改是不會監控web.xml變化的,web.xml變了之後並不會重新加載項目。而且直接在server.xml裏配置,server.xml變化了Tomcat是不會重新加載的,必須重新啓動Tomcat纔會更新server.xml中的內容。

加入WatchedResource標籤,首先我嘗試了直接在server.xml直接加入:

<Context path="" docBase="FileManager" reloadable="true">
       <WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>
<Context path="/FileManager" docBase="FileManager" reloadable="true">
       <WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>

但是這樣並沒有效果,web.xml變了後,Tomcat並沒有reload,原因暫時不知道。

在項目的META-INF中加入context.xml:

<?xml version='1.0' encoding='utf-8'?>
<Context reloadable="true">
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
</Context>

此時,server.xml的配置如下:

<Context path="" docBase="FileManager" reloadable="true">
</Context>

因爲如果在server.xml裏配置了Context,就不會加載項目中的META-INF中的context.xml

我在這裏的想法是通過server.xml裏這樣配置,指定ip+端口可以直接指向我的那個項目,然後再在項目的META-INF中配置context.xml實現監控web.xml。

事實證明,ip+端口或者ip+端口+項目名都可以自動加載改變的class文件了,並且也會在web.xml變化的時候重新加載,但是修改web.xml指揮改變ip+端口+項目名的,而不會變化ip+端口,例如,我將welcom-file改成Home1.jsp,這時前者會報404錯誤(因爲我的項目中並沒有Home1.jsp,這證明了它的web.xml確實改變了,但是後者卻依然可以正常訪問,並且是指向了原先的Home.jsp)。

分析下原因,在第二部分提到了再server.xml裏直接加WatchedResource無效,所以其實按照第三部分的設置,ip+端口只是指向了FileManger那個文件夾,並沒有監控web.xml的變化。(原因依然未知,爲啥在那裏設置WatchedResource無效?

經過前三部分的試驗,再結合ip+端口默認加載的是webapps下ROOT文件夾下的項目,應該可以想到了一個解決方案了。

將FileManger文件夾下的項目拷貝到ROOT文件夾下,server.xml配置文件不用加額外配置,在兩個文件夾下中的META-INF中都加入內容如第三部分的context.xml文件,這樣就可以都監控到class文件變化,也可以監控web.xml變化了。但是這樣的話軟件更新就必須要改兩處地方,更好的解決方案也沒有想到,因爲對Tomcat的配置也不是特別清楚。

注意

這樣不重啓Tomcat自動加載class文件,有時候控制檯會報錯,內容如下:

Illegal access: this web application instance has been stopped already.  Could not load ********.  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.

這個是因爲Tomcat在重新加載class的時候是重新裝載整個web項目的,並沒有關閉所有線程,在Tomcat關閉後,那些線程依然運行,這樣就會導致這些錯誤。

我用了DBCP來管理連接,每次都是那塊報這個錯誤,但是好像並沒有影響軟件的使用,等那些沒有關閉的線程都關閉後,就不會繼續報錯了。如果不想報錯的話,只能重啓Tomcat,把reloadable設置成false。

發佈了63 篇原創文章 · 獲贊 78 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章