「Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門」補足


このページは、拙著「Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門」の補足(いいわけ?)のページです。

Tomcat10からServlet APIのパッケージが変わりました(2022/09/23)

掲示板にてご指摘をいただきました。

本書で、HenacatではないTomcatに付属する本家サーブレットAPIを使用しているソース(リスト3-5、3-6)では、以下のようにしてjavax.servletのクラスをインポートしています。

  2: import javax.servlet.http.*;

しかし、Java EEのJakarta EEへの移管に伴い、javax.servletというパッケージ名は、jakarta.servletに変更されました。よって、Tomcat10からは、上記のままではコンパイルが通らなくなります。

しかし、このステージでもっとも影響の大きい項目は、すべてのJava APIパッケージ名をjavax.*からjakarta.*に変更することです。たとえば、javax.faces.context.FacesContextはjakarta.faces.context.FacesContextになります。このパッケージ名変更は、結果として既存アプリケーションのコードの更新が必要になるため、重大なアップデートです。

そこで、以下のように変更してください。

  2: import jakarta.servlet.http.*;

元のままの状態だと、以下のようなエラーが出ます。

C:\maebashi\doc\webserver\20190211\src_20181021\src\chap03\testbbs\WEB-INF\classes>javac -classpath C:\Tomcat10\lib\servlet-api.jar *.java
PostBBS.java:4: エラー: シンボルを見つけられません
public class PostBBS extends HttpServlet {
                             ^
  シンボル: クラス HttpServlet
PostBBS.java:6: エラー: シンボルを見つけられません
    public void doPost(HttpServletRequest request, HttpServletResponse response)
                       ^
  シンボル:   クラス HttpServletRequest
  場所: クラス PostBBS
PostBBS.java:6: エラー: シンボルを見つけられません
    public void doPost(HttpServletRequest request, HttpServletResponse response)
                                                   ^
  シンボル:   クラス HttpServletResponse
  場所: クラス PostBBS
PostBBS.java:2: エラー: パッケージjavax.servlet.httpは存在しません
import javax.servlet.http.*;
^
ShowBBS.java:4: エラー: シンボルを見つけられません
public class ShowBBS extends HttpServlet {
                             ^
  シンボル: クラス HttpServlet
ShowBBS.java:13: エラー: シンボルを見つけられません
    public void doGet(HttpServletRequest request, HttpServletResponse response)
                      ^
  シンボル:   クラス HttpServletRequest
  場所: クラス ShowBBS
ShowBBS.java:13: エラー: シンボルを見つけられません
    public void doGet(HttpServletRequest request, HttpServletResponse response)
                                                  ^
  シンボル:   クラス HttpServletResponse
  場所: クラス ShowBBS
ShowBBS.java:2: エラー: パッケージjavax.servlet.httpは存在しません
import javax.servlet.http.*;
^
PostBBS.java:5: エラー: メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません
    @Override
    ^
ShowBBS.java:12: エラー: メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません
    @Override
    ^
エラー10個

Class#newInstance()は現在は推奨されていません(2022/08/29)

掲示板にてご指摘をいただきました。

Henacatのcom.kmaebashi.henacat.webserver.ServletService.javaの中で使っているClassnewInstance()メソッドは現在は非推奨になっているとのことです。非推奨になっているのはJavaの9からですが、本書執筆時はJava8で作っていたので気付きませんでした。

現状で、そのままコンパイルすると、以下の警告が出ます(Java17で確認)。

C:\maebashi\temp\src_20181021\src\appendix\Henacat_0_4>javac com\kmaebashi\henacat\webserver\Main.java
ノート:.\com\kmaebashi\henacat\servletimpl\ServletService.javaは推奨されないAPIを使用またはオーバーライドしています。
ノート:詳細は、-Xlint:deprecationオプションを指定して再コンパイルしてください。

「詳細は、-Xlint:deprecationオプションを指定して再コンパイルしてください。」とあるのでそのようにすると、以下のように表示されます。

C:\maebashi\temp\src_20181021\src\appendix\Henacat_0_4>javac -Xlint:deprecation com\kmaebashi\henacat\webserver\Main.java
.\com\kmaebashi\henacat\servletimpl\ServletService.java:12: 警告:[deprecation] ClassのnewInstance()は推奨されません
        return (HttpServlet)clazz.newInstance();
                                 ^
  Tが型変数の場合:
    クラス Classで宣言されているT extends Object
警告1個

原因は、メッセージに出ている通り、ClassnewInstance()メソッドが Java9から非推奨になったためです。該当箇所は、ServletService.javaの中の以下の場所です。

    private static HttpServlet createServlet(ServletInfo info)
                throws Exception {
        Class<?> clazz
                = info.webApp.classLoader.loadClass(info.servletClassName);
        return (HttpServlet)clazz.newInstance();
    }

コンパイル時に警告が出るだけで動くには動きますが、修正する場合は以下のように直してください。

    private static HttpServlet createServlet(ServletInfo info)
                throws Exception {
        Class<?> clazz
                = info.webApp.classLoader.loadClass(info.servletClassName);
        return (HttpServlet)clazz.getDeclaredConstructor().newInstance();
    }

詳細はこちらのページに記述があります。


著者のWebページトップはこちら

ご意見、ご質問、不具合連絡等は掲示板にお願いいたします。