Tomcat 10.0.4 doesn't load servlets (@WebServlet classes) with 404 error [duplicate]

I'm having a problem with my first Web Application. I use IntelliJ as IDE and Tomcat as Webserver. Every servlet I've tried to acces, throws an 404 Error. Even if I copy some youtube tutorials, which seems to work like a charm.

The button in the form sends me to: http://localhost:8080/IUBHQuiz/login

Can you tell me whats wrong? I am going nuts.

login.java

package com.example.IUBHQuiz;

import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.sql.*;

@WebServlet("/login")
public class login extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        String email = request.getParameter("fmail");
        String pass = request.getParameter("fpw");

        if(email.equals("j") && pass.equals("j"))
        {
            RequestDispatcher rs = request.getRequestDispatcher("/main.jsp");
            rs.forward(request, response);
        }
        else
        {
            out.println("Username or Password incorrect");

            RequestDispatcher rs = request.getRequestDispatcher("/index.jsp");
            rs.include(request, response);
        }

        out.close();
    }

index.jsp

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <title>IUBH Quiz</title>
    <link href="./resources/css/style.css" rel="stylesheet">
</head>
<body>
    <div class="main">
        <div class="image-container">
           <img src="./resources/images/logo.png" alt="Logo">
        </div>
        <div class="Login">
            <h1>Willkommen beim IUBH-Quiz!</h1>
            <form action="login" method="post">
                E-Mail:<input type="text" id="fmail" name="fmail"><br><br>
                Passwort: <input type="password" id="fpw" name="fpw"><br><br>
                <input type="submit" value="Log In" class="button">
            </form>
        </div>
        <div class="Links">
            <a href="#">Passwort vergessen</a>
            <a href="#">Registrieren</a>
        </div>
    </div>
</body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
</web-app>

Solution 1:

For copyright reasons the Servlet 5.0 API (implemented by Tomcat 10) and the Servlet 4.0 API (implemented by Tomcat 9) are incompatible: the API namespace changed from javax.* to jakarta.*. This can manifest in many ways:

  1. Software written for Servlet 4.0 does not compile against the API jars from Tomcat 10: cf. Servlet 5.0 JAR throws compile error on javax.servlet.* but Servlet 4.0 JAR does not,
  2. Servlet 4.0 applications which use a web.xml descriptor throw a lot of ClassNotFoundExceptions and don't start: cf. Tomcat 10.x throws java.lang.NoClassDefFoundError on javax/servlet/ServletRequestListener.
  3. Servlet 4.0 applications which use a web.xml descriptor log a "X is not a jakarta.servlet.Servlet" error: cf. Servlet class org.restlet.ext.servlet.ServerServlet is not a jakarta.servlet.Servlet.
  4. Servlet 4.0 applications which use annotations to declare servlets stop working, as in your case,
  5. Servlet 4.0 applications which rely on a ServletContainerInitializer (like Spring and Spring Boot applications) don't start: cf. Deploying Spring MVC 5 on Tomcat 10 … deployment problems

The last one is the hardest to diagnose: no errors are written to the log files, but the application doesn't work. The reason behind this behavior is that @javax.servlet.WebServlet annotations are ignored: the server is scanning for @jakarta.servlet.WebServlet.

Since all three problems have the same cause, the solutions provided to the aforementioned questions all work. In this specific case I would advise to use the Tomcat Migration Tool for Jakarta EE.

Remark: The Tomcat download site features a warning, that unfortunately many people don't notice:

Users of Tomcat 10 onwards should be aware that, as a result of the move from Java EE to Jakarta EE as part of the transfer of Java EE to the Eclipse Foundation, the primary package for all implemented APIs has changed from javax.* to jakarta.*. This will almost certainly require code changes to enable applications to migrate from Tomcat 9 and earlier to Tomcat 10 and later.

Solution 2:

I had the same issue while reproducing the problem reported at IntelliJ IDEA forums.

It didn't work with Tomcat 10 for the reasons described in the answer by Piotr P. Karwasz, but it works just fine with Tomcat 9.0.44 and earlier versions.