https://bz.apache.org/bugzilla/show_bug.cgi?id=69405

            Bug ID: 69405
           Summary: Vague error message: "A filter or servlet of the
                    current chain does not support asynchronous
                    operations"
           Product: Tomcat 9
           Version: 9.0.87
          Hardware: PC
                OS: Mac OS X 10.1
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: minf...@apache.org
  Target Milestone: -----

Production service suffers unexpected outage, an endpoint has started returning
the following exception to the client:

javax.ws.rs.ProcessingException: Attempt to suspend a connection of an
asynchronous request failed in the underlying container.
       
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:384)
       
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
        org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:256)
        org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
        org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
        org.glassfish.jersey.internal.Errors.process(Errors.java:292)
        org.glassfish.jersey.internal.Errors.process(Errors.java:274)
        org.glassfish.jersey.internal.Errors.process(Errors.java:244)
       
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
       
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)
       
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)
       
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
       
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
       
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358)
       
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311)
       
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
        org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
       
org.apache.catalina.filters.RequestDumperFilter.doFilter(RequestDumperFilter.java:191)

The underlying exception logged to catalina.out is as follows:

18-Oct-2024 14:07:07.172 WARNING
[http-nio-/run/tomcat-xxx3-service-test/socket-exec-3]
org.glassfish.jersey.servlet.internal.ResponseWriter.suspend Attempt to put
servlet request into asynchronous mode has failed. Please check your servlet
configura
tion - all Servlet instances and Servlet filters involved in the request
processing must explicitly declare support for asynchronous request processing.
        java.lang.IllegalStateException: A filter or servlet of the current
chain does not support asynchronous operations.
                at
org.apache.catalina.connector.Request.startAsync(Request.java:1668)
                at
org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:742)
                at
org.glassfish.jersey.servlet.async.AsyncContextDelegateProviderImpl$ExtensionImpl.getAsyncContext(AsyncContextDelegateProviderImpl.java:89)
                at
org.glassfish.jersey.servlet.async.AsyncContextDelegateProviderImpl$ExtensionImpl.suspend(AsyncContextDelegateProviderImpl.java:73)
                at
org.glassfish.jersey.servlet.internal.ResponseWriter.suspend(ResponseWriter.java:101)
                at
org.glassfish.jersey.server.ServerRuntime$AsyncResponder.suspend(ServerRuntime.java:847)
                at
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:383)
                at
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
                at
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:256)
                at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
                at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
                at
org.glassfish.jersey.internal.Errors.process(Errors.java:292)
                at
org.glassfish.jersey.internal.Errors.process(Errors.java:274)
                at
org.glassfish.jersey.internal.Errors.process(Errors.java:244)
                at
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
                at
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)
                at
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)
                at
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
                at
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
                at
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358)
                at
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311)
                at
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
                at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:210)
                at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
                at
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
                at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:179)
                at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
                at
org.apache.catalina.filters.RequestDumperFilter.doFilter(RequestDumperFilter.java:191)
                at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:179)
                at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
                at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168)
                at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
                at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:596)
                at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
                at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
                at
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:670)
                at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
                at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
                at
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
                at
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
                at
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928)
                at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1786)
                at
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
                at
org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
                at
org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
                at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
                at java.base/java.lang.Thread.run(Thread.java:840)


Headline is that the server has thrown the exception from within Tomcat itself.

Searching for the string "A filter or servlet of the current chain does not
support asynchronous operations" leads us to the Tomcat constant
"request.asyncNotSupported", which in turn leads us to this code:

https://github.com/apache/tomcat/blob/fe3f74debf0ae971918771a4399c8ba4eb3b6c54/java/org/apache/catalina/connector/Request.java#L1459

    public AsyncContext startAsync(ServletRequest request, ServletResponse
response) {
        if (!isAsyncSupported()) {
            IllegalStateException ise = new
IllegalStateException(sm.getString("request.asyncNotSupported"));
            log.warn(sm.getString("coyoteRequest.noAsync",
StringUtils.join(getNonAsyncClassNames())), ise);
            throw ise;
        }

        if (asyncContext == null) {
            asyncContext = new AsyncContextImpl(this);
        }

        asyncContext.setStarted(getContext(), request, response,
                request == getRequest() && response ==
getResponse().getResponse());
        asyncContext.setTimeout(getConnector().getAsyncTimeout());

        return asyncContext;
    }

What is happening is that the function isAsyncSupported() returns a boolean
saying whether across the whole server async is not supported, but it gives no
clue as to how Tomcat reached this conclusion.

The end user (me) is left mystified as to what the cause is, or what to do to
fix it.

The error message needs to be updated to include the name of whatever part of
Tomcat that does not support async, so that it can be removed.

Going further down the rabbit hole, the function isAsyncSupported() returns the
value of a boolean variable called asyncSupported. I cannot find where
asyncSupported is set, it leads me to what looks like a series of configuration
options in a series of objects that is too opaque to see.

What should happen is that if async is not supported, the name(s) of the
element(s) that does not support async needs to be remembered and added to the
message.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to