问题解决:启动tomcat,日志输出:java.lang.ClassNotFoundException
问题场景
有一个老项目,其中的tomcat有引入听云的插件。之后,因为项目不需要了,所以需要移除相关的插件。之前是直接在启动命令里面加上javaagent
参数。现在移除了这个参数,但是启动了,提示报错,报错提示如下:
java.lang.ClassNotFoundException: com.tingyun.api.agent.TingYunApiImpl
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
at org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:126)
at org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:63)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at org.apache.jsp.admin.commonModule.fastdfs.index_jsp._jspService(index_jsp.java:180)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:439)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
问题环境
软件 | 版本 |
---|---|
tomcat | 7.0 |
JDK | 1.6 |
问题原因
如果了解tomcat
的目录结构的话,遇到这个问题的时候,应该知道是为什么。这是tomcat
的内部机制导致的。对于JSP
文件,tomcat在调用JSP
页面的时候,在第一次调用的时候,会在本地的工作目录的work/Catalina/
生成对应的域名的文件夹,里面会存放对应的JSP
生成的java
文件,并进行编译,形成对应的class
文件。如下图:
所以,如果是新页面,第一次调用的时候,会比较慢。等编译成功之后,调用起来就比较快了。之后,如果JSP
页面有变动的时候,tomcat
检测到就会进行更新。
所以,有经验的运维及开发,就会在更新代码的时候,顺便删除掉 work
目录,避免出现问题。
那么,听云这个插件启动的时候,会在对应的页面加入对应的代码。而这部分代码已经被生成在work
目录下面了。如果我们只是移除插件,而没有变动代码,那么原来已经包含插件的代码就会出现问题。
解决方案
既然知道了原因了,那我们在脚本移除听云的配置的时候,也得将tomcat
的work
目录给删除掉。
结果
tomcat
的
work
目录给删除掉,重新启动无报错。
总结
了解tomcat
的目录结构,遇到一些问题,就可以很轻易的解决掉。