Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Servlet 5.0 JAR throws compile error on javax.servlet.* but Servlet 4.0 JAR does not

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

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!

like image 921
msTam Avatar asked Oct 16 '20 10:10

msTam


People also ask

How to handle exceptions in servlet?

When a servlet throws an exception, the web container searches the configurations in web. xml that use the exception-type element for a match with the thrown exception type. You would have to use the error-page element in web.

What is the current version of servlet?

The current version of Servlet is 5.0.

What is Java servlet specification?

The Java Servlet specificationIt defines how the server will send requests and responses during network interactions over HTTP. All Java servers must be compatible with the Java Servlet specification. Most Java servers today are compatible with Servlet 4.0.


1 Answers

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:

  • 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).
like image 112
BalusC Avatar answered Oct 19 '22 23:10

BalusC