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

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

问题描述

我正在尝试从命令行编译和部署一个简单的 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;导入 javax.servlet.*;导入 javax.servlet.http.*;导入 java.io.*;公共类 BeerSelect 扩展 HttpServlet {public void doPost(HttpServletRequest 请求,HttpServletResponse 响应)抛出 IOException,ServletException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("啤酒选择建议<br>");String c = request.getParameter(颜色");out.println(<br>有啤酒颜色" + c);}}

当我尝试用 servlet-api.jar 编译它时,我得到:

public class BeerSelect extends HttpServlet {^符号:类 HttpServletsrccomexamplecontrollersBeerSelect.java:9: 错误:找不到符号public void doPost(HttpServletRequest 请求,^符号:类 HttpServletRequest地点:类 BeerSelectsrccomexamplecontrollersBeerSelect.java:10: 错误:找不到符号HttpServletResponse 响应)^符号:类 HttpServletResponse地点:类 BeerSelectsrccomexamplecontrollersBeerSelect.java:11: 错误:找不到符号抛出 IOException,ServletException {^符号:类 ServletException地点:类 BeerSelectsrccomexamplecontrollersBeerSelect.java:3: 错误:包 javax.servlet 不存在导入 javax.servlet.*;^srccomexamplecontrollersBeerSelect.java:4: 错误:包 javax.servlet.http 不存在导入 javax.servlet.http.*;^6 错误

然而,javax.servlet-api-4.0.1 编译成功.注意:我已经测试并排除了命令行命令作为问题的可能原因.

当我将.class文件放在对应的Tomcat目录下,启动服务器并尝试与app交互时,出现如下异常:

异常jakarta.servlet.ServletException:实例化 servlet 类 [com.example.controllers.BeerSelect] 时出错根本原因java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet根本原因java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet

我尝试将 javax.servlet-api-4.0.1 放在 Tomcat/lib 目录中,但是我得到:

异常jakarta.servlet.ServletException: Class [com.example.controllers.BeerSelect] 不是 Servlet根本原因java.lang.ClassCastException: 类 com.example.controllers.BeerSelect 不能转换为类 jakarta.servlet.Servlet(com.example.controllers.BeerSelect 在加载器 org.apache.catalina.loader.ParallelWebappClassLoader @7862f56 的未命名模块中;jakarta.servlet.Servlet 位于加载程序 java.net.URLClassLoader @4b4523f8 的未命名模块中)

不确定最后一个是否有意义,但我的想法用完了.

非常欢迎任何帮助!

解决方案

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

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

<块引用>

我尝试将 javax.servlet-api-4.0.1 放在 Tomcat/lib 目录中,但是我得到:

java.lang.ClassCastException: class com.example.controllers.BeerSelect无法转换为 jakarta.servlet.Servlet 类

jakarta.servlet.Servlet 是 Servlet API 5.0 版的一部分,而后者又是 Jakarta EE 9 版的一部分.您的 servlet 实际上是从 javax.servlet.Servlet 反过来又是旧 JEE 版本的一部分,实际上您的目标运行时 (Tomcat 10.x) 不支持该版本.

您有两个选择:

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

    import jakarta.servlet.*;导入 jakarta.servlet.http.*;

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

  2. 或者,将 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.* 的示例之一.通常它会工作得很好.

另见:

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

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.

I am using:

  • javac 11.0.8
  • Apache Tomcat 10.0 (servlet-api.jar 5.0)

Java file:

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);
    }               
} 

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

public class BeerSelect extends HttpServlet {
                                ^
  symbol: class HttpServlet
srccomexamplecontrollersBeerSelect.java:9: error: cannot find symbol
        public void doPost(HttpServletRequest request,
                           ^
  symbol:   class HttpServletRequest
  location: class BeerSelect
srccomexamplecontrollersBeerSelect.java:10: error: cannot find symbol
                        HttpServletResponse response)
                        ^
  symbol:   class HttpServletResponse
  location: class BeerSelect
srccomexamplecontrollersBeerSelect.java:11: error: cannot find symbol
                        throws IOException, ServletException {
                                            ^
  symbol:   class ServletException
  location: class BeerSelect
srccomexamplecontrollersBeerSelect.java:3: error: package javax.servlet does not exist
import javax.servlet.*;
^
srccomexamplecontrollersBeerSelect.java:4: error: package javax.servlet.http does not exist
import javax.servlet.http.*;
^
6 errors 

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.

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

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.

Any help is more than welcome!

解决方案

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

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

You have 2 options:

  1. Replace the javax.servlet.* imports in your code by jakarta.servlet.* ones.

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

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

  2. 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.

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.

So, when following any servlet tutorials which still use the old javax.servlet.* package while you're using Tomcat 10 or newer, then you need to manually swap out the package used in code examples for the jakarta.servlet.* one. Generally it'll work just fine.

See also:

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

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