关于在使用tomcat作开发测试的某些时候无故报ClassNotFound异常的解决方法

        不少人都使用tomcat来做为java web项目的服务器,特别是在开发阶段,选择的人更多。本文所说的问题针对tomcat的开发环境,在正式环境中不会出现这个问题。html

        前段时间,在进行项目运行的时候出现了一件怪事:一个类明明就有,可是tomcat在启动的时候就是要反复报“java.lang.ClassNotFoundException”,通过不断检查,上网查询,终于找到了缘由并解决之,下面作一些说明,但愿对其余人有所帮助。java

0、重现

        要重现这个问题,须要知足一些条件:在开发的IDE中进行部署(如eclipse,这是很常见的),项目中有用户登陆的操做,连续的直接重启服务器(这在开发中也是很常见的)。web

        这个问题并非每次都会出现,只不过出现的几率也是挺大的,出现的时候报的错误就是说的用于在session中保存用户登陆的那个类找不到,服务器也启动成功,可是看到有异常总感受不舒坦,就想解决了她。apache

一、缘由

        出现这个问题的缘由就是tomcat在关闭的时候会保存当前存在的session对象,而后在启动的时候恢复,这个的具体过程没有去研究过,不过关于这个的例子你们能够试一试——就是在正式环境(不是在IDE中部署)中,用户登陆以后不关闭浏览器,使用tomcat的shutdown脚本关闭服务器,而后在启动服务器,就能够看到浏览器的session仍是有效的。浏览器

        这个功能默认都是开启的,可是在开发环境中服务器关闭的时候保存的用户对象对应的类有可能已经改变了(部署的时候从新编译有可能会形成这种状况),等到服务器启动的时候恢复session就找不到类了,因此就报了那个错误。tomcat

        再出现这个错误以后咱们就会去找,发现这个类真真正正是存在的,而后就会很疑惑,不知因此。服务器

        下面就来解决这个问题。session

二、解决方法

        既然前面已经说过,这个问题的缘由是由于tomcat要试图恢复关闭时保存的session形成成的,那么咱们就关闭这个功能吧,这样服务器启动还会快速一些呢。app

        说干就干,下载就以使用eclipse的java ee版中关联的tomcat为例子进行说明。eclipse

2.1 在eclipse中关联tomcat以后产生的服务器配置

        注:使用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 &quot;%r&quot; %s %b" prefix="localhost_access_log" suffix=".txt"/>
</Host>

        这就是配置服务器的部署状况的。

2.2 部署项目以后的配置

        咱们经过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 &quot;%r&quot; %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 &quot;%r&quot; %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文件了,这样作主要是它的自动从新加载不只消耗机器的性能,并且还多数时候很差用,仍是要手动的重启服务器。

2.3 关闭tomcat关闭时的session自动保存

        直接修改关于部署的配置为下面这个样子(删去了注释):

<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">

   <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
       pattern="%h %l %u %t &quot;%r&quot; %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!!

相关文章
相关标签/搜索