关于不重启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。

posted @ 2017-11-20 22:50  孤夏  阅读(4483)  评论(0编辑  收藏  举报