https://atmarkit.itmedia.co.jp/ait/articles/0710/11/news121_2.html
↑これでトムキャットのサンプルファイル使ったウェブページ表示に苦戦
壁1:サンプルファイルのコンパイルに失敗
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet {
public void doGet(HttpServletRequest request
,HttpServletResponse response)
throws IOException, ServletException{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World!</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
}
}
失敗1
javac -classpath /opt/tomcat6/lib/servlet-api.jar HelloWorld.java
HelloWorld.java:4: error: cannot find symbol
public class HelloWorld extends HttpServlet {
^
symbol: class HttpServlet
HelloWorld.java:5: error: cannot find symbol
public void doGet(HttpServletRequest request
^
symbol: class HttpServletRequest
location: class HelloWorld
HelloWorld.java:6: error: cannot find symbol
,HttpServletResponse response)
^
symbol: class HttpServletResponse
location: class HelloWorld
HelloWorld.java:7: error: cannot find symbol
throws IOException, ServletException{
^
symbol: class ServletException
location: class HelloWorld
HelloWorld.java:2: error: package javax.servlet does not exist
import javax.servlet.*;
^
HelloWorld.java:3: error: package javax.servlet.http does not exist
import javax.servlet.http.*;
^
6 errors
似たエラーのリンク:
https://stackoverflow.com/questions/52640868/error-package-javax-servlet-http-does-not-exist-even-after-adding-the-classpath
https://coderanch.com/t/427630/java/HelloWorld-Servlet-Run
↑どちらもクラスパスちゃんと指定してみたいなこと書いてありますが、今回は違いました。
tomcat10以降はimportするパッケージ名が変更になるため修正したところ出来ました。
import java.io.*;
//import javax.servlet.*;
//import javax.servlet.http.*;
import jakarta.servlet.*; // tomcat10以降、javax.servletではなくjakarta.servletを使用する
import jakarta.servlet.http.*; // 同上
public class HelloWorld extends HttpServlet {
public void doGet(HttpServletRequest request
,HttpServletResponse response)
throws IOException, ServletException{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World!</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
}
}
HelloWorld.classというファイルが作成されてたらコンパイル成功
https://rc30-popo.hatenablog.com/entry/2022/05/05/002023
壁2バージョンの不一致で実行
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
ここに書いているように、拡張子をつけずに以下のコマンド実行
https://techacademy.jp/magazine/22220
java HelloWorld
出力結果
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: HelloWorld has been compiled by a more recent version of the Java Runtime (class file version
55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:473)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:601)
ここにも書いてあるけど、javaのバージョンが古いため失敗している模様
https://teratail.com/questions/164145
https://qiita.com/hajimeni/items/67d9e9b0d169bf68d1c9
javaのソース:https://www.oracle.com/java/technologies/downloads/
どれ選べばいいんだとなれば以下のコマンドでまずtomcatやOSの情報確認
/usr/local/tomcat/bin/version.sh
出力結果
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /opt/java/openjdk
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Server version: Apache Tomcat/10.0.23
Server built: Jul 14 2022 08:16:11 UTC
Server number: 10.0.23.0
OS Name: Linux
OS Version: 5.10.104-linuxkit
Architecture: amd64
JVM Version: 1.8.0_345-b01 → javaのバージョン
JVM Vendor: Temurin
javac -version
結果
javac 11.0.16
javaのアップデート
https://qiita.com/terappy/items/537c069923144a9d9755
上記リンクを参考にインストール
バージョンはクラスファイル55.0が必要なのでjava11 JDK でコンパイルした環境に対応するバージョンをインストール(少なくとも現バージョンのJVM Version: 1.8.0_345-b01 ではクラスファイル52.0までしか対応してないので無理。それ以上のバージョンにする必要がある)
https://teratail.com/questions/274766
https://qiita.com/terappy/items/537c069923144a9d9755
上記参考にインストール。パッケージを確認するコマンドも便利そうなので良さそう
apt search openjdk-\(\.\)\+-jre$
・
・(色々出てくる
・
apt-get install -y openjdk-11-jre
・
・(色々出てくる
・
ところがこれだけだとjavaのバージョンが古いままです。一工夫必要らしい。
壁3:javaのバージョンが新しくならない問題
https://cpp0302.hatenablog.com/entry/2017/12/20/012901
これ参考に/usr/local/tomcat/bin/catalina.shでパス指定
・
・
JAVA_HOME="/usr/java/jdk1.8.0_131"
・
・
↑JAVA_HOMEは参照される値なのでスクリプトの割りと最初の方に挿入しました
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
echo $JAVA_HOME
/usr/lib/jvm/java-11-openjdk-amd64
よし。しかし注意このまま再起動すると設定した環境変数の値は保存されません。
https://e-seventh.com/linux-save-environment-variable/
したがって/.bashrcに以下をぶっこみます
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
再起動すると環境変数として反映されてたし以下のコマンドの結果の内容が変わってる
/usr/local/tomcat/bin/version.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/lib/jvm/java-11-openjdk-amd64
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
Server version: Apache Tomcat/10.0.23
Server built: Jul 14 2022 08:16:11 UTC
Server number: 10.0.23.0
OS Name: Linux
OS Version: 5.10.104-linuxkit
Architecture: amd64
JVM Version: 11.0.16+8-post-Ubuntu-0ubuntu122.04
JVM Vendor: Ubuntu
しかし、、、java HelloWorldコマンド失敗
java -version
openjdk version "1.8.0_345"
OpenJDK Runtime Environment (Temurin)(build 1.8.0_345-b01)
OpenJDK 64-Bit Server VM (Temurin)(build 25.345-b01, mixed mode)
別のコマンドでバージョン調べるとバージョンが変わってない。なんでや
javaコマンドをストーキングする
・・・
壁4:tomcatのバージョン情報のjavaのバージョンとjavaコマンドで出力するバージョンが不一致
コマンドをストーキング
which java
/opt/java/openjdk/bin/java
ああ、javaコマンドがもともとのやつね
find / -name java
/var/lib/dpkg/alternatives/java
/usr/bin/java
/usr/share/lintian/data/java
/usr/share/java
/usr/lib/jvm/java-18-openjdk-amd64/bin/java →新しい
/usr/lib/jvm/java-11-openjdk-amd64/bin/java
/opt/java
/opt/java/openjdk/bin/java →古い
/etc/alternatives/java
/etc/ssl/certs/java
・
・
/usr/lib/jvm/java-18-openjdk-amd64/bin/java -version
openjdk version "18.0.2-ea" 2022-07-19
OpenJDK Runtime Environment (build 18.0.2-ea+9-Ubuntu-222.04)
OpenJDK 64-Bit Server VM (build 18.0.2-ea+9-Ubuntu-222.04, mixed mode, sharing)
↑そゆこと
ってことで
/usr/lib/jvm/java-18-openjdk-amd64/bin/java HelloWorld
Error: Could not find or load main class HelloWorld
Caused by: java.lang.NoClassDefFoundError: jakarta/servlet/http/HttpServlet
meow???
ちょっと出直してきます
この辺からディグる