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
去年と今年と
もう年が明けて5日になってしまいましたが、去年の総括と今年についてつらつらと。
12月末日で今の会社に入ってからちょうど5年が経ちました。 社会人生活に入ってからここまで長く勤めた会社ってのは初めてなので、 まあ、今までで一番合っている会社なんだと思う。 熊本には4年7か月。まだまだ居続けることになりそう。
3年続けないと効果がわからない
3年ぐらいやらないとその人が本当に優秀なのかというのはわからないと思いました。 単年度でものすごい実績を上げれる人はいるのですが、その実績が2年目、3年目も続くかというとそういうわけではない。 東芝のチャレンジもそうでしたが、会計、その他を操ることでその年の実績を上澄みすることができるけど、組織として無理してたら次の年はぼろぼろになるよねぇという。 すごい実績を上げたんですよといいつつ1、2年で次の会社へってことをやってる人がいるけど、どれだけの屍が後ろに積みあがってるんだろうかという。 いや、本当に優秀なのかもしれないけど。
もちろんベンチャーとかだと速度が価値なので、一方向からの見方でしかないのだけれども、まあ、難しいよねぇという感じ。 特に何か結論があるわけではない。
今年はマネージメントにコミットしなければならなくなりそうなので、ちょっと気を付けたいと思いました。
筋トレ
始めてから6年。そろそろこれ以上は筋肉増やさなくても良い感じである。
クラウドは楽
本格的にAWSを使った案件に入ることになってさくっとネットワーク設計とかしたけれども、本当に楽。 オンプレだとげんなりするようなことがマウスポチポチだけで簡単にできる。 サーバールームとか考えなくていいのでビルの部屋割りとかも考えなくてよいから本当に素晴らしい。 という、8年遅れぐらいの感想です。 AWS資格を今年はいくつか取りたい。
人材採用は難しい
いや、本当に。 採用周りはログが残るわけではないから人事がくそみたいなことをやってることもあり、ちょっとずつでも改善していかなければいけないなぁという感じ。 他の会社の採用面接を受けたときに、面接官がバイネームでほかの人の個人情報をべらべらとしゃべり始めたときについてはどうすればよいかと思いました。 リファラル採用とか、社員の友達だから友達感覚でしゃべりたくなるんだろうけれども、お前と私は友達じゃない。 採用活動なんて会社のアンチを作りやすい活動でもあるので、気をつけんとなぁ・・・・・
アウトプットが消えた
去年は本当にアウトプットがなかった・・・・・ついでにインプットも少なかった気がするので、今年は頑張ろう。
モンハン
めざせMR999。
引っ越し
今年(1月中に)結婚することになったので年末からずっと引っ越しとか新居選びとかで忙しい感じです。 結婚報告はまた後程。
まとめ
今年も頑張る。
Oracle DBがWindowsの再起動時に自動で立ち上がらなくなった場合
Oracle DBをサービスとして登録してあり自動で起動するように設定されていて、TNSリスナーは自動で立ち上がるのにOracle DBに接続できない場合があります。 データベースを再作成した時にそうなることがあるのですが、そちらについての確認方法と対処方法を記入します。
今回のケースでは、DBにDBA権限で接続したときにマウント及びオープンされていないので、とりあえず、以下のコマンドを入力することでDBに接続できるようになります。
C:\Users\oracle>sqlplus /nolog SQL*Plus: Release 11.2.0.2.0 Production on 水 12月 4 13:49:43 2019 Copyright (c) 1982, 2014, Oracle. All rights reserved. //sysdba権限でログイン SQL> CONN / AS SYSDBA アイドル・インスタンスに接続しました。 //DBの起動 SQL> STARTUP ORACLEインスタンスが起動しました。 Total System Global Area ********* bytes Fixed Size ********** bytes Variable Size ********** bytes Database Buffers ********** bytes Redo Buffers *********** bytes データベースがマウントされました。 データベースがオープンされました。
Oracle DBを使用するためにはサービスとして起動するほかに、マウント、オープンを行う必要があります。 マウント、オープンする設定がレジストリにあるのですが、オフになっているもしくは不整合が発生している可能性があります。
regeditを管理者権限で開いて、以下のキーを参照してください。 HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_[HomeName]
以下のような観点で確認してください。
- ORA[ServiceName]AUTOSTARTがtrueになっているか
- 初期化パラメーターファイル等の設定ファイルの場所があっているか
詳細はレジストリ・パラメータの概要に。
コマンドからだとoradimコマンドで修正もできます。 詳細はORADIMを使用したOracle Databaseインスタンスの管理についてに。
教えていただいた @takashitel さんありがとうございました。
特定の文字がWindows-31J(Shift_JIS)で扱えるかどうかをJavaで確認する。
現時点では、以下のコードが一番よさそう。
private static final Charset windows31J = Charset.forName("Windows-31J"); public boolean canEncodeWithWindows31J(CharSequence str) { CharsetEncoder encoder = windows31J.newEncoder(); return encoder.canEncode(str); }