我们遇到以下异常
2024-03-13 11:42:00,723 ERROR | Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.jsp.ImportTab_jsp] with root cause
java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.jsp.ImportTab_jsp
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
at org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:129)
at org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:58)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:151)
at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:189)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:410)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:380)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:328)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108)
at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365)
at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at com.comptel.catalog.support.filter.OperationClientRestFilter.doFilter(OperationClientRestFilter.java:86)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at com.comptel.catalog.support.filter.JwtSecurityChainFilter.doFilter(JwtSecurityChainFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
在我们的项目中,我们使用带有嵌入式
Springboot3.2.2
和Java17的tomcat10
。很多时候,我们在访问jsp页面时会超出预期,一旦出现此问题,该页面将无法访问,直到我们不重新启动应用程序为止,这个问题偶尔会来。
我尝试过的:
javax.servlet-api-4.0.1
和 jakarta.servlet-api-5.0.0
。这会产生任何问题吗?任何人都可以帮助如何重现此问题或如何解决此问题?为什么有时某个特定的 JSP 会抛出
500(java.lang.ClassNotFoundException)
。
我已成功复制该问题。请观察如何复制它。 那么到底发生了什么?
1- 开始申请。
2-应用程序将在Linux中的tmp目录下创建一个tomcat目录
/tmp/tomcat.47003.2497552974163365448/work/Tomcat/localhost/ROOT/org/apache/jsp/
3- 默认情况下,它将编译并复制
Login_jsp.java
& Login_jsp.class
到上面的文件夹中。
4- 现在用户登录 UI( )。
5-它将编译并复制
Index_jsp.jav
a & Index_jsp.class
到上面的文件夹中。
让我们带着一个问题来理解这一点。
现在以这个场景为例,让我们试着理解这里发生了什么
1- 应用程序已启动并正在运行(可能会在今天开始或在几天、几周或几个月后运行) 2-所以tomcat创建了一个文件夹结构
/tmp/tomcat.47003.2497552974163365448/work/Tomcat/localhost/ROOT/org/apache/jsp/WEB_002dINF/jsp/
3- 默认情况下(Servlet 知道
login.jsp
是应用程序的入口点)编译并复制 Login_jsp.class
和 Login_jsp.java
到 jsp 文件夹下。
4-现在一些操作系统进程或 cron 作业或其他东西(不确定是谁在做这个)删除了
/tmp/tomcat.47003.2497552974163365448/work/Tomcat/localhost/ROOT/org/apache/jsp/WEB_002dINF/jsp/
5-现在,如果有人访问该应用程序,他将能够看到登录页面,因为它已编译并且 tomcat 还持有
Login.jsp
引用其他地方。但是登录后他将无法看到 Index.jsp
页面,因为在编译此 jsp 之前,/tmp/tomcat
目录已删除(通过任何过程或手动或其他方式)。
6- 因此登录后,用户将收到 500 错误
java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.jsp.Index_jsp
现在我们必须监控谁真正删除了
/tmp/tomcat
目录
或者
我们可以使用
server.tomcat.basedir
[Tomcat 基目录。如果未指定,则使用临时目录。]