spring-projects / spring-projects/spring-security

"setAttribute is not supported" error from PathPatternRequestMatcher in child context with Spring Security 6.5.7

Open
#19,219 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage type: bug
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Describe the bug

We are attempting to update an application from Java EE8 to EE9, including moving from Spring Security 5 to 6.5.7, and replacing AntPathRequestMatcher with PathPatternRequestMatcher. However, this results in java.lang.UnsupportedOperationException: public abstract void jakarta.servlet.ServletRequest.setAttribute(java.lang.String,java.lang.Object) is not supported when the matcher is used.

jakarta.servlet.ServletException: Request processing failed: java.lang.UnsupportedOperationException: public abstract void jakarta.servlet.ServletRequest.setAttribute(java.lang.String,java.lang.Object) is not supported
    at org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet.java:1022)
    at org.springframework.web.servlet.FrameworkServlet.doGet (FrameworkServlet.java:903)
    at jakarta.servlet.http.HttpServlet.service (HttpServlet.java:527)
    at org.springframework.web.servlet.FrameworkServlet.service (FrameworkServlet.java:885)
    at jakarta.servlet.http.HttpServlet.service (HttpServlet.java:614)
    at org.eclipse.jetty.ee10.servlet.ServletHolder$NotAsync.service (ServletHolder.java:1397)
    at org.eclipse.jetty.ee10.servlet.ServletHolder.handle (ServletHolder.java:754)
    at org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter (ServletHandler.java:1622)
    at org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle (ServletHandler.java:1556)
    at org.eclipse.jetty.ee10.servlet.Dispatcher.forward (Dispatcher.java:135)
    at org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequestDispatcher.forward (HeaderWriterFilter.java:170)
    at org.springframework.security.web.access.AccessDeniedHandlerImpl.handle (AccessDeniedHandlerImpl.java:72)
    at org.springframework.security.web.access.ExceptionTranslationFilter.handleAccessDeniedException (ExceptionTranslationFilter.java:208)
    at org.springframework.security.web.access.ExceptionTranslationFilter.handleSpringSecurityException (ExceptionTranslationFilter.java:177)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter (ExceptionTranslationFilter.java:146)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter (ExceptionTranslationFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at au.com.citec.rads.web.auth.ForceChangePasswordFilter.doFilter (ForceChangePasswordFilter.java:53)
    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 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter (AbstractAuthenticationProcessingFilter.java:235)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter (AbstractAuthenticationProcessingFilter.java:229)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter (LogoutFilter.java:107)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter (LogoutFilter.java:93)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal (CsrfFilter.java:117)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter (HeaderWriterFilter.java:90)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal (HeaderWriterFilter.java:75)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter (SecurityContextHolderFilter.java:82)
    at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter (SecurityContextHolderFilter.java:69)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal (WebAsyncManagerIntegrationFilter.java:62)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal (DisableEncodeUrlFilter.java:42)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal (FilterChainProxy.java:233)
    at org.springframework.security.web.FilterChainProxy.doFilter (FilterChainProxy.java:191)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter (CompositeFilter.java:113)
    at org.springframework.web.filter.ServletRequestPathFilter.doFilter (ServletRequestPathFilter.java:52)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter (CompositeFilter.java:113)
    at org.springframework.web.filter.CompositeFilter.doFilter (CompositeFilter.java:74)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$CompositeFilterChainProxy.doFilter (WebSecurityConfiguration.java:319)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate (DelegatingFilterProxy.java:362)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter (DelegatingFilterProxy.java:278)
    at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter (FilterHolder.java:205)
    at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter (ServletHandler.java:1594)
    at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal (MultipartFilter.java:125)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:116)
    at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter (FilterHolder.java:208)
    at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter (ServletHandler.java:1594)
    at org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle (ServletHandler.java:1556)
    at org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch (ServletChannel.java:871)
    at org.eclipse.jetty.ee10.servlet.ServletChannel.handle (ServletChannel.java:449)
    at org.eclipse.jetty.ee10.servlet.ServletHandler.handle (ServletHandler.java:469)
    at org.eclipse.jetty.security.SecurityHandler.handle (SecurityHandler.java:546)
    at org.eclipse.jetty.ee10.servlet.SessionHandler.handle (SessionHandler.java:719)
    at org.eclipse.jetty.server.handler.ContextHandler.handle (ContextHandler.java:1250)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle (ContextHandlerCollection.java:148)
    at org.eclipse.jetty.server.Server.handle (Server.java:197)
    at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run (HttpChannelState.java:793)
    at org.eclipse.jetty.server.internal.HttpConnection.onFillable (HttpConnection.java:419)
    at org.eclipse.jetty.server.internal.HttpConnection$FillableCallback.succeeded (HttpConnection.java:1780)
    at org.eclipse.jetty.io.FillInterest.fillable (FillInterest.java:105)
    at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run (SelectableChannelEndPoint.java:54)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask (AdaptiveExecutionStrategy.java:492)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.epcRunTask (AdaptiveExecutionStrategy.java:428)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask (AdaptiveExecutionStrategy.java:401)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce (AdaptiveExecutionStrategy.java:255)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run (AdaptiveExecutionStrategy.java:204)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run (ReservedThreadExecutor.java:317)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob (QueuedThreadPool.java:1009)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob (QueuedThreadPool.java:1240)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run (QueuedThreadPool.java:1194)
    at java.lang.Thread.run (Thread.java:840)
