Tomcat 10でJakarta EE 9のServlet APIを試す。

Tomcat 10のマイルストーンリリースが出ました。こちらはJakarta EE 9(旧Java EE 9)対応のリリースとなります。

tomcat.apache.org

現時点ではパッケージ名称が変わったぐらいで大きい変更はなく、結果だけ言えばうごいたねーぐらい。

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>");
        }
    }
}

結果としては面白くないですが、ふつううううううに表示されます。

f:id:megascus:20200302142415p:plain

ちなみに、アノテーション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)

追記

去年と今年と

もう年が明けて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);

    }

CharsetEncoder (Java SE 11 & JDK 11 )

Hitachi Cosminexusの新規採用は止めましょう。

Java EE(Jakarta EE)の仕様検討ワーキンググループへの参加を止めてしまい、最新仕様への追従も数年前から止めてしまっているようなので、導入するのは止めましょう。 仮に導入しても、レガシーAPIしか使用できず、生産性の向上は望めません。

Java EE(Jakarta EE)サーバーを選択する場合は、少なくとも以下のページに名前の挙がっているベンダーから選択することが推奨されます。

jakarta.ee

WindowsでOracle 18c XEのインストール時に管理者権限があるのに管理者権限がないと怒られて失敗する場合

ドメインに参加しているWindowsドメインユーザーを使用してOracle 18c XEをインストールしようとすると、管理者権限がついていたとしても管理者権限がないといわれて怒られる。

その場合、同名のローカルユーザーを作って管理者権限を付けてあげると、ドメインユーザーでもインストールすることが出来るようになる。*1

*1:どう考えてもダメだと思う

Servlet APIとJPA APIの日本語翻訳を独自ドメインに移動させました。

タイトルのとおり。

古いページにアクセスしても自動でリダイレクトされるはずですが、ご連絡として。

中身はgithub pagesのままで何も変わってないです。

https://github.megascus.dev/

よくある質問と答え

  • なんでドメインを移動させたんですか?
    • github pagesのドメインだと社内プロキシに阻まれてアクセスできないという苦情を受けたためです。