UnavailableException: Servlet class is not a javax.servlet.Servlet with Jetty

908 Views Asked by At

The example given on the plugin page throws an exception when updated with the latest version of the jetty container and the jakarta package.

It expects old class 'javax.servlet.Servlet' not new 'jakarta.servlet.Servlet'

os: Ubuntu 22.10
java: openjdk version "11.0.11" 2021-04-20
scala: 2.13.10

build.sbt

ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.13.10"

lazy val root = (project in file("."))
  .settings(
    name := "MyServlet"
  )

val jakartaServletApiVersion = "6.0.0"
val jettyVersion = "11.0.13"

libraryDependencies += "jakarta.servlet" % "jakarta.servlet-api" % jakartaServletApiVersion

Jetty / containerLibs := Seq("org.eclipse.jetty" % "jetty-runner" % jettyVersion)

enablePlugins(JettyPlugin)

plugins.sbt

addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.4")

web.xml

<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>mypackage.MyServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

MyServlet.scala

package mypackage

import jakarta.servlet.annotation.WebServlet
import jakarta.servlet.http.{HttpServlet, HttpServletRequest, HttpServletResponse}

@WebServlet(urlPatterns = Array("/hello"))
class MyServlet extends HttpServlet {
  println("HEY")

  override def doGet(req: HttpServletRequest, res: HttpServletResponse): Unit = {
    res.setContentType("text/html")

    res.setCharacterEncoding("UTF-8")
    res.getWriter.write("""<h1>Hello, world!</h1>""")
  }
}

Command:

jetty:start

Exception:

UnavailableException: Servlet class mypackage.MyServlet is not a javax.servlet.Servlet

javax.servlet.UnavailableException: Servlet class mypackage.MyServlet is not a javax.servlet.Servlet
    at org.eclipse.jetty.servlet.ServletHolder.checkServletType(ServletHolder.java:514)
    at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:386)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
    at org.eclipse.jetty.servlet.ServletHandler.lambda$initialize$0(ServletHandler.java:730)
    at java.base/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:357)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
    at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:755)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:379)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1449)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1414)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:911)
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:288)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:524)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:117)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:97)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:117)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:97)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169)
    at org.eclipse.jetty.server.Server.start(Server.java:423)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:110)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:97)
    at org.eclipse.jetty.server.Server.doStart(Server.java:387)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
    at org.eclipse.jetty.runner.Runner.run(Runner.java:519)
    at org.eclipse.jetty.runner.Runner.main(Runner.java:564)

Please what am I doing wrong?

1

There are 1 best solutions below

0
On

You have a mix of Jetty versions present in your classpath on your project.

Align them all to one version.

Not sure what your build tooling is like, but Jetty offers a jetty-bom that can help you align your versions of Jetty artifacts, regardless of where they come from in your build (eg: transitive dependencies)

Jetty 11.0.13 uses Jakarta Servlet 5.0, not 6.0

https://github.com/eclipse/jetty.project/blob/jetty-11.0.13/pom.xml#L65

Also, do not use jetty-runner in your build tooling, it's a deprecated concept and is only meant for command line usage of the simplest webapps.

https://github.com/eclipse/jetty.project/blob/jetty-11.0.13/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java#L68-L70

Use jetty-home and a separate jetty-base properly instead.