Caused by: java.lang.UnsupportedOperationException: public abstract void jakarta.servlet.ServletRequest.setAttribute(java.lang.String,java.lang.Object) is not supported
    at org.springframework.security.web.FilterInvocation$UnsupportedOperationExceptionInvocationHandler.invoke (FilterInvocation.java:331)
    at jdk.proxy5.$Proxy218.setAttribute (Unknown Source)
    at jakarta.servlet.ServletRequestWrapper.setAttribute (ServletRequestWrapper.java:238)
    at org.springframework.web.util.ServletRequestPathUtils.parseAndCache (ServletRequestPathUtils.java:71)
    at org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.getPathContainer (PathPatternRequestMatcher.java:119)
    at org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.matcher (PathPatternRequestMatcher.java:108)
    at org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.matches (PathPatternRequestMatcher.java:97)
    at org.springframework.security.web.util.matcher.OrRequestMatcher.matches (OrRequestMatcher.java:59)
    at org.springframework.security.web.DefaultSecurityFilterChain.matches (DefaultSecurityFilterChain.java:89)
    at org.springframework.security.web.util.matcher.RequestMatcher.matcher (RequestMatcher.java:48)
    at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.check (RequestMatcherDelegatingAuthorizationManager.java:83)
    at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.check (RequestMatcherDelegatingAuthorizationManager.java:50)
    at org.springframework.security.authorization.AuthorizationManager.authorize (AuthorizationManager.java:69)
    at org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.isAllowed (AuthorizationManagerWebInvocationPrivilegeEvaluator.java:60)
    at org.springframework.security.web.access.RequestMatcherDelegatingWebInvocationPrivilegeEvaluator.isAllowed (RequestMatcherDelegatingWebInvocationPrivilegeEvaluator.java:114)
    at org.springframework.security.taglibs.authz.AbstractAuthorizeTag.authorizeUsingUrlCheck (AbstractAuthorizeTag.java:149)
    at org.springframework.security.taglibs.authz.AbstractAuthorizeTag.authorize (AbstractAuthorizeTag.java:103)
    at org.springframework.security.taglibs.authz.JspAuthorizeTag.doStartTag (JspAuthorizeTag.java:70)
    at freemarker.ext.jakarta.jsp.TagTransformModel$TagWriter.onStart (TagTransformModel.java:322)
    at freemarker.core.Environment.visitAndTransform (Environment.java:509)
    at freemarker.core.UnifiedCall.accept (UnifiedCall.java:103)
    at freemarker.core.Environment.visit (Environment.java:380)
    at freemarker.core.Environment.visitAndTransform (Environment.java:511)
    at freemarker.core.UnifiedCall.accept (UnifiedCall.java:103)
    at freemarker.core.Environment.visit (Environment.java:380)
    at freemarker.core.Environment.visitAndTransform (Environment.java:511)
    at freemarker.core.UnifiedCall.accept (UnifiedCall.java:103)
    at freemarker.core.Environment.visit (Environment.java:380)
    at freemarker.core.Environment.invokeMacroOrFunctionCommonPart (Environment.java:886)
    at freemarker.core.Environment.invokeMacro (Environment.java:822)
    at freemarker.core.UnifiedCall.accept (UnifiedCall.java:83)
    at freemarker.core.Environment.visit (Environment.java:380)
    at freemarker.core.Environment.invokeNestedContent (Environment.java:630)
    at freemarker.core.BodyInstruction.accept (BodyInstruction.java:60)
    at freemarker.core.Environment.visit (Environment.java:380)
    at freemarker.core.Environment.invokeMacroOrFunctionCommonPart (Environment.java:886)
    at freemarker.core.Environment.invokeMacro (Environment.java:822)
    at freemarker.core.UnifiedCall.accept (UnifiedCall.java:83)
    at freemarker.core.Environment.visit (Environment.java:344)
    at freemarker.core.Environment.visit (Environment.java:350)
    at freemarker.core.Environment.process (Environment.java:323)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate (FreeMarkerView.java:447)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender (FreeMarkerView.java:351)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel (FreeMarkerView.java:302)
    at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel (AbstractTemplateView.java:181)
    at org.springframework.web.servlet.view.AbstractView.render (AbstractView.java:314)
    at org.springframework.web.servlet.DispatcherServlet.render (DispatcherServlet.java:1438)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult (DispatcherServlet.java:1168)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet.java:1106)
    at org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:979)
    at org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet.java:1014)
    at org.springframework.web.servlet.FrameworkServlet.doGet (FrameworkServlet.java:903)
    at jakarta.servlet.http.HttpServlet.service (HttpServlet.java:527)
    at org.springframework.web.servlet.FrameworkServlet.service (FrameworkServlet.java:885)
    at jakarta.servlet.http.HttpServlet.service (HttpServlet.java:614)
    at org.eclipse.jetty.ee10.servlet.ServletHolder$NotAsync.service (ServletHolder.java:1397)
    at org.eclipse.jetty.ee10.servlet.ServletHolder.handle (ServletHolder.java:754)
    at org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter (ServletHandler.java:1622)
    at org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle (ServletHandler.java:1556)
    at org.eclipse.jetty.ee10.servlet.Dispatcher.forward (Dispatcher.java:135)
    at org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequestDispatcher.forward (HeaderWriterFilter.java:170)
    at org.springframework.security.web.access.AccessDeniedHandlerImpl.handle (AccessDeniedHandlerImpl.java:72)
    at org.springframework.security.web.access.ExceptionTranslationFilter.handleAccessDeniedException (ExceptionTranslationFilter.java:208)
    at org.springframework.security.web.access.ExceptionTranslationFilter.handleSpringSecurityException (ExceptionTranslationFilter.java:177)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter (ExceptionTranslationFilter.java:146)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter (ExceptionTranslationFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at au.com.citec.rads.web.auth.ForceChangePasswordFilter.doFilter (ForceChangePasswordFilter.java:53)
    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 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter (AbstractAuthenticationProcessingFilter.java:235)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter (AbstractAuthenticationProcessingFilter.java:229)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter (LogoutFilter.java:107)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter (LogoutFilter.java:93)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal (CsrfFilter.java:117)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter (HeaderWriterFilter.java:90)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal (HeaderWriterFilter.java:75)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter (SecurityContextHolderFilter.java:82)
    at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter (SecurityContextHolderFilter.java:69)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal (WebAsyncManagerIntegrationFilter.java:62)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal (DisableEncodeUrlFilter.java:42)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:374)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal (FilterChainProxy.java:233)
    at org.springframework.security.web.FilterChainProxy.doFilter (FilterChainProxy.java:191)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter (CompositeFilter.java:113)
    at org.springframework.web.filter.ServletRequestPathFilter.doFilter (ServletRequestPathFilter.java:52)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter (CompositeFilter.java:113)
    at org.springframework.web.filter.CompositeFilter.doFilter (CompositeFilter.java:74)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$CompositeFilterChainProxy.doFilter (WebSecurityConfiguration.java:319)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate (DelegatingFilterProxy.java:362)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter (DelegatingFilterProxy.java:278)
    at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter (FilterHolder.java:205)
    at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter (ServletHandler.java:1594)
    at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal (MultipartFilter.java:125)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:116)
    at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter (FilterHolder.java:208)
    at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter (ServletHandler.java:1594)
    at org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle (ServletHandler.java:1556)
    at org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch (ServletChannel.java:871)
    at org.eclipse.jetty.ee10.servlet.ServletChannel.handle (ServletChannel.java:449)
    at org.eclipse.jetty.ee10.servlet.ServletHandler.handle (ServletHandler.java:469)
    at org.eclipse.jetty.security.SecurityHandler.handle (SecurityHandler.java:546)
    at org.eclipse.jetty.ee10.servlet.SessionHandler.handle (SessionHandler.java:719)
    at org.eclipse.jetty.server.handler.ContextHandler.handle (ContextHandler.java:1250)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle (ContextHandlerCollection.java:148)
    at org.eclipse.jetty.server.Server.handle (Server.java:197)
    at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run (HttpChannelState.java:793)
    at org.eclipse.jetty.server.internal.HttpConnection.onFillable (HttpConnection.java:419)
    at org.eclipse.jetty.server.internal.HttpConnection$FillableCallback.succeeded (HttpConnection.java:1780)
    at org.eclipse.jetty.io.FillInterest.fillable (FillInterest.java:105)
    at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run (SelectableChannelEndPoint.java:54)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask (AdaptiveExecutionStrategy.java:492)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.epcRunTask (AdaptiveExecutionStrategy.java:428)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask (AdaptiveExecutionStrategy.java:401)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce (AdaptiveExecutionStrategy.java:255)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run (AdaptiveExecutionStrategy.java:204)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run (ReservedThreadExecutor.java:317)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob (QueuedThreadPool.java:1009)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob (QueuedThreadPool.java:1240)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run (QueuedThreadPool

To Reproduce

Visit any page post-login.

Expected behavior

Pages should load normally

Sample

Our web application initializer is configured with:

@Override
public void onStartup(final ServletContext sc) {
    sc.setInitParameter("defaultHtmlEscape", "true");

    sc.addFilter("charsetFilter", new CharacterEncodingFilter("UTF-8", true))
        .addMappingForUrlPatterns(null, true, "/*");

    /*
     * Multipart resolution needs to come before Spring Security
     * so that CSRF tokens are visible.
     */
    sc.addFilter("springMultipartResolver", org.springframework.web.multipart.support.MultipartFilter.class)
        .addMappingForUrlPatterns(null, false, "/*");

    sc.addFilter("springSecurityFilterChain", org.springframework.web.filter.DelegatingFilterProxy.class)
        .addMappingForUrlPatterns(null, false, "/*");

    sc.addFilter("welcomePageFilter", au.com.citec.rads.web.filter.RedirectFilter.class)
        .addMappingForUrlPatterns(null, true, "/");

    sc.addFilter("clickjackFilter", org.owasp.esapi.filters.ClickjackFilter.class)
        .addMappingForUrlPatterns(null, true, "/*");

    AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
    root.register(SpringCoreConfig.class, SpringSecurityConfig.class);

    AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
    root.register(SpringCoreConfig.class, SpringSecurityConfig.class);

    AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
    dispatcherContext.register(SpringServletConfig.class);
    ServletRegistration.Dynamic servlet = sc.addServlet("rads", new DispatcherServlet(dispatcherContext));
    servlet.setLoadOnStartup(1);
    servlet.setMultipartConfig(
        new MultipartConfigElement("", 10485760L, 10485760L, 0)  // 10MB (10485760 bytes)
    );
    servlet.addMapping("/web/*");

    dispatcherContext = new AnnotationConfigWebApplicationContext();
    dispatcherContext.register(SpringRestConfig.class);
    servlet = sc.addServlet("restful", new DispatcherServlet(dispatcherContext));
    servlet.setLoadOnStartup(2);
    servlet.addMapping("/rest/*");

    dispatcherContext = new AnnotationConfigWebApplicationContext();
    dispatcherContext.register(SpringWebServiceConfig.class);
    servlet = sc.addServlet("rads-ws", new MessageDispatcherServlet(dispatcherContext));
    servlet.setLoadOnStartup(3);
    servlet.addMapping("/ws/*");

    sc.addListener(new ContextLoaderListener(root));
}

SpringCoreConfig.java merely defines general application beans like the data layer.

SpringSecurityConfig.java includes the relevant request matcher that triggers the exception:

@Bean
@Order(2)
public SecurityFilterChain servletFilterChain(HttpSecurity http) throws Exception {
    PathPatternRequestMatcher appPath = PathPatternRequestMatcher.withDefaults().basePath("/web");
    return http.addFilterAfter(forceChangePasswordFilter, AnonymousAuthenticationFilter.class)
        .formLogin(loginConfig -> loginConfig
            ...
        )
        .logout(logoutConfig -> logoutConfig
            ...
        )
        .exceptionHandling(exception -> exception.accessDeniedPage("/web/security/accessDenied"))
        .authorizeHttpRequests(authz -> authz
            .requestMatchers(appPath.matcher(("/security/login")).anonymous()
            ...
        )
        .build();

SpringServletConfig.java contains:

package au.com.citec.rads.config;

import java.lang.invoke.MethodHandles;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.Properties;

import au.com.citec.rads.ReferenceService;
import au.com.citec.rads.common.BillingFee;
import au.com.citec.rads.common.Money;
import au.com.citec.rads.domain.FinancialAdjustment;
import au.com.citec.rads.domain.MerchantFee;
import au.com.citec.rads.domain.Payment;
import au.com.citec.rads.domain.enumtype.RateType;
import au.com.citec.rads.domain.reference.Agency;
import au.com.citec.rads.domain.reference.BillingRuleApplication;
import au.com.citec.rads.domain.reference.BusinessArea;
import au.com.citec.rads.domain.reference.Channel;
import au.com.citec.rads.domain.reference.Service;
import au.com.citec.rads.domain.reference.SubChannel;
import au.com.citec.rads.web.controller.FileBrowserController;
import au.com.citec.rads.web.convert.*;
import au.com.citec.rads.web.customview.FreeMarkerCSVView;
import au.com.citec.rads.web.customview.FreeMarkerDownloadView;
import au.com.citec.rads.web.customview.FreeMarkerPDFView;
import au.com.citec.rads.web.customview.FreeMarkerTXTView;
import au.com.citec.rads.web.interceptor.HelpPageInterceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.springframework.web.servlet.ViewResolver;

@Configuration
@ComponentScan(
    basePackages = {"au.com.citec.rads.web", "au.com.citec.rads.rest"},
    excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION, value = org.springframework.ws.server.endpoint.annotation.Endpoint.class),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = FileBrowserController.class)
    }
)
@EnableWebMvc
@PropertySource({"classpath:environment.properties", "classpath:applicationConfig.properties"})
public class SpringServletConfig implements WebMvcConfigurer {

    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    @Value("file:${file.root.folder:failed}/interfaces")
    private Resource interfacesRoot;

    @Value("file:${archive.root.folder:failed}")
    private Resource archiveRoot;

    @Value("file:${file.root.folder:failed}/reports")
    private Resource reportsRoot;

    @Autowired
    private ReferenceService referenceService;

    @Autowired
    private HelpPageInterceptor helpPageInterceptor;

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatterForFieldType(BillingRuleApplication.class, new BillingRuleApplicationTypeFormatter());
        registry.addFormatterForFieldAnnotation(new RadsDateTimeFormatAnnotationFormatterFactory(new Jsr310DateTimeFormatAnnotationFormatterFactory()));
        registry.addFormatterForFieldType(Money.class, new MoneyFormatter());
        registry.addFormatterForFieldType(BillingFee.class, new BillingFeeFormatter());
        registry.addFormatterForFieldType(Payment.Discriminator.class, new PaymentDiscriminatorFormatter());
        registry.addFormatterForFieldType(MerchantFee.MerchantFeeType.class, new MerchantFeeTypeFormatter());
        registry.addFormatterForFieldType(RateType.class, new RateTypeFormatter());
        registry.addFormatterForFieldType(FinancialAdjustment.AdjustmentType.class, new FinancialAdjustmentTypeFormatter());
        registry.addFormatterForFieldType(Channel.class, new ChannelFormatter(referenceService));
        registry.addFormatterForFieldType(SubChannel.class, new SubChannelFormatter(referenceService));
        registry.addFormatterForFieldType(Agency.class, new AgencyFormatter(referenceService));
        registry.addFormatterForFieldType(Service.class, new ServiceFormatter(referenceService));
        registry.addFormatterForFieldType(BusinessArea.class, new BusinessAreaFormatter(referenceService));
        registry.addFormatterForFieldType(ZonedDateTime.class, new ZonedDateTimeFormatter());
        registry.addFormatterForFieldType(LocalDate.class, new LocalDateFormatter());
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(helpPageInterceptor);
    }

    @Bean
    public FreeMarkerConfigurer freemarkerConfig() {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setTemplateLoaderPaths("/WEB-INF/templates/", "classpath:/templates");
        Properties freemarkerSettings = new Properties(5);
        freemarkerSettings.setProperty("object_wrapper", "au.com.citec.rads.JDKTimeAwareObjectWrapper");
        freemarkerSettings.setProperty("locale", "en_GB");
        freemarkerSettings.setProperty("number_format", "0");
        freemarkerSettings.setProperty("date_format", "dd/MM/yyyy");
        freemarkerSettings.setProperty("datetime_format", "dd/MM/yyyy HH:mm:ss");
        configurer.setFreemarkerSettings(freemarkerSettings);
        return configurer;
    }

    @Bean
    public ViewResolver radsStandardViewResolver() {
        FreeMarkerViewResolver resolver = new FreeMarkerViewResolver("", ".ftl");
        resolver.setCache(true);
        resolver.setContentType(MediaType.TEXT_HTML_VALUE);
        resolver.setExposeSpringMacroHelpers(true);
        return resolver;
    }

    private FreeMarkerViewResolver makeViewResolver(FreeMarkerDownloadView view) {
        FreeMarkerViewResolver resolver = new FreeMarkerViewResolver("", view.getFileNameExtension() + ".ftl");
        resolver.setCache(true);
        resolver.setContentType(view.getContentType());
        resolver.setExposeSpringMacroHelpers(true);
        resolver.setViewClass(view.getClass());
        return resolver;
    }

    @Bean
    public ViewResolver pdfViewResolver() {
        return makeViewResolver(new FreeMarkerPDFView());
    }

    @Bean
    public ViewResolver csvViewResolver() {
        return makeViewResolver(new FreeMarkerCSVView());
    }

    @Bean
    public ViewResolver txtViewResolver() {
        return makeViewResolver(new FreeMarkerTXTView());
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.viewResolver(radsStandardViewResolver());
        registry.viewResolver(csvViewResolver());
        registry.viewResolver(pdfViewResolver());
        registry.viewResolver(txtViewResolver());
        registry.enableContentNegotiation(new MappingJackson2JsonView());
    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorParameter(true)
            .defaultContentType(MediaType.TEXT_HTML)
            .mediaType("pdf", MediaType.APPLICATION_PDF)
            .mediaType("csv", new MediaType("application", "csv"))
            .mediaType("json", MediaType.APPLICATION_JSON)
            .mediaType("html", MediaType.TEXT_HTML)
            .mediaType("txt", MediaType.TEXT_PLAIN);
    }

    @Bean
    public MultipartResolver multipartResolver() {
        return new StandardServletMultipartResolver();
    }

}

Note that if we register SpringServletConfig in the root context, then the error goes away. However, this causes it to clash with the /rest DispatcherServlet and apply unwanted content negotiation settings to it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with PathPatternRequestMatcher.java and trace its getPathContainer call into ServletRequestPathUtils.parseAndCache, then inspect FilterInvocation.java to understand the child-context request wrapper shown in the stack trace. Reproduce the failure with PathPatternRequestMatcher in a child context and establish the expected request-matching behavior. Done means the matcher no longer throws UnsupportedOperationException in that scenario and the regression is covered by a test.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.