spring-bootjsptomcatclasspath

java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.jsp.ImportTab_jsp


We are getting below exception

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)

In our Project we are using Springboot3.2.2 with embedded tomcat10 and Java17.Many times we are getting above expectations when accessing the jsp pages and once this issue come that page wont access upto the time we wont restart the application,this issue is coming occasionally .

What I've tried:

  1. Deleted the /tmp/Tomcat directory and checked but 500 error is not coming, All Jsp pages working fine without any issue.
  2. We are using javax.servlet-api-4.0.1 and jakarta.servlet-api-5.0.0. Will this create any issue.

Any one can please help how to reproduce this issue or how to fix this? Why sometime a particular JSP throwing 500(java.lang.ClassNotFoundException).


Solution

  • I have successfully replicated the issue. Kindly observe how it can be reproduced. So what exactly Happening ?

    1- Started Application.

    2- Application will create a tomcat directory under tmp directory in Linux

    /tmp/tomcat.47003.2497552974163365448/work/Tomcat/localhost/ROOT/org/apache/jsp/
    

    3- By default it will compile and copy Login_jsp.java & Login_jsp.class inside above folder.

    4- Now user Login into UI( ).

    5- It will compile and copy Index_jsp.java & Index_jsp.class inside above folder.

    Lets understand this with a issue .

    Now take this scenario as a example and lets try to understand what happened here

    1- Application was up and running(It may be started today or running from couple of days or week or months) 2- So tomcat created a folder structure

    /tmp/tomcat.47003.2497552974163365448/work/Tomcat/localhost/ROOT/org/apache/jsp/WEB_002dINF/jsp/
    

    3- By default(As Servlet know login.jsp is entry point of application) compiled and copied the Login_jsp.class and Login_jsp.java under jsp folder.

    4- Now some of the OS process OR cron job OR something else(Not sure who is doing this) deleted the

    /tmp/tomcat.47003.2497552974163365448/work/Tomcat/localhost/ROOT/org/apache/jsp/WEB_002dINF/jsp/
    

    5- Now if someone will access the application he will able to see login page ,because its compiled and tomcat holding Login.jsp reference some other place as well. But after Login he will not able to see the Index.jsp page because before it should compile this jsp, /tmp/tomcat directory deleted(By any process or manually or some other way) .

    6- Due to this after login ,user will get 500 error

    java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.jsp.Index_jsp

    Now we have to monitor who actually deleting /tmp/tomcat directory

    Or

    We can use server.tomcat.basedir [Tomcat base directory. If not specified, a temporary directory is used.]