perwendel / spark

A simple expressive web framework for java. Spark has a kotlin DSL https://github.com/perwendel/spark-kotlin
Apache License 2.0
9.65k stars 1.56k forks source link

2.9.2 breaks serving via Tomcat #1203

Open thomas4g opened 3 years ago

thomas4g commented 3 years ago

Something between 2.9.1 and 2.9.2 breaks serving of Spark apps via Tomcat using the SparkFilter. Specifically, Tomcat throws "Error starting child" which is ultimately caused by java.lang.IllegalStateException: Unable to find ServletContextHandler for provided ServletContext (full stack trace below).

For context, I have a pretty standard Spark App with a basic web.xml that sets up the SparkFilter. I package as a WAR and upload to Tomcat.

I've verified this issue begins in 2.9.2 through 2.9.3, by testing from 2.5.4 through 2.9.1 with no problems.

I'll continue to investigate this, as I'd like to get the security patches from 2.9.2 & 2.9.3. But if anyone has encountered before, would definitely appreciate it!

mccoder commented 3 years ago

My solution

Exclude Jetty, tomcat use own websocket

Gradle config

api("com.sparkjava:spark-core:2.9.3") {
            exclude group: "org.eclipse.jetty", module: "jetty-server"
            exclude group: "org.eclipse.jetty", module: "jetty-webapp"
            exclude group: "org.eclipse.jetty.websocket", module: "websocket-servlet"
            exclude group: "org.eclipse.jetty.websocket", module: "websocket-server"
    }

        compileOnly("javax.servlet:javax.servlet-api")
        compileOnly "org.eclipse.jetty:jetty-server"
        compileOnly "org.eclipse.jetty:jetty-webapp"
        compileOnly "org.eclipse.jetty.websocket:websocket-servlet"
        compileOnly "org.eclipse.jetty.websocket:websocket-server"

Create HttpServlet, and register, without servlet filter not working

import javax.servlet.http.HttpServlet;

public class DefaultServlet extends HttpServlet {}

append to web.xml

    <servlet>
        <servlet-name>DefaultServlet</servlet-name>
        <servlet-class>DefaultServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DefaultServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>