Servlet 5.0 JAR 在 javax.servlet.* 上抛出编译错误,但 Servlet 4.0 JAR 不会
Servlet 5.0 JAR throws compile error on javax.servlet.* but Servlet 4.0 JAR does not
我正在尝试从命令行编译和部署一个简单的网络应用程序。
servlet-api.jar 来自 Apache Tomcat 不编译我的 java 文件,但是 javax.servlet-api-4.0.1 来自 maven central存储库成功编译它。即便如此,当我部署应用程序并尝试在浏览器中使用它时,我还是遇到了错误。
我正在使用:
- javac 11.0.8
- Apache Tomcat 10.0 (servlet-api.jar 5.0)
Java 文件:
package com.example.controllers;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class BeerSelect extends HttpServlet {
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Beer Selection Advice <br>");
String c = request.getParameter("color");
out.println("<br>Got beer color " + c);
}
}
当我尝试用 servlet-api.jar 编译它时,我得到:
public class BeerSelect extends HttpServlet {
^
symbol: class HttpServlet
src\com\example\controllers\BeerSelect.java:9: error: cannot find symbol
public void doPost(HttpServletRequest request,
^
symbol: class HttpServletRequest
location: class BeerSelect
src\com\example\controllers\BeerSelect.java:10: error: cannot find symbol
HttpServletResponse response)
^
symbol: class HttpServletResponse
location: class BeerSelect
src\com\example\controllers\BeerSelect.java:11: error: cannot find symbol
throws IOException, ServletException {
^
symbol: class ServletException
location: class BeerSelect
src\com\example\controllers\BeerSelect.java:3: error: package javax.servlet does not exist
import javax.servlet.*;
^
src\com\example\controllers\BeerSelect.java:4: error: package javax.servlet.http does not exist
import javax.servlet.http.*;
^
6 errors
然而,javax.servlet-api-4.0.1 编译文件成功。注意:我已经测试并排除了命令行命令作为问题的可能原因。
当我将 .class 文件放在相应的 Tomcat 目录中,启动服务器并尝试与应用程序交互时,出现以下异常:
Exception
jakarta.servlet.ServletException: Error instantiating servlet class [com.example.controllers.BeerSelect]
Root Cause
java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet
Root Cause
java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet
我尝试将 javax.servlet-api-4.0.1 放在 Tomcat/lib 目录中,但随后我得到:
Exception
jakarta.servlet.ServletException: Class [com.example.controllers.BeerSelect] is not a Servlet
Root Cause
java.lang.ClassCastException: class com.example.controllers.BeerSelect cannot be cast to class jakarta.servlet.Servlet (com.example.controllers.BeerSelect is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @7862f56; jakarta.servlet.Servlet is in unnamed module of loader java.net.URLClassLoader @4b4523f8)
不确定最后一个是否有意义,但我 运行 没有想法。
非常欢迎任何帮助!
我已经在 Apache Tomcat 9.0.39 上测试并成功编译了 java 文件。
此时,Apache Tomcat 10 正在开发中,没有稳定版本:
http://tomcat.apache.org/whichversion.html
降级 Apache Tomcat 版本应该可以解决问题。
When I place the .class file in the corresponding Tomcat directory, start the server and try to interact with the app, I get the following exception:
java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet
I tried placing the javax.servlet-api-4.0.1 in the Tomcat/lib directory, but then I get:
java.lang.ClassCastException: class com.example.controllers.BeerSelect
cannot be cast to class jakarta.servlet.Servlet
jakarta.servlet.Servlet
是 Servlet API 版本 5.0 的一部分,后者又是 Jakarta EE 版本 9 的一部分。您的 servlet 实际上是从 javax.servlet.Servlet
扩展而来的,而后者又是目标运行时实际上不支持的旧 JEE 版本 (Tomcat 10.x)。
您有 2 个选择:
将代码中的 javax.servlet.*
导入替换为 jakarta.servlet.*
。
import jakarta.servlet.*;
import jakarta.servlet.http.*;
然后您可以只针对来自基于 Servlet 5.0 的目标运行时的库进行编译。
或者,将 servlet 容器从 Servlet API 版本 5.0 降级到以前的版本,至少是仍然具有 javax.servlet.*
包名称的版本。 Tomcat 9.x 是最新的仍然有旧包。
技术原因是,在从 Java/Jakarta EE 8 到 Jakarta EE 9 的步骤中,所有 javax.*
包都已重命名为 jakarta.*
包。因此自 Jakarta EE 9 以来不再向后兼容。
因此,当您在使用 Tomcat 10 或更新版本时遵循任何仍然使用旧 javax.servlet.*
包的 servlet 教程时,您需要手动换出代码示例中使用的包对于 jakarta.servlet.*
一个。通常它会工作得很好。
另请参阅:
- Apache Tomcat - versions
- (此答案包含 Tomcat 10+、Tomcat 9-、JEE 9+ 和 JEE 8- 的正确
pom.xml
声明的完整示例,只是如果您使用的是 Maven)。
Sree Kumar wrote 关于另一个为我解决了问题的重复问题:
Right-click on project -> Build Path -> Configure Build Path... -> Libraries (tab) -> Select Classpath -> Add Library -> Server Runtime -> Select the one you must have added for Tomcat 10.
我正在尝试从命令行编译和部署一个简单的网络应用程序。
servlet-api.jar 来自 Apache Tomcat 不编译我的 java 文件,但是 javax.servlet-api-4.0.1 来自 maven central存储库成功编译它。即便如此,当我部署应用程序并尝试在浏览器中使用它时,我还是遇到了错误。
我正在使用:
- javac 11.0.8
- Apache Tomcat 10.0 (servlet-api.jar 5.0)
Java 文件:
package com.example.controllers;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class BeerSelect extends HttpServlet {
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Beer Selection Advice <br>");
String c = request.getParameter("color");
out.println("<br>Got beer color " + c);
}
}
当我尝试用 servlet-api.jar 编译它时,我得到:
public class BeerSelect extends HttpServlet {
^
symbol: class HttpServlet
src\com\example\controllers\BeerSelect.java:9: error: cannot find symbol
public void doPost(HttpServletRequest request,
^
symbol: class HttpServletRequest
location: class BeerSelect
src\com\example\controllers\BeerSelect.java:10: error: cannot find symbol
HttpServletResponse response)
^
symbol: class HttpServletResponse
location: class BeerSelect
src\com\example\controllers\BeerSelect.java:11: error: cannot find symbol
throws IOException, ServletException {
^
symbol: class ServletException
location: class BeerSelect
src\com\example\controllers\BeerSelect.java:3: error: package javax.servlet does not exist
import javax.servlet.*;
^
src\com\example\controllers\BeerSelect.java:4: error: package javax.servlet.http does not exist
import javax.servlet.http.*;
^
6 errors
然而,javax.servlet-api-4.0.1 编译文件成功。注意:我已经测试并排除了命令行命令作为问题的可能原因。
当我将 .class 文件放在相应的 Tomcat 目录中,启动服务器并尝试与应用程序交互时,出现以下异常:
Exception
jakarta.servlet.ServletException: Error instantiating servlet class [com.example.controllers.BeerSelect]
Root Cause
java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet
Root Cause
java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet
我尝试将 javax.servlet-api-4.0.1 放在 Tomcat/lib 目录中,但随后我得到:
Exception
jakarta.servlet.ServletException: Class [com.example.controllers.BeerSelect] is not a Servlet
Root Cause
java.lang.ClassCastException: class com.example.controllers.BeerSelect cannot be cast to class jakarta.servlet.Servlet (com.example.controllers.BeerSelect is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @7862f56; jakarta.servlet.Servlet is in unnamed module of loader java.net.URLClassLoader @4b4523f8)
不确定最后一个是否有意义,但我 运行 没有想法。
非常欢迎任何帮助!
我已经在 Apache Tomcat 9.0.39 上测试并成功编译了 java 文件。
此时,Apache Tomcat 10 正在开发中,没有稳定版本: http://tomcat.apache.org/whichversion.html
降级 Apache Tomcat 版本应该可以解决问题。
When I place the .class file in the corresponding Tomcat directory, start the server and try to interact with the app, I get the following exception:
java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet
I tried placing the javax.servlet-api-4.0.1 in the Tomcat/lib directory, but then I get:
java.lang.ClassCastException: class com.example.controllers.BeerSelect cannot be cast to class jakarta.servlet.Servlet
jakarta.servlet.Servlet
是 Servlet API 版本 5.0 的一部分,后者又是 Jakarta EE 版本 9 的一部分。您的 servlet 实际上是从 javax.servlet.Servlet
扩展而来的,而后者又是目标运行时实际上不支持的旧 JEE 版本 (Tomcat 10.x)。
您有 2 个选择:
将代码中的
javax.servlet.*
导入替换为jakarta.servlet.*
。import jakarta.servlet.*; import jakarta.servlet.http.*;
然后您可以只针对来自基于 Servlet 5.0 的目标运行时的库进行编译。
或者,将 servlet 容器从 Servlet API 版本 5.0 降级到以前的版本,至少是仍然具有
javax.servlet.*
包名称的版本。 Tomcat 9.x 是最新的仍然有旧包。
技术原因是,在从 Java/Jakarta EE 8 到 Jakarta EE 9 的步骤中,所有 javax.*
包都已重命名为 jakarta.*
包。因此自 Jakarta EE 9 以来不再向后兼容。
因此,当您在使用 Tomcat 10 或更新版本时遵循任何仍然使用旧 javax.servlet.*
包的 servlet 教程时,您需要手动换出代码示例中使用的包对于 jakarta.servlet.*
一个。通常它会工作得很好。
另请参阅:
- Apache Tomcat - versions
- (此答案包含 Tomcat 10+、Tomcat 9-、JEE 9+ 和 JEE 8- 的正确
pom.xml
声明的完整示例,只是如果您使用的是 Maven)。
Sree Kumar wrote
Right-click on project -> Build Path -> Configure Build Path... -> Libraries (tab) -> Select Classpath -> Add Library -> Server Runtime -> Select the one you must have added for Tomcat 10.