このページは、拙著「Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門」の補足(いいわけ?)のページです。
掲示板にてご指摘をいただきました。
本書で、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個
掲示板にてご指摘をいただきました。
Henacatのcom.kmaebashi.henacat.webserver.ServletService.javaの中で使っているClassのnewInstance()メソッドは現在は非推奨になっているとのことです。非推奨になっているのは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個
原因は、メッセージに出ている通り、ClassのnewInstance()メソッドが 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(); }
詳細はこちらのページに記述があります。
ご意見、ご質問、不具合連絡等は掲示板にお願いいたします。