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

查看:145
本文介绍了Servlet 5.0 JAR会在javax.servlet.*上引发编译错误,但Servlet 4.0 JAR不会的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to compile and deploy a simple web app from command line.

servlet-api.jar不能编译我的java文件,但是来自maven中央存储库的javax.servlet-api-4.0.1可以成功编译它.即便如此,当我部署该应用程序并尝试在浏览器中使用它时,也会出现错误.

servlet-api.jar from Apache Tomcat does not compile my java file, but javax.servlet-api-4.0.1 from the maven central repository compiles it successfully. Even so, I get an error when I deploy the app and try to use it in the browser.

我正在使用:

  • 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进行编译时,我得到:

When I try to compile it with the servlet-api.jar I get:

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成功编译了文件.注意:我已经测试并排除了命令行命令是造成此问题的可能原因.

However, javax.servlet-api-4.0.1 compiles the file successfully. Note: I've already tested and ruled out command-line command as a possible cause of the problem.

当我将.class文件放在相应的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:

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目录中,但随后得到:

I tried placing the javax.servlet-api-4.0.1 in the Tomcat/lib directory, but then I get:

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)

不确定最后一种方法是否有意义,但我的想法没了.

Not sure the last makes any sense, but I ran out of ideas.

欢迎任何帮助!

推荐答案

当我将.class文件放在相应的Tomcat目录中,启动服务器并尝试与该应用进行交互时,出现以下异常:

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

jakarta.servlet.Servlet 是Servlet API版本5.0的一部分,而Servlet API版本5.0又是Jakarta EE版本9的一部分.您的servlet实际上是从 javax.servlet.Servlet

The jakarta.servlet.Servlet is part of Servlet API version 5.0 which in turn is part of Jakarta EE version 9. Your servlet is actually extending from javax.servlet.Servlet which in turn is part of an older JEE version which is actually not supported by your target runtime (Tomcat 10.x).

您有2个选择:

  1. jakarta.servlet.* 替换代码中的 javax.servlet.* 导入.

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

然后,您可以从基于Servlet 5.0的目标运行时中针对库进行编译.

Then you can just compile against the libraries from a Servlet 5.0 based target runtime.

或者,将Servlet容器从Servlet API 5.0版降级到以前的版本,至少一个仍具有 javax.servlet.* 包名称的容器.Tomcat 9.x是最新的版本,但仍带有旧软件包.

Or, downgrade the servlet container from Servlet API version 5.0 to a previous version, at least the one still having the javax.servlet.* package name. Tomcat 9.x is the latest one still having the old package.

技术原因是在从Java/Jakarta EE 8到Jakarta EE 9的步骤中,所有 javax.* 软件包都被重命名为 jakarta.* 软件包.因此,自Jakarta EE 9起,就不再存在向后兼容性.

The technical reason is that during the step from Java/Jakarta EE 8 to Jakarta EE 9 all javax.* packages have been renamed to jakarta.* packages. So there is no backwards compatibility anymore since Jakarta EE 9.

  • Apache Tomcat - versions
  • Tomcat casting servlets to javax.servlet.Servlet instead of jakarta.servlet.http.HttpServlet (this answer contains complete examples of proper pom.xml declarations for Tomcat 10+, Tomcat 9-, JEE 9+ and JEE 8-, just in case you're using Maven).

这篇关于Servlet 5.0 JAR会在javax.servlet.*上引发编译错误,但Servlet 4.0 JAR不会的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