これは、なにをしたくて書いたもの?
前に、Jakarta Servletの非同期処理について扱ってみました。
Jakarta Servletの非同期処理をWildFly 35、Apache Tomcat 10.1で試す - CLOVER🍀
この時はディスパッチに関しては試していなかったので、今回見てみようかなと思います。
今回はWildFly 35.0.0.1.FinalとApache Tomcat 10.1.0.36で確認します。
Jakarta Servletの非同期処理とディスパッチ
Jakarta Servletの仕様書で、非同期処理について書かれている箇所については前回まとめてみました。
Jakarta Servletの非同期処理をWildFly 35、Apache Tomcat 10.1で試す - CLOVER🍀
非同期処理を使っている時でも、AsyncContext#dispatch
でディスパッチを行えることが書かれています。
When asynchronous processing begins on the request, another thread or callback may either generate the response and call complete or dispatch the request so that it may run in the context of the container using the AsyncContext.dispatch method.
また、asyncSupported
がtrue
のServletからasyncSupported
がfalse
のServletへもディスパッチできるようです。
Dispatching from a servlet that has asyncSupported=true to one where asyncSupported is set to false is allowed. In this case, the response will be committed when the service method of the servlet that does not support async is exited, and it is the container’s responsibility to call complete on the AsyncContext so that any interested AsyncListener instances will be notified. The AsyncListener.
ServletRequest#startAsync
を呼び出す時には、それまでにasyncSupported
がfalse
のServletやフィルターがひとつでもあると
ダメだったんですけどね。ディスパッチ先ならOKのようです。
ディスパッチ先の同期Servletのservice
メソッドが終了すると、レスポンスはコミットされることには注意が必要ですが。
同期Servletから非同期Servletへのディスパッチは不正ですが、IllegalStateException
をスローするかどうかは
ServletRequest#startAsync
を呼び出すまで遅延します。このため、非同期Servletでも明示的に非同期処理を開始しなければ
同期Servletとしても機能できることを意味します。
Dispatching from a synchronous servlet to an asynchronous servlet would be illegal. However the decision of throwing an IllegalStateException is deferred to the point when the application calls startAsync. This would allow a servlet to either function as a synchronous or an asynchronous servlet.
1回の非同期サイクル(ServletRequest#startAsync
の呼び出し)ごとに最大1回の非同期ディスパッチを実行できます。
同じ非同期サイクル内でさらにディスパッチを行おうとするとIllegalStateException
が発生します。
There can be at most one asynchronous dispatch operation per asynchronous cycle, which is started by a call to one of the ServletRequest.startAsync methods. Any attempt to perform additional asynchronous dispatch operations within the same asynchronous cycle is illegal and will result in an IllegalStateException. If startAsync is subsequently called on the dispatched request, then any of the dispatch methods may be called with the same restriction as above.
ディスパッチ後のリクエストでは、上記制限のもとでさらにディスパッチを行うことができます。
非同期処理下でのJSPの利用はデフォルトではサポートされていないようで、どのような動作になるかはコンテナ次第だと
されています。
Async processing in JSP would not be supported by default as it is used for content generation and async processing would have to be done before the content generation. It is up to the container how to handle this case. Once all the async activities are done, a dispatch to the JSP page using the AsyncContext.dispatch can be used for generating content.
ディスパッチを行うAsyncContext#dispatch
には引数にパスを取るものと取らないものがあり、パスを指定する場合は
ServletContextからの相対パスになり/
から指定します。パスを指定しない場合は、もともとのリクエストと
同じパス(HttpServletRequest#getRequestURI
)に対してディスパッチされます。さらにServletContext
を指定して
別のWebアプリケーションにディスパッチすることもできます。
AsyncContext (Jakarta Servlet API documentation)
今回は、ディスパッチと同期・非同期Servletの組み合わせを確認してみたいと思います。
環境
今回の環境はこちら。
$ java --version openjdk 21.0.6 2025-01-21 OpenJDK Runtime Environment (build 21.0.6+7-Ubuntu-124.04.1) OpenJDK 64-Bit Server VM (build 21.0.6+7-Ubuntu-124.04.1, mixed mode, sharing) $ mvn --version Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 21.0.6, vendor: Ubuntu, runtime: /usr/lib/jvm/java-21-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "6.8.0-54-generic", arch: "amd64", family: "unix"
WildFlyは35.0.0.1.Final、Apache Tomcatは10.1.0.36を使います。
準備
まずはMavenプロジェクトの準備から。
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.littlewings</groupId> <artifactId>servlet-async-dispatch-example</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <maven.compiler.release>21</maven.compiler.release> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-bom</artifactId> <version>10.0.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.annotation</groupId> <artifactId>jakarta.annotation-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.16</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>2.0.16</version> <scope>runtime</scope> </dependency> </dependencies> <build> <finalName>ROOT</finalName> </build> <profiles> <profile> <id>wildfly</id> <activation> <activeByDefault>true</activeByDefault> </activation> <build> <plugins> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>5.1.2.Final</version> <executions> <execution> <id>package</id> <goals> <goal>package</goal> </goals> </execution> </executions> <configuration> <overwrite-provisioned-server>true</overwrite-provisioned-server> <discover-provisioning-info> <version>35.0.1.Final</version> <layers-for-jndi> <layer>ee-concurrency</layer> </layers-for-jndi> </discover-provisioning-info> </configuration> </plugin> </plugins> </build> </profile> <profile> <id>tomcat</id> <build> <plugins> <plugin> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven3-plugin</artifactId> <version>1.10.17</version> <configuration> <container> <containerId>tomcat10x</containerId> <zipUrlInstaller> <url>https://archive.apache.org/dist/tomcat/tomcat-10/v10.1.36/bin/apache-tomcat-10.1.36.tar.gz</url> </zipUrlInstaller> </container> </configuration> </plugin> </plugins> </build> </profile> </profiles> </project>
SLF4JはWildFly上でもApache Tomcat上でもログ出力を行えるようにするために使います。
WildFlyはWildFly Maven Pluginを使ってプロビジョニング、Apache TomcatはCodehaus Cargo Maven 3 Pluginを使って
ダウンロードします。
WildFlyではJakarta Concurrecyを使うのですが明示的にManagedExecutorService
は使わないので、レイヤーをlayers-for-jndi
で
引き込んでいます。
<configuration> <overwrite-provisioned-server>true</overwrite-provisioned-server> <discover-provisioning-info> <version>35.0.1.Final</version> <layers-for-jndi> <layer>ee-concurrency</layer> </layers-for-jndi> </discover-provisioning-info> </configuration>
デフォルトはWildFlyで、Apache Tomcatを使う時は-P tomcatでプロファイルを切り替えます。
WildFlyは以下のコマンドでプロビジョニングと起動を行います。
$ mvn wildfly:run
Apache Tomcatは以下のコマンドでパッケージングと起動を行います。
$ mvn -P tomcat package cargo:run
Jakarta Servletで同期・非同期Servletとディスパッチの組み合わせを確認する
ここから先は、ServletやJakarta Server Pages(以降JSP)、Filterを用意してディスパッチの組み合わせを確認していきます。
ざっくりと以下の組み合わせを試していきたいと思います。
同期Servletのパスは/sync/〜
で始め、非同期Servletのパスは/async/〜
で始めることにします。
厳密には、もう少しネストした組み合わせにもします。
ベースの作成
まずは基本となる同期・非同期ServletやJSP、Filterを作成します。それぞれWildFlyとApache Tomcatで確認していきます。
起動コマンドは以下を使っている前提にして、以降では省略します。
## WildFly $ mvn wildfly:run ## Apache Tomcat $ mvn -P tomcat package cargo:run
同期Servlet。
src/main/java/org/littlewings/servlet/async/SyncServlet.java
package org.littlewings.servlet.async; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebServlet("/sync/simple") public class SyncServlet extends HttpServlet { private Logger logger = LoggerFactory.getLogger(SyncServlet.class); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info("do get"); response.getWriter().println("Hello from Sync Servlet"); } }
JSP。
src/main/webapp/WEB-INF/hello.jsp
Hello from JSP!!
src/main/java/org/littlewings/servlet/async/SyncViewJspServlet.java
package org.littlewings.servlet.async; import jakarta.servlet.RequestDispatcher; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebServlet("/sync/jsp") public class SyncViewJspServlet extends HttpServlet { private Logger logger = LoggerFactory.getLogger(SyncViewJspServlet.class); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info("do get"); RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/hello.jsp"); dispatcher.forward(request, response); } }
同期Filter。
src/main/java/org/littlewings/servlet/async/SyncFilter.java
package org.littlewings.servlet.async; import jakarta.servlet.DispatcherType; import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import jakarta.servlet.annotation.WebFilter; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebFilter(value = "/sync/*", dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD}) public class SyncFilter implements Filter { private Logger logger = LoggerFactory.getLogger(SyncFilter.class); @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { logger.info("do filter / sync"); chain.doFilter(request, response); } }
同期Filterと非同期処理を組み合わせると動作しないのは前回確認しているので適用対象のパスを同期Servletに絞り、
ディスパッチの種類も非同期は含めていません。
非同期Servlet…にいく前に、非同期処理で使うスレッドプールを用意します。
Apache Tomcatを使うことも考えると、初期化やインジェクションなどができるように用意するのがするのが
めんどうだったので、ServletContextListener
を使ってServletContext
にスレッドプールを登録することにしました。
このスレッドプールは複数のServletから使います。
src/main/java/org/littlewings/servlet/async/ExecutorInitializer.java
package org.littlewings.servlet.async; import javax.naming.InitialContext; import javax.naming.NamingException; import jakarta.servlet.ServletContextEvent; import jakarta.servlet.ServletContextListener; import jakarta.servlet.annotation.WebListener; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @WebListener public class ExecutorInitializer implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent event) { ExecutorService executorService; try { // Jakarta Concurrency(WildFly) executorService = InitialContext.doLookup("java:comp/DefaultManagedExecutorService"); } catch (NamingException e) { // Tomcat executorService = Executors.newFixedThreadPool(10); } event.getServletContext().setAttribute("asyncWorker", executorService); } }
では、非同期Servlet。
src/main/java/org/littlewings/servlet/async/AsyncServlet.java
package org.littlewings.servlet.async; import jakarta.servlet.AsyncContext; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UncheckedIOException; import java.util.concurrent.ExecutorService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebServlet(value = "/async/simple", asyncSupported = true) public class AsyncServlet extends HttpServlet { private Logger logger = LoggerFactory.getLogger(AsyncServlet.class); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info("do get"); AsyncContext asyncContext = request.startAsync(request, response); ExecutorService executorService = (ExecutorService)request.getServletContext().getAttribute("asyncWorker"); executorService.submit(() -> { logger.info("do task"); try { HttpServletResponse res = (HttpServletResponse) asyncContext.getResponse(); res.getWriter().println("Hello from Async Servlet"); asyncContext.complete(); } catch (IOException e) { throw new UncheckedIOException(e); } }); } }
JSPは同期のものと同じものを使います。
src/main/java/org/littlewings/servlet/async/AsyncViewJspServlet.java
package org.littlewings.servlet.async; import jakarta.servlet.AsyncContext; import jakarta.servlet.RequestDispatcher; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UncheckedIOException; import java.util.concurrent.ExecutorService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebServlet(value = "/async/jsp", asyncSupported = true) public class AsyncViewJspServlet extends HttpServlet { private Logger logger = LoggerFactory.getLogger(AsyncViewJspServlet.class); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info("do get"); AsyncContext asyncContext = request.startAsync(); ExecutorService executorService = (ExecutorService)request.getServletContext().getAttribute("asyncWorker"); executorService.submit(() -> { logger.info("do task"); asyncContext.dispatch("/WEB-INF/hello.jsp"); }); } }
AsyncContext#dispatch
でディスパッチ先のパスを指定します。
asyncContext.dispatch("/WEB-INF/hello.jsp");
非同期をサポートするFilter。
src/main/java/org/littlewings/servlet/async/AsyncSupportedFilter.java
package org.littlewings.servlet.async; import jakarta.servlet.DispatcherType; import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import jakarta.servlet.annotation.WebFilter; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebFilter(value = "/*", asyncSupported = true, dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC}) public class AsyncSupportedFilter implements Filter { private Logger logger = LoggerFactory.getLogger(AsyncSupportedFilter.class); @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { logger.info("do filter / async supported"); chain.doFilter(request, response); } }
非同期をサポートするFilterは、すべてのパスに適用することにします。同期、非同期の両方で使えるはずなので。
DispatcherType
もASYNC
を加えておきました。
このセットでまずは確認。
同期Servlet。
## WildFly $ curl localhost:8080/sync/simple Hello from Sync Servlet ## Apache Tomcat $ curl localhost:8080/sync/simple Hello from Sync Servlet
ログ。
## WildFly 20:20:47,812 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:20:47,812 INFO [org.littlewings.servlet.async.SyncFilter] (default task-1) do filter / sync 20:20:47,813 INFO [org.littlewings.servlet.async.SyncServlet] (default task-1) do get ## Apache Tomcat [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.SyncFilter - do filter / sync [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.SyncServlet - do get
## WildFly $ curl localhost:8080/sync/jsp Hello from JSP!! ## Apache Tomcat $ curl localhost:8080/sync/jsp Hello from JSP!!
ログ。
## WildFly 20:21:25,066 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:21:25,066 INFO [org.littlewings.servlet.async.SyncFilter] (default task-1) do filter / sync 20:21:25,067 INFO [org.littlewings.servlet.async.SyncViewJspServlet] (default task-1) do get 20:21:25,067 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported ## Apache Tomcat [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncFilter - do filter / sync [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncViewJspServlet - do get [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported
非同期Servlet。
## WildFly $ curl localhost:8080/async/simple Hello from Async Servlet ## Apache Tomcat $ curl localhost:8080/async/simple Hello from Async Servlet
ログ。
## WildFly 20:22:45,886 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:22:45,886 INFO [org.littlewings.servlet.async.AsyncServlet] (default task-1) do get 20:22:45,888 INFO [org.littlewings.servlet.async.AsyncServlet] (EE-ManagedExecutorService-default-Thread-3) do task ## Apache Tomcat [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.AsyncServlet - do get [INFO] [pool-1-thread-1] INFO org.littlewings.servlet.async.AsyncServlet - do task
## WildFly $ curl localhost:8080/async/jsp Hello from JSP!! ## Apache Tomcat $ curl localhost:8080/async/jsp Hello from JSP!!
ログ。
## WildFly 20:23:40,577 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:23:40,578 INFO [org.littlewings.servlet.async.AsyncViewJspServlet] (default task-1) do get 20:23:40,579 INFO [org.littlewings.servlet.async.AsyncViewJspServlet] (EE-ManagedExecutorService-default-Thread-5) do task 20:23:40,582 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported ## Apache Tomcat [INFO] [http-nio-8080-exec-7] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-7] INFO org.littlewings.servlet.async.AsyncViewJspServlet - do get [INFO] [pool-1-thread-2] INFO org.littlewings.servlet.async.AsyncViewJspServlet - do task [INFO] [http-nio-8080-exec-8] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported
特になにも設定していませんが、JSPは非同期Servletからディスパッチしても動くんですね。
ちなみに、Jakarta Server Pagesの仕様書には特にasyncについては書かれていませんでした。
またログをよく見ると気づきますが、JSPにディスパッチ後のフィルターはHTTPリクエストを処理するスレッドで
動いています。
Servletの前にディスパッチするServletを置く
次は、これらのServletの前にパスに応じてディスパッチするServletを用意してみます。
同期Servlet、非同期Servletにディスパッチする同期Servlet。
src/main/java/org/littlewings/servlet/async/SyncDispatchServlet.java
package org.littlewings.servlet.async; import jakarta.servlet.RequestDispatcher; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebServlet("/sync/dispatch/*") public class SyncDispatchServlet extends HttpServlet { private Logger logger = LoggerFactory.getLogger(SyncDispatchServlet.class); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String nextPath = switch (request.getPathInfo()) { case "/simple" -> "/sync/simple"; case "/jsp" -> "/sync/jsp"; case "/async/simple" -> "/async/simple"; case "/async/jsp" -> "/async/jsp"; default -> throw new IllegalArgumentException("not found"); }; logger.info("dispatch from access path = {}{}, next -> {}", request.getServletPath(), request.getPathInfo(), nextPath); RequestDispatcher dispatcher = request.getRequestDispatcher(nextPath); dispatcher.forward(request, response); } }
/async
付きのパスだと、非同期Servletにディスパッチするようにしています。ここで使うのはRequestDispatcher
です。
同期Servlet、非同期Servletにディスパッチする非同期Servlet。
src/main/java/org/littlewings/servlet/async/AsyncDispatchServlet.java
package org.littlewings.servlet.async; import jakarta.servlet.AsyncContext; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.concurrent.ExecutorService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebServlet(value = "/async/dispatch/*", asyncSupported = true) public class AsyncDispatchServlet extends HttpServlet { private Logger logger = LoggerFactory.getLogger(AsyncDispatchServlet.class); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info("do get"); AsyncContext asyncContext = request.startAsync(); ExecutorService executorService = (ExecutorService) request.getServletContext().getAttribute("asyncWorker"); executorService.submit(() -> { HttpServletRequest req = (HttpServletRequest) asyncContext.getRequest(); String nextPath = switch (req.getPathInfo()) { case "/sync/simple" -> "/sync/simple"; case "/sync/jsp" -> "/sync/jsp"; case "/simple" -> "/async/simple"; case "/jsp" -> "/async/jsp"; default -> throw new IllegalArgumentException("not found"); }; logger.info("dispatch from access path = {}{}, next -> {}", req.getServletPath(), req.getPathInfo(), nextPath); asyncContext.dispatch(nextPath); }); } }
こちらは、/sync
付きのパスだと同期Servletにディスパッチします。ここで使うのはAsyncContext#dispatch
です。
確認してみましょう。
同期Servetからのディスパッチ。
## WildFly ### 同期Serlvetへ $ curl -i localhost:8080/sync/dispatch/simple HTTP/1.1 200 OK Connection: keep-alive Content-Length: 25 Date: Sun, 02 Mar 2025 11:38:24 GMT Hello from Sync Servlet ### 同期Serlvet+JSPへ $ curl -i localhost:8080/sync/dispatch/jsp HTTP/1.1 200 OK Connection: keep-alive X-Powered-By: JSP/3.1 Set-Cookie: JSESSIONID=Dmt0yczxveGVZMkr3imJC7nOSw0GuBa3kh0iiSuS.ikaruga; path=/ Content-Type: text/html;charset=ISO-8859-1 Content-Length: 17 Date: Sun, 02 Mar 2025 11:39:24 GMT Hello from JSP!! ### 非同期Serlvetへ $ curl -i localhost:8080/sync/dispatch/async/simple HTTP/1.1 500 Internal Server Error Connection: keep-alive Content-Type: text/html;charset=UTF-8 Content-Length: 15494 Date: Sun, 02 Mar 2025 11:39:51 GMT <html><head><title>ERROR</title><style> body { 〜省略〜 ### 非同期Serlvet+JSPへ $ curl -i localhost:8080/sync/dispatch/async/jsp HTTP/1.1 500 Internal Server Error Connection: keep-alive Content-Type: text/html;charset=UTF-8 Content-Length: 15505 Date: Sun, 02 Mar 2025 11:41:03 GMT <html><head><title>ERROR</title><style> body { ## Apache Tomcat ### 同期Serlvetへ $ curl -i localhost:8080/sync/dispatch/simple HTTP/1.1 200 Content-Length: 24 Date: Sun, 02 Mar 2025 11:42:20 GMT Hello from Sync Servlet ### 同期Serlvet+JSPへ $ curl -i localhost:8080/sync/dispatch/jsp HTTP/1.1 200 Set-Cookie: JSESSIONID=C880BF89D731A130F9182FAA6D65632A; Path=/; HttpOnly Content-Type: text/html;charset=UTF-8 Content-Length: 17 Date: Sun, 02 Mar 2025 11:42:49 GMT Hello from JSP!! ### 非同期Serlvetへ $ curl -i localhost:8080/sync/dispatch/async/simple HTTP/1.1 500 Content-Type: text/html;charset=utf-8 Content-Language: ja Content-Length: 2198 Date: Sun, 02 Mar 2025 11:43:20 GMT Connection: close <!doctype html><html lang="ja"><head><title>HTTPステータス 500 – Internal Server Error</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTPステータス 500 – Internal Server Error</h1><hr class="line" /><p><b>タイプ</b> 例外報告</p><p><b>メッセージ</b> 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。</p><p><b>説明</b> サーバーは予期しない条件に遭遇しました。それはリクエストの実行を妨げます。</p><p><b>例 外</b></p><pre>java.lang.IllegalStateException: 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。 〜省略〜 ### 非同期Serlvet+JSPへ $ curl -i localhost:8080/sync/dispatch/async/jsp HTTP/1.1 500 Content-Type: text/html;charset=utf-8 Content-Language: ja Content-Length: 2281 Date: Sun, 02 Mar 2025 11:44:30 GMT Connection: close <!doctype html><html lang="ja"><head><title>HTTPステータス 500 – Internal Server Error</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTPステータス 500 – Internal Server Error</h1><hr class="line" /><p><b>タイプ</b> 例外報告</p><p><b>メッセージ</b> 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。</p><p><b>説明</b> サーバーは予期しない条件に遭遇しました。それはリクエストの実行を妨げます。</p><p><b>例 外</b></p><pre>java.lang.IllegalStateException: 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。 〜省略〜
というわけで、同期Servletから非同期Servletへのディスパッチはしっかりエラーになりました。
ログを見てみましょう。
## WildFly ### 同期Serlvetへ 20:38:24,887 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:38:24,887 INFO [org.littlewings.servlet.async.SyncFilter] (default task-1) do filter / sync 20:38:24,888 INFO [org.littlewings.servlet.async.SyncDispatchServlet] (default task-1) dispatch from access path = /sync/dispatch/simple, next -> /sync/simple 20:38:24,890 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:38:24,890 INFO [org.littlewings.servlet.async.SyncFilter] (default task-1) do filter / sync 20:38:24,890 INFO [org.littlewings.servlet.async.SyncServlet] (default task-1) do get ### 同期Serlvet+JSPへ 20:39:24,104 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:39:24,104 INFO [org.littlewings.servlet.async.SyncFilter] (default task-1) do filter / sync 20:39:24,105 INFO [org.littlewings.servlet.async.SyncDispatchServlet] (default task-1) dispatch from access path = /sync/dispatch/jsp, next -> /sync/jsp 20:39:24,105 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:39:24,106 INFO [org.littlewings.servlet.async.SyncFilter] (default task-1) do filter / sync 20:39:24,106 INFO [org.littlewings.servlet.async.SyncViewJspServlet] (default task-1) do get 20:39:24,116 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported ### 非同期Serlvetへ 20:39:51,503 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:39:51,503 INFO [org.littlewings.servlet.async.SyncFilter] (default task-1) do filter / sync 20:39:51,503 INFO [org.littlewings.servlet.async.SyncDispatchServlet] (default task-1) dispatch from access path = /sync/dispatch/async/simple, next -> /async/simple 20:39:51,504 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:39:51,504 INFO [org.littlewings.servlet.async.AsyncServlet] (default task-1) do get 20:39:51,507 ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /async/simple: java.lang.RuntimeException: java.lang.IllegalStateException: UT010026: Async is not supported for this request, as not all filters or Servlets were marked as supporting async at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:211) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.RequestDispatcherImpl.forwardImplSetup(RequestDispatcherImpl.java:137) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:100) at deployment.ROOT.war//org.littlewings.servlet.async.SyncDispatchServlet.doGet(SyncDispatchServlet.java:31) at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527) at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at deployment.ROOT.war//org.littlewings.servlet.async.SyncFilter.doFilter(SyncFilter.java:22) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at deployment.ROOT.war//org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at org.wildfly.security.elytron-web.undertow-server@4.1.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.lambda$handleRequest$1(ElytronRunAsHandler.java:68) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.FlexibleIdentityAssociation.runAsFunctionEx(FlexibleIdentityAssociation.java:103) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAsFunctionEx(Scoped.java:161) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:73) at org.wildfly.security.elytron-web.undertow-server@4.1.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.handleRequest(ElytronRunAsHandler.java:67) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.core@2.3.18.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.core@2.3.18.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at org.wildfly.security.elytron-web.undertow-server-servlet@4.1.0.Final//org.wildfly.elytron.web.undertow.server.servlet.CleanUpHandler.handleRequest(CleanUpHandler.java:38) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at org.wildfly.extension.undertow@35.0.1.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:44) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at org.wildfly.extension.undertow@35.0.1.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:51) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at org.wildfly.extension.undertow@35.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1421) at org.wildfly.extension.undertow@35.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1421) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101) at io.undertow.core@2.3.18.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:395) at io.undertow.core@2.3.18.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:861) at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377) at org.jboss.xnio@3.8.16.Final//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282) at java.base/java.lang.Thread.run(Thread.java:1583) Caused by: java.lang.IllegalStateException: UT010026: Async is not supported for this request, as not all filters or Servlets were marked as supporting async at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.HttpServletRequestImpl.startAsync(HttpServletRequestImpl.java:1096) at deployment.ROOT.war//org.littlewings.servlet.async.AsyncServlet.doGet(AsyncServlet.java:23) at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527) at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at deployment.ROOT.war//org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at org.wildfly.security.elytron-web.undertow-server@4.1.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.lambda$handleRequest$1(ElytronRunAsHandler.java:68) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.FlexibleIdentityAssociation.runAsFunctionEx(FlexibleIdentityAssociation.java:103) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAsFunctionEx(Scoped.java:161) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:73) at org.wildfly.security.elytron-web.undertow-server@4.1.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.handleRequest(ElytronRunAsHandler.java:67) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:258) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchToPath(ServletInitialHandler.java:183) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:189) ... 53 more ### 非同期Serlvet+JSPへ 20:41:03,057 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:41:03,058 INFO [org.littlewings.servlet.async.SyncFilter] (default task-1) do filter / sync 20:41:03,058 INFO [org.littlewings.servlet.async.SyncDispatchServlet] (default task-1) dispatch from access path = /sync/dispatch/async/jsp, next -> /async/jsp 20:41:03,059 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:41:03,060 INFO [org.littlewings.servlet.async.AsyncViewJspServlet] (default task-1) do get 20:41:03,060 ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /async/jsp: java.lang.RuntimeException: java.lang.IllegalStateException: UT010026: Async is not supported for this request, as not all filters or Servlets were marked as supporting async at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:211) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.RequestDispatcherImpl.forwardImplSetup(RequestDispatcherImpl.java:137) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:100) at deployment.ROOT.war//org.littlewings.servlet.async.SyncDispatchServlet.doGet(SyncDispatchServlet.java:31) at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527) at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at deployment.ROOT.war//org.littlewings.servlet.async.SyncFilter.doFilter(SyncFilter.java:22) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at deployment.ROOT.war//org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at org.wildfly.security.elytron-web.undertow-server@4.1.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.lambda$handleRequest$1(ElytronRunAsHandler.java:68) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.FlexibleIdentityAssociation.runAsFunctionEx(FlexibleIdentityAssociation.java:103) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAsFunctionEx(Scoped.java:161) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:73) at org.wildfly.security.elytron-web.undertow-server@4.1.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.handleRequest(ElytronRunAsHandler.java:67) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.core@2.3.18.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.core@2.3.18.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at org.wildfly.security.elytron-web.undertow-server-servlet@4.1.0.Final//org.wildfly.elytron.web.undertow.server.servlet.CleanUpHandler.handleRequest(CleanUpHandler.java:38) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at org.wildfly.extension.undertow@35.0.1.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:44) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at org.wildfly.extension.undertow@35.0.1.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:51) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at org.wildfly.extension.undertow@35.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1421) at org.wildfly.extension.undertow@35.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1421) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101) at io.undertow.core@2.3.18.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:395) at io.undertow.core@2.3.18.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:861) at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377) at org.jboss.xnio@3.8.16.Final//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282) at java.base/java.lang.Thread.run(Thread.java:1583) Caused by: java.lang.IllegalStateException: UT010026: Async is not supported for this request, as not all filters or Servlets were marked as supporting async at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.HttpServletRequestImpl.startAsync(HttpServletRequestImpl.java:1070) at deployment.ROOT.war//org.littlewings.servlet.async.AsyncViewJspServlet.doGet(AsyncViewJspServlet.java:24) at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527) at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at deployment.ROOT.war//org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at org.wildfly.security.elytron-web.undertow-server@4.1.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.lambda$handleRequest$1(ElytronRunAsHandler.java:68) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.FlexibleIdentityAssociation.runAsFunctionEx(FlexibleIdentityAssociation.java:103) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAsFunctionEx(Scoped.java:161) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:73) at org.wildfly.security.elytron-web.undertow-server@4.1.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.handleRequest(ElytronRunAsHandler.java:67) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.core@2.3.18.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:258) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchToPath(ServletInitialHandler.java:183) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:189) ... 53 more ## Apache Tomcat ### 同期Serlvetへ [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.SyncFilter - do filter / sync [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.SyncDispatchServlet - dispatch from access path = /sync/dispatch/simple, next -> /sync/simple [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.SyncFilter - do filter / sync [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.SyncServlet - do get ### 同期Serlvet+JSPへ [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncFilter - do filter / sync [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncDispatchServlet - dispatch from access path = /sync/dispatch/jsp, next -> /sync/jsp [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncFilter - do filter / sync [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncViewJspServlet - do get [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported ### 非同期Serlvetへ [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncFilter - do filter / sync [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncDispatchServlet - dispatch from access path = /sync/dispatch/jsp, next -> /sync/jsp [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncFilter - do filter / sync [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncViewJspServlet - do get [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.SyncFilter - do filter / sync [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.SyncDispatchServlet - dispatch from access path = /sync/dispatch/async/simple, next -> /async/simple [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.AsyncServlet - do get [INFO] 3月 02, 2025 8:43:20 午後 org.apache.catalina.connector.Request startAsync [INFO] 警告: 処理チェーン内の次のクラスが非同期をサポートしていないため、非同期を開始できません [org.littlewings.servlet.async.SyncDispatchServlet,org.littlewings.servlet.async.SyncFilter] [INFO] java.lang.IllegalStateException: 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。 [INFO] at org.apache.catalina.connector.Request.startAsync(Request.java:1510) [INFO] at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:720) [INFO] at jakarta.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:358) [INFO] at org.littlewings.servlet.async.AsyncServlet.doGet(AsyncServlet.java:23) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:633) [INFO] at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:409) [INFO] at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:331) [INFO] at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:268) [INFO] at org.littlewings.servlet.async.SyncDispatchServlet.doGet(SyncDispatchServlet.java:31) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.SyncFilter.doFilter(SyncFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) [INFO] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) [INFO] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) [INFO] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) [INFO] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) [INFO] at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) [INFO] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [INFO] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [INFO] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) [INFO] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) [INFO] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) [INFO] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) [INFO] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [INFO] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) [INFO] at java.base/java.lang.Thread.run(Thread.java:1583) [INFO] [INFO] 3月 02, 2025 8:43:20 午後 org.apache.catalina.core.ApplicationDispatcher invoke [INFO] 重大: サーブレット [org.littlewings.servlet.async.AsyncServlet] のServlet.service()が例外を投げました [INFO] java.lang.IllegalStateException: 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。 [INFO] at org.apache.catalina.connector.Request.startAsync(Request.java:1510) [INFO] at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:720) [INFO] at jakarta.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:358) [INFO] at org.littlewings.servlet.async.AsyncServlet.doGet(AsyncServlet.java:23) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:633) [INFO] at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:409) [INFO] at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:331) [INFO] at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:268) [INFO] at org.littlewings.servlet.async.SyncDispatchServlet.doGet(SyncDispatchServlet.java:31) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.SyncFilter.doFilter(SyncFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) [INFO] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) [INFO] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) [INFO] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) [INFO] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) [INFO] at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) [INFO] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [INFO] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [INFO] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) [INFO] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) [INFO] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) [INFO] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) [INFO] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [INFO] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) [INFO] at java.base/java.lang.Thread.run(Thread.java:1583) [INFO] [INFO] 3月 02, 2025 8:43:20 午後 org.apache.catalina.core.StandardWrapperValve invoke [INFO] 重大: サーブレット [org.littlewings.servlet.async.SyncDispatchServlet] のServlet.service()が例外を投げました [INFO] java.lang.IllegalStateException: 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。 [INFO] at org.apache.catalina.connector.Request.startAsync(Request.java:1510) [INFO] at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:720) [INFO] at jakarta.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:358) [INFO] at org.littlewings.servlet.async.AsyncServlet.doGet(AsyncServlet.java:23) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:633) [INFO] at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:409) [INFO] at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:331) [INFO] at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:268) [INFO] at org.littlewings.servlet.async.SyncDispatchServlet.doGet(SyncDispatchServlet.java:31) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.SyncFilter.doFilter(SyncFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) [INFO] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) [INFO] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) [INFO] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) [INFO] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) [INFO] at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) [INFO] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [INFO] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [INFO] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) [INFO] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) [INFO] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) [INFO] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) [INFO] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [INFO] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) [INFO] at java.base/java.lang.Thread.run(Thread.java:1583) [INFO] ### 非同期Serlvet+JSPへ [INFO] [http-nio-8080-exec-6] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-6] INFO org.littlewings.servlet.async.SyncFilter - do filter / sync [INFO] [http-nio-8080-exec-6] INFO org.littlewings.servlet.async.SyncDispatchServlet - dispatch from access path = /sync/dispatch/async/jsp, next -> /async/jsp [INFO] [http-nio-8080-exec-6] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-6] INFO org.littlewings.servlet.async.AsyncViewJspServlet - do get [INFO] 3月 02, 2025 8:44:30 午後 org.apache.catalina.connector.Request startAsync [INFO] 警告: 処理チェーン内の次のクラスが非同期をサポートしていないため、非同期を開始できません [org.littlewings.servlet.async.SyncDispatchServlet,org.littlewings.servlet.async.SyncFilter] [INFO] java.lang.IllegalStateException: 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。 [INFO] at org.apache.catalina.connector.Request.startAsync(Request.java:1510) [INFO] at org.apache.catalina.connector.Request.startAsync(Request.java:1504) [INFO] at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:713) [INFO] at jakarta.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:341) [INFO] at org.littlewings.servlet.async.AsyncViewJspServlet.doGet(AsyncViewJspServlet.java:24) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:633) [INFO] at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:409) [INFO] at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:331) [INFO] at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:268) [INFO] at org.littlewings.servlet.async.SyncDispatchServlet.doGet(SyncDispatchServlet.java:31) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.SyncFilter.doFilter(SyncFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) [INFO] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) [INFO] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) [INFO] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) [INFO] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) [INFO] at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) [INFO] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [INFO] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [INFO] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) [INFO] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) [INFO] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) [INFO] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) [INFO] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [INFO] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) [INFO] at java.base/java.lang.Thread.run(Thread.java:1583) [INFO] [INFO] 3月 02, 2025 8:44:30 午後 org.apache.catalina.core.ApplicationDispatcher invoke [INFO] 重大: サーブレット [org.littlewings.servlet.async.AsyncViewJspServlet] のServlet.service()が例外を投げました [INFO] java.lang.IllegalStateException: 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。 [INFO] at org.apache.catalina.connector.Request.startAsync(Request.java:1510) [INFO] at org.apache.catalina.connector.Request.startAsync(Request.java:1504) [INFO] at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:713) [INFO] at jakarta.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:341) [INFO] at org.littlewings.servlet.async.AsyncViewJspServlet.doGet(AsyncViewJspServlet.java:24) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:633) [INFO] at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:409) [INFO] at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:331) [INFO] at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:268) [INFO] at org.littlewings.servlet.async.SyncDispatchServlet.doGet(SyncDispatchServlet.java:31) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.SyncFilter.doFilter(SyncFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) [INFO] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) [INFO] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) [INFO] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) [INFO] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) [INFO] at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) [INFO] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [INFO] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [INFO] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) [INFO] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) [INFO] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) [INFO] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) [INFO] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [INFO] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) [INFO] at java.base/java.lang.Thread.run(Thread.java:1583) [INFO] [INFO] 3月 02, 2025 8:44:30 午後 org.apache.catalina.core.StandardWrapperValve invoke [INFO] 重大: サーブレット [org.littlewings.servlet.async.SyncDispatchServlet] のServlet.service()が例外を投げました [INFO] java.lang.IllegalStateException: 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。 [INFO] at org.apache.catalina.connector.Request.startAsync(Request.java:1510) [INFO] at org.apache.catalina.connector.Request.startAsync(Request.java:1504) [INFO] at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:713) [INFO] at jakarta.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:341) [INFO] at org.littlewings.servlet.async.AsyncViewJspServlet.doGet(AsyncViewJspServlet.java:24) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:633) [INFO] at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:409) [INFO] at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:331) [INFO] at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:268) [INFO] at org.littlewings.servlet.async.SyncDispatchServlet.doGet(SyncDispatchServlet.java:31) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) [INFO] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.SyncFilter.doFilter(SyncFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.littlewings.servlet.async.AsyncSupportedFilter.doFilter(AsyncSupportedFilter.java:22) [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) [INFO] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) [INFO] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) [INFO] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) [INFO] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) [INFO] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) [INFO] at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) [INFO] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [INFO] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [INFO] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) [INFO] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) [INFO] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) [INFO] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) [INFO] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) [INFO] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [INFO] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) [INFO] at java.base/java.lang.Thread.run(Thread.java:1583) [INFO]
WildFly、Apache Tomcatのいずれも、同期Servletから非同期Servletにディスパッチ後、ServletRequest#startAsync
を
呼び出した時点でIllegalStateException
がスローされています。
## WildFly Caused by: java.lang.IllegalStateException: UT010026: Async is not supported for this request, as not all filters or Servlets were marked as supporting async ## Apache Tomcat [INFO] 重大: サーブレット [org.littlewings.servlet.async.SyncDispatchServlet] のServlet.service()が例外を投げました [INFO] java.lang.IllegalStateException: 現在のチェーンのフィルタまたはサーブレットは非同期操作をサポートしていません。
非同期Servetからのディスパッチ。
## WildFly ### 同期Serlvetへ $ curl -i localhost:8080/async/dispatch/sync/simple HTTP/1.1 200 OK Connection: keep-alive Content-Length: 25 Date: Sun, 02 Mar 2025 11:49:06 GMT Hello from Sync Servlet ### 同期Serlvet+JSPへ $ curl -i localhost:8080/async/dispatch/sync/jsp HTTP/1.1 200 OK Connection: keep-alive X-Powered-By: JSP/3.1 Set-Cookie: JSESSIONID=xt7wcq1k-cduTXd0VyYlMKHXUTndIhI929oc_6yv.ikaruga; path=/ Content-Type: text/html;charset=ISO-8859-1 Content-Length: 17 Date: Sun, 02 Mar 2025 11:49:31 GMT Hello from JSP!! ### 非同期Serlvetへ $ curl -i localhost:8080/async/dispatch/simple HTTP/1.1 200 OK Connection: keep-alive Content-Length: 26 Date: Sun, 02 Mar 2025 11:49:57 GMT Hello from Async Servlet ### 非同期Serlvet+JSPへ $ curl -i localhost:8080/async/dispatch/jsp HTTP/1.1 200 OK Connection: keep-alive X-Powered-By: JSP/3.1 Set-Cookie: JSESSIONID=Shm7SiE5rEcXgbT7Qgij7g_Pqcl1ZJPlRUGKOVi3.ikaruga; path=/ Content-Type: text/html;charset=ISO-8859-1 Content-Length: 17 Date: Sun, 02 Mar 2025 11:50:25 GMT Hello from JSP!! ## Apache Tomcat ### 同期Serlvetへ $ curl -i localhost:8080/async/dispatch/sync/simple HTTP/1.1 200 Content-Length: 24 Date: Sun, 02 Mar 2025 11:52:59 GMT Hello from Sync Servlet ### 同期Serlvet+JSPへ $ curl -i localhost:8080/async/dispatch/sync/jsp HTTP/1.1 200 Set-Cookie: JSESSIONID=B0A56A254F1942A7E22C9274B3E9C040; Path=/; HttpOnly Content-Type: text/html;charset=UTF-8 Content-Length: 17 Date: Sun, 02 Mar 2025 11:53:30 GMT Hello from JSP!! ### 非同期Serlvetへ $ curl -i localhost:8080/async/dispatch/simple HTTP/1.1 200 Content-Length: 25 Date: Sun, 02 Mar 2025 11:53:55 GMT Hello from Async Servlet ### 非同期Serlvet+JSPへ $ curl -i localhost:8080/async/dispatch/jsp HTTP/1.1 200 Set-Cookie: JSESSIONID=AA6B76172CB8CE225BFDB6371860C81A; Path=/; HttpOnly Content-Type: text/html;charset=UTF-8 Content-Length: 17 Date: Sun, 02 Mar 2025 11:54:20 GMT Hello from JSP!!
ログ。
## WildFly ### 同期Serlvetへ 20:49:06,612 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:49:06,612 INFO [org.littlewings.servlet.async.AsyncDispatchServlet] (default task-1) do get 20:49:06,617 INFO [org.littlewings.servlet.async.AsyncDispatchServlet] (EE-ManagedExecutorService-default-Thread-1) dispatch from access path = /async/dispatch/sync/simple, next -> /sync/simple 20:49:06,619 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:49:06,620 INFO [org.littlewings.servlet.async.SyncServlet] (default task-1) do get ### 同期Serlvet+JSPへ 20:49:31,487 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:49:31,487 INFO [org.littlewings.servlet.async.AsyncDispatchServlet] (default task-1) do get 20:49:31,488 INFO [org.littlewings.servlet.async.AsyncDispatchServlet] (EE-ManagedExecutorService-default-Thread-2) dispatch from access path = /async/dispatch/sync/jsp, next -> /sync/jsp 20:49:31,490 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:49:31,490 INFO [org.littlewings.servlet.async.SyncViewJspServlet] (default task-1) do get 20:49:31,501 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported ### 非同期Serlvetへ 20:49:57,957 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:49:57,958 INFO [org.littlewings.servlet.async.AsyncDispatchServlet] (default task-1) do get 20:49:57,959 INFO [org.littlewings.servlet.async.AsyncDispatchServlet] (EE-ManagedExecutorService-default-Thread-3) dispatch from access path = /async/dispatch/simple, next -> /async/simple 20:49:57,960 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:49:57,960 INFO [org.littlewings.servlet.async.AsyncServlet] (default task-1) do get 20:49:57,961 INFO [org.littlewings.servlet.async.AsyncServlet] (EE-ManagedExecutorService-default-Thread-4) do task ### 非同期Serlvet+JSPへ 20:50:25,409 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:50:25,410 INFO [org.littlewings.servlet.async.AsyncDispatchServlet] (default task-1) do get 20:50:25,410 INFO [org.littlewings.servlet.async.AsyncDispatchServlet] (EE-ManagedExecutorService-default-Thread-5) dispatch from access path = /async/dispatch/jsp, next -> /async/jsp 20:50:25,412 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 20:50:25,412 INFO [org.littlewings.servlet.async.AsyncViewJspServlet] (default task-1) do get 20:50:25,414 INFO [org.littlewings.servlet.async.AsyncViewJspServlet] (EE-ManagedExecutorService-default-Thread-6) do task 20:50:25,415 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported ## Apache Tomcat ### 同期Serlvetへ [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.AsyncDispatchServlet - do get [INFO] [pool-1-thread-1] INFO org.littlewings.servlet.async.AsyncDispatchServlet - dispatch from access path = /async/dispatch/sync/simple, next -> /sync/simple [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.SyncServlet - do get ### 同期Serlvet+JSPへ [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.AsyncDispatchServlet - do get [INFO] [pool-1-thread-2] INFO org.littlewings.servlet.async.AsyncDispatchServlet - dispatch from access path = /async/dispatch/sync/jsp, next -> /sync/jsp [INFO] [http-nio-8080-exec-6] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-6] INFO org.littlewings.servlet.async.SyncViewJspServlet - do get [INFO] [http-nio-8080-exec-6] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported ### 非同期Serlvetへ [INFO] [http-nio-8080-exec-7] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-7] INFO org.littlewings.servlet.async.AsyncDispatchServlet - do get [INFO] [pool-1-thread-3] INFO org.littlewings.servlet.async.AsyncDispatchServlet - dispatch from access path = /async/dispatch/simple, next -> /async/simple [INFO] [http-nio-8080-exec-8] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-8] INFO org.littlewings.servlet.async.AsyncServlet - do get [INFO] [pool-1-thread-4] INFO org.littlewings.servlet.async.AsyncServlet - do task ### 非同期Serlvet+JSPへ [INFO] [http-nio-8080-exec-10] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-10] INFO org.littlewings.servlet.async.AsyncDispatchServlet - do get [INFO] [pool-1-thread-5] INFO org.littlewings.servlet.async.AsyncDispatchServlet - dispatch from access path = /async/dispatch/jsp, next -> /async/jsp [INFO] [http-nio-8080-exec-1] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-1] INFO org.littlewings.servlet.async.AsyncViewJspServlet - do get [INFO] [pool-1-thread-6] INFO org.littlewings.servlet.async.AsyncViewJspServlet - do task [INFO] [http-nio-8080-exec-2] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported
非同期Servletからは、同期・非同期Servletのどちらにディスパッチしても問題なく動作します。
非同期Servletからディスパッチしても、転送先のServletはHTTPアクセスを処理するスレッドで動作していることがここでも
確認できます。
2回ディスパッチしてみる
ここまでで、ディスパッチ自体は複数繰り返してもOKでしたが、最大1回というのはServletRequest#startAsync
を
呼び出した非同期サイクルで1回のみ可能ということを一応確認しておきます。
こんな非同期Servletを用意。
src/main/java/org/littlewings/servlet/async/AsyncBadDispatchServlet.java
package org.littlewings.servlet.async; import jakarta.servlet.AsyncContext; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.concurrent.ExecutorService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebServlet(value = "/async/bad/*", asyncSupported = true) public class AsyncBadDispatchServlet extends HttpServlet { private Logger logger = LoggerFactory.getLogger(AsyncBadDispatchServlet.class); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info("do get"); AsyncContext asyncContext = request.startAsync(request, response); ExecutorService executorService = (ExecutorService) request.getServletContext().getAttribute("asyncWorker"); executorService.submit(() -> { logger.info("do task"); if ("jsp".equals(((HttpServletRequest) asyncContext.getRequest()).getQueryString())) { logger.info("dispatch jsp"); asyncContext.dispatch("/jsp"); try { asyncContext.dispatch("/simple"); } catch (IllegalStateException e) { logger.info("error = {}", e.getMessage(), e); } } else { logger.info("do dispatch simple"); asyncContext.dispatch("/simple"); try { asyncContext.dispatch("/simple"); } catch (IllegalStateException e) { logger.info("error = {}", e.getMessage(), e); } } }); } }
それぞれ2回AsyncContext#dispatch
を呼び出しています。ディスパッチ先は非同期Servletおよび非同期Servlet+JSPですね。
## WildFly ### 非同期Servletへ $ curl -i localhost:8080/async/bad/simple HTTP/1.1 404 Not Found Connection: keep-alive Content-Type: text/html;charset=UTF-8 Content-Length: 68 Date: Sun, 02 Mar 2025 12:03:15 GMT <html><head><title>Error</title></head><body>Not Found</body></html> ### 非同期Servlet+JSPへ $ curl -i localhost:8080/async/bad/jsp HTTP/1.1 404 Not Found Connection: keep-alive Content-Type: text/html;charset=UTF-8 Content-Length: 68 Date: Sun, 02 Mar 2025 12:04:05 GMT <html><head><title>Error</title></head><body>Not Found</body></html> ## Apache Tomcat ### 非同期Servletへ $ curl -i localhost:8080/async/bad/simple HTTP/1.1 404 Content-Type: text/html;charset=utf-8 Content-Language: ja Content-Length: 902 Date: Sun, 02 Mar 2025 12:05:16 GMT <!doctype html><html lang="ja"><head><title>HTTPステータス 404 – 見つかりません</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTPステータス 404 – 見つかりません</h1><hr class="line" /><p><b>タイプ</b> ステータスレポート</p><p><b>メッセージ</b> 要求されたリソース [/simple] は利用できません。</p><p><b>説明</b> オリジンサーバーは、ターゲットリソースの現在の表現を見つけられなかったか、またはそれが存在することを開示するつもりはありません。</p><hr class="line" /><h3>Apache Tomcat/10.1.36</h3></body></html> ### 非同期Servlet+JSPへ $ curl -i localhost:8080/async/bad/jsp HTTP/1.1 404 Content-Type: text/html;charset=utf-8 Content-Language: ja Content-Length: 902 Date: Sun, 02 Mar 2025 12:05:49 GMT <!doctype html><html lang="ja"><head><title>HTTPステータス 404 – 見つかりません</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTPステータス 404 – 見つかりません</h1><hr class="line" /><p><b>タイプ</b> ステータスレポート</p><p><b>メッセージ</b> 要求されたリソース [/simple] は利用できません。</p><p><b>説明</b> オリジンサーバーは、ターゲットリソースの現在の表現を見つけられなかったか、またはそれが存在することを開示するつもりはありません。</p><hr class="line" /><h3>Apache Tomcat/10.1.36</h3></body></html>
今回のコードの場合は、404になりました。
ログ。
## WildFly ### 非同期Servletへ 21:03:15,523 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 21:03:15,524 INFO [org.littlewings.servlet.async.AsyncBadDispatchServlet] (default task-1) do get 21:03:15,528 INFO [org.littlewings.servlet.async.AsyncBadDispatchServlet] (EE-ManagedExecutorService-default-Thread-1) do task 21:03:15,529 INFO [org.littlewings.servlet.async.AsyncBadDispatchServlet] (EE-ManagedExecutorService-default-Thread-1) do dispatch simple 21:03:15,533 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 21:03:15,535 INFO [org.littlewings.servlet.async.AsyncBadDispatchServlet] (EE-ManagedExecutorService-default-Thread-1) error = UT010025: Async request already dispatched: java.lang.IllegalStateException: UT010025: Async request already dispatched at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.AsyncContextImpl.dispatch(AsyncContextImpl.java:218) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.AsyncContextImpl.dispatch(AsyncContextImpl.java:211) at deployment.ROOT.war//org.littlewings.servlet.async.AsyncBadDispatchServlet.lambda$doGet$0(AsyncBadDispatchServlet.java:43) at org.wildfly.concurrency@35.0.1.Final//org.jboss.as.ee.concurrent.ControlPointUtils$ControlledRunnable.run(ControlPointUtils.java:118) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.SecurityIdentity.runAsConsumer(SecurityIdentity.java:376) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAsConsumer(Scoped.java:112) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:60) at org.wildfly.concurrency@35.0.1.Final//org.jboss.as.ee.concurrent.SecurityIdentityUtils.lambda$doIdentityWrap$1(SecurityIdentityUtils.java:50) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at org.glassfish.jakarta.enterprise.concurrent//org.glassfish.enterprise.concurrent.internal.ManagedFutureTask.run(ManagedFutureTask.java:119) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583) at org.glassfish.jakarta.enterprise.concurrent//org.glassfish.enterprise.concurrent.ManagedThreadFactoryImpl$ManagedThread.run(ManagedThreadFactoryImpl.java:322) ### 非同期Servlet+JSPへ 21:04:05,710 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 21:04:05,710 INFO [org.littlewings.servlet.async.AsyncBadDispatchServlet] (default task-1) do get 21:04:05,712 INFO [org.littlewings.servlet.async.AsyncBadDispatchServlet] (EE-ManagedExecutorService-default-Thread-3) do task 21:04:05,713 INFO [org.littlewings.servlet.async.AsyncBadDispatchServlet] (EE-ManagedExecutorService-default-Thread-3) do dispatch simple 21:04:05,713 INFO [org.littlewings.servlet.async.AsyncSupportedFilter] (default task-1) do filter / async supported 21:04:05,713 INFO [org.littlewings.servlet.async.AsyncBadDispatchServlet] (EE-ManagedExecutorService-default-Thread-3) error = UT010025: Async request already dispatched: java.lang.IllegalStateException: UT010025: Async request already dispatched at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.AsyncContextImpl.dispatch(AsyncContextImpl.java:218) at io.undertow.servlet@2.3.18.Final//io.undertow.servlet.spec.AsyncContextImpl.dispatch(AsyncContextImpl.java:211) at deployment.ROOT.war//org.littlewings.servlet.async.AsyncBadDispatchServlet.lambda$doGet$0(AsyncBadDispatchServlet.java:43) at org.wildfly.concurrency@35.0.1.Final//org.jboss.as.ee.concurrent.ControlPointUtils$ControlledRunnable.run(ControlPointUtils.java:118) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.SecurityIdentity.runAsConsumer(SecurityIdentity.java:376) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAsConsumer(Scoped.java:112) at org.wildfly.security.elytron-base@2.6.0.Final//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:60) at org.wildfly.concurrency@35.0.1.Final//org.jboss.as.ee.concurrent.SecurityIdentityUtils.lambda$doIdentityWrap$1(SecurityIdentityUtils.java:50) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at org.glassfish.jakarta.enterprise.concurrent//org.glassfish.enterprise.concurrent.internal.ManagedFutureTask.run(ManagedFutureTask.java:119) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583) at org.glassfish.jakarta.enterprise.concurrent//org.glassfish.enterprise.concurrent.ManagedThreadFactoryImpl$ManagedThread.run(ManagedThreadFactoryImpl.java:322) ## Apache Tomcat ### 非同期Servletへ [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-3] INFO org.littlewings.servlet.async.AsyncBadDispatchServlet - do get [INFO] [pool-1-thread-1] INFO org.littlewings.servlet.async.AsyncBadDispatchServlet - do task [INFO] [pool-1-thread-1] INFO org.littlewings.servlet.async.AsyncBadDispatchServlet - do dispatch simple [INFO] [pool-1-thread-1] INFO org.littlewings.servlet.async.AsyncBadDispatchServlet - error = complete()の後、またはdispatch()メソッドのどれかが呼び出された不正なgetRequest()の呼び出し [INFO] java.lang.IllegalStateException: complete()の後、またはdispatch()メソッドのどれかが呼び出された不正なgetRequest()の呼び出し [INFO] at org.apache.catalina.core.AsyncContextImpl.getRequest(AsyncContextImpl.java:213) [INFO] at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:176) [INFO] at org.littlewings.servlet.async.AsyncBadDispatchServlet.lambda$doGet$0(AsyncBadDispatchServlet.java:43) [INFO] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) [INFO] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) [INFO] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) [INFO] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) [INFO] at java.base/java.lang.Thread.run(Thread.java:1583) [INFO] [http-nio-8080-exec-4] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported ### 非同期Servlet+JSPへ [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported [INFO] [http-nio-8080-exec-5] INFO org.littlewings.servlet.async.AsyncBadDispatchServlet - do get [INFO] [pool-1-thread-2] INFO org.littlewings.servlet.async.AsyncBadDispatchServlet - do task [INFO] [pool-1-thread-2] INFO org.littlewings.servlet.async.AsyncBadDispatchServlet - do dispatch simple [INFO] [pool-1-thread-2] INFO org.littlewings.servlet.async.AsyncBadDispatchServlet - error = complete()の後、またはdispatch()メソッドのどれかが呼び出された不正なgetRequest()の呼び出し [INFO] java.lang.IllegalStateException: complete()の後、またはdispatch()メソッドのどれかが呼び出された不正なgetRequest()の呼び出し [INFO] at org.apache.catalina.core.AsyncContextImpl.getRequest(AsyncContextImpl.java:213) [INFO] at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:176) [INFO] at org.littlewings.servlet.async.AsyncBadDispatchServlet.lambda$doGet$0(AsyncBadDispatchServlet.java:43) [INFO] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) [INFO] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) [INFO] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) [INFO] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) [INFO] at java.base/java.lang.Thread.run(Thread.java:1583) [INFO] [http-nio-8080-exec-7] INFO org.littlewings.servlet.async.AsyncSupportedFilter - do filter / async supported
WildFly、Apache Tomcatのどちらも2回目のAsyncContext#dispatch
が呼び出されたところでIllegalStateException
が
スローされます。
少しソースコードを見る
非同期ServletからAsyncContext#dispatch
でディスパッチすると、HTTPリクエストを処理するスレッドで動いていそうな
ことがわかりましたが、それをソースコードからも確認してみましょう。
Undertowの場合
Undertowの場合、dispatch
メソッドの実体はこちらです。
ディスパッチしたリクエストはキューに入れられます。
そしてこのキューからリクエストを取り出し、Executor
で処理するのですが
ここで使われるExecutor
の取得経路はAsyncContect#start
と同じなので、結果的にワーカースレッド(Servletの
リクエストを処理するのと同じスレッドプール)を使うことになります。
どうしてワーカースレッドになるのかは、このエントリーを書いた時にまとめています。
Jakarta Servletの非同期処理をWildFly 35、Apache Tomcat 10.1で試す - CLOVER🍀
Apache Tomcatの場合
Apache Tomcatの場合、dispatch
メソッドについてはこのあたりを追っていきます。
AsyncStateMachine
の状態的に問題がなければディスパッチが行われ
https://github.com/apache/tomcat/blob/10.1.36/java/org/apache/coyote/AbstractProcessor.java#L883
最終的にエンドポイントを処理するものと同じExecutor
が使われることが確認できます。
おわりに
WildFly 35.0.1.Final、Apache Tomcat 10.1.36を使って、Jakarta Servletの非同期処理でディスパッチをいろいろ試してみました。
およそ思ったとおりの動きだったのですが、ディスパッチ先でどのスレッドが使われるかはあまり考えていなかったので
結果を見てこの視点に気付かされました。
特に気にしていなかったのですが、なるほどなとは思いましたね。
あとはエラーハンドリングまわりを気にしておいた方がよさそうです。