java.lang.ClassCastException: class クラス名 cannot be cast to class jakarta.servlet.Servlet

# 解決策

jakarta.servlet-apiを依存関係に設定する。

```build.gradle
dependencies {
     // https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api
     compileOnly group: 'jakarta.servlet', name: 'jakarta.servlet-api', version: '5.0.0'
 }
```

## 補足

Jakartaについては↓
[Jakarta Servlet 5.0 | The Eclipse Foundation](https://jakarta.ee/specifications/servlet/5.0/) 

# 背景

Tomcat 10のサンプルアプリと同じものを自分で作成しようとしていた。
サンプルアプリのページは↓
https://tomcat.apache.org/tomcat-10.0-doc/appdev/sample/

>Example Application - This directory contains a very simple, but functionally complete, "Hello, World" application built according to the principles described in this manual. You can use this application to practice using the described techniques.
>https://tomcat.apache.org/tomcat-10.0-doc/appdev/

アプリはGradleで作成したwarを、Dockerで立ち上げたTomcatにデプロイする想定で作成していた。

## 補足

Tomcatは [Image Layer Details - tomcat:10-jdk11-corretto -](https://hub.docker.com/layers/tomcat/library/tomcat/10-jdk11-corretto/images/sha256-2e2054f781fceca097690e995d9e86096a7f1e9f73a5d3e5aa06e782c721eb65?context=explore)を使っていた。

# 問題

デプロイし、ページにアクセスすると以下のエラー画面が…。

![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131659/656d8a60-5d74-6659-7c83-3aabfd5a22f5.png)

```
HTTPステータス 500 – Internal Server Error

jakarta.servlet.ServletException: Class [mypackage.Hello] is not a Servlet
	org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
	org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)

根本原因

java.lang.ClassCastException: class mypackage.Hello cannot be cast to class jakarta.servlet.Servlet (mypackage.Hello is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @2a898881; jakarta.servlet.Servlet is in unnamed module of loader java.net.URLClassLoader @71423665)
	org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
	org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
```

## 補足

[ClassCastException (Java SE 11 & JDK 11 )](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/lang/ClassCastException.html)
>public class ClassCastException
extends RuntimeException
あるオブジェクトを継承関係にないサブクラスにキャストしようとしたことを示すためにスローされます。 たとえば、次のコードはClassCastExceptionを生成します。
     Object x = new Integer(0);
     System.out.println((String)x); 

# 原因

javax.servlet-apiを依存関係に設定していたため。

```build.gradle
 dependencies {
 	// https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api
 	compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
 }
```

公式にちゃんと書いてありました…。Tomcat10からAPI変わってたんですねえ…。
[Apache Tomcat® - Welcome!](https://tomcat.apache.org/index.html)

>Tomcat 10.0.2 Released 2021-02-02
> The Apache Tomcat Project is proud to announce the release of version 10.0.2 of Apache Tomcat. This release is the first stable release in the 10.0.x series and is targeted at Jakarta EE 9.
> 
> 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. A migration tool is under development to aid this process.