当前位置: 首页 > 知识库问答 >
问题:

Servlet 5.0JAR在javax.Servlet.*上抛出编译错误,但Servlet 4.0 JAR没有

金钊
2023-03-14

我正在尝试从命令行编译和部署一个简单的web应用程序。

Apache Tomcat的servlet-api.jar没有编译我的Java文件,但是maven中央存储库的javax.servlet-api-4.0.1成功地编译了它。即便如此,当我部署应用程序并尝试在浏览器中使用它时,我还是会得到一个错误。

我正在使用:

  • 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)

不知道最后一个有什么意义,但我没有主意了。

欢迎任何帮助!

共有2个答案

太叔鸿博
2023-03-14

我已经测试并在Apache Tomcat 9.0.39上编译了Java文件。

目前,Apache Tomcat 10正在开发中,没有稳定的版本:http://Tomcat.Apache.org/whichversion.html

降级您的Apache Tomcat版本应该可以解决这个问题。

颜博达
2023-03-14

当我将.class文件放置在相应的Tomcat目录中,启动服务器并尝试与应用程序交互时,我得到以下异常:

java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet

Jakarta.Servlet.Servlet是Servlet API Version5.0的一部分,而Servlet API Version5.0又是Jakarta EE Version9的一部分。您的servlet实际上是从javax.servlet.servlet扩展而来的,后者又是较旧的JEE版本的一部分,目标运行时(Tomcat10.x)实际上不支持该版本。

您有两个选项:

>

  • 将代码中的javax.servlet.*导入替换为jakarta.servlet.*

    import jakarta.servlet.*;
    import jakarta.servlet.http.*;
    

    然后您就可以从基于Servlet5.0的目标运行时对库进行编译。

    或者,将servlet容器从servlet API Version5.0降级到以前的版本,至少是仍然具有javax.servlet.*包名的版本。Tomcat9.x是最新的一个仍然使用旧包的软件。

    技术原因是,在从Java/Jakarta EE 8到Jakarta EE 9的步骤中,所有javax.*包都被重命名为Jakarta.*包。因此,自Jakarta EE 9以来,再也没有向下兼容了。

    • Apache Tomcat-版本
    • servlet类org.restlet.ext.servlet.ServerServlet不是jakarta.servlet.Servlet
    • 在Tomcat 9上运行时在Maven/Jersey web服务上获取java.lang.ClassNotFoundException:jakarta.servlet.filter

  •  类似资料:
    • 问题内容: 我有一个包,其中导入了javax.servlet。和javax.servlet.http。,当我尝试在命令提示符下对其进行编译时,出现错误 软件包javax.servlet不存在 我使用JDK 1.7.0和Tomcat 6.0。 问题答案: 您需要将Tomcat 文件的路径添加到编译时类路径。 Java需要在类路径中查找导入的依赖项。否则,它将默认为上面示例中包含的当前文件夹。的是Wi

    • 包javax.servlet不存在 我使用JDK1.7.0和Tomcat6.0。

    • 我的任务是创建一个名为MyRectangle的类来表示矩形。 所需的数据字段是宽度、高度和颜色。宽度和高度使用双数据类型,颜色使用字符串。然后编写一个程序来测试MyRectangle类。在客户端程序中,创建两个MyRectangle对象。为两个对象中的每一个指定宽度和高度。将第一个对象指定为红色,将第二个对象指定为黄色。显示两个对象的所有属性,包括其面积。 我已经写了所有的东西,没有错误,但是无论

    • 在上下文路径[/VirtualStore]上部署了基于servlet的web应用程序,但上下文未能从下面的日志开始。 这是如何造成的,我该如何解决?

    • 我使用IntelliJ进行java开发。我想在我只有shell访问权限的另一台主机上运行我的应用程序。 当我在本地运行应用程序时,一切都很好。当我尝试在远程主机上编译代码时,我得到: 文件位于同一目录中: 我也不能在本地编译,除非它来自IDE,所以我假设我只是没有做正确的事情。我错过了什么?我只想能够从shell运行我的应用程序,我真的不在乎如何运行。

    • 项目无法执行maven生命周期映射的两个生命周期阶段: null