Tomcat 10でJakarta EE 9のServlet APIを試す。
Tomcat 10のマイルストーンリリースが出ました。こちらはJakarta EE 9(旧Java EE 9)対応のリリースとなります。
現時点ではパッケージ名称が変わったぐらいで大きい変更はなく、結果だけ言えばうごいたねーぐらい。
mavenの依存性には以下を指定します。
<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api --> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>5.0.0-M1</version> <scope>provided</scope> </dependency>
で、サーブレットは以下のような感じ。 importだけ以前のjavaxからjakartaに変更されています。
package dev.megascus.tomcat10test; 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.PrintWriter; @WebServlet(name = "TestServlet", urlPatterns = {"/"}) public class TestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); try (PrintWriter out = response.getWriter()) { /* TODO output your page here. You may use following sample code. */ out.println("<!DOCTYPE html>"); out.println("<html>"); out.println("<head>"); out.println("<title>Servlet TestServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Servlet TestServlet at " + request.getContextPath() + "</h1>"); out.println("</body>"); out.println("</html>"); } } }
結果としては面白くないですが、ふつううううううに表示されます。
ちなみに、アノテーションをjakarta.servlet.annotation.WebServletからjavax.servlet.annotation.WebServletに変更したところ、TomcatからはServletとして認識されませんでした。 jakartaから始まるもののみ認識するように修正されているのでしょうね。
javaxのままweb.xmlで直接指定すると起動時にエラーになります。
<servlet> <servlet-name>TestServlet</servlet-name> <servlet-class>dev.megascus.tomcat10test.TestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>test</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1365) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188) at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174) at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2419) at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:865) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1334) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188) at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:541) at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:522) at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:151) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1043) at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:762) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:688) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:845) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1553) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:834)
追記
Tomcatは一括変換ツール(開発中)で互換性問題を解決するつもりのようです。 https://t.co/22JThuOZ8q このほかにバイトコードを動的にいじる方法が2種類(最初に提案されたやつとjavassist使うやつ)が今のところ提案されています。
— btnrouge (@btnrouge) March 2, 2020