spring-boot icon indicating copy to clipboard operation
spring-boot copied to clipboard

Document how to downgrade dependencies to use embedded Jetty 11

Open wilkinsona opened this issue 1 year ago • 23 comments

In addition to downgrading the Servlet API to 5.0, we also need to cover the impact that this will have on testing. Framework's Servlet-related mocks require Servlet 6.0 and will fail due to the absence of ServletConnection when run against the Servlet 5.0 API. Similarly, Jetty requires Servlet 5.0 and will fail due to the absence of HttpSessionContext when run against the Servlet 6.0 API. This leaves us with two arrangements that will work:

  1. Tests use the Servlet 6.0 API and avoid starting Jetty by only using a mock web environment
  2. Tests use the Servlet 5.0 API and avoid using Framework's Servlet mocks by only using a full-blown web environment

If a mixture of web environments is required by an application's tests, it can be done but it may require some structural changes to separate the two web environments. With Gradle this could be done with different source sets or separate modules. With Maven, I believe separate modules will always be required.

wilkinsona avatar Nov 07 '22 17:11 wilkinsona

Hi @wilkinsona,

I'm facing this issue in a real application, not only in tests. Do you know how to fix it?

Starters added:

  • spring-boot-starter-web
    • exclude
      • spring-boot-starter-tomcat
  • spring-boot-starter-jetty
  • spring-boot-starter-amqp
  • spring-boot-starter-data-redis
  • spring-boot-starter-actuator
  • spring-boot-starter-validation
  • spring-boot-starter-json
  • spring-boot-starter-webflux
  • spring-boot-starter-data-jpa

Version: 3.0.0-RC2

Error trace:

java.lang.ClassNotFoundException: jakarta.servlet.http.HttpSessionContext
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	... 41 common frames omitted
Wrapped by: java.lang.NoClassDefFoundError: jakarta/servlet/http/HttpSessionContext
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	at org.eclipse.jetty.server.session.SessionHandler.<clinit>(SessionHandler.java:136)
	at org.eclipse.jetty.servlet.ServletContextHandler.newSessionHandler(ServletContextHandler.java:339)
	at org.eclipse.jetty.servlet.ServletContextHandler.getSessionHandler(ServletContextHandler.java:432)
	at org.eclipse.jetty.servlet.ServletContextHandler.relinkHandlers(ServletContextHandler.java:257)
	at org.eclipse.jetty.servlet.ServletContextHandler.<init>(ServletContextHandler.java:180)
	at org.eclipse.jetty.webapp.WebAppContext.<init>(WebAppContext.java:301)
	at org.eclipse.jetty.webapp.WebAppContext.<init>(WebAppContext.java:228)
	at org.springframework.boot.web.embedded.jetty.JettyEmbeddedWebAppContext.<init>(JettyEmbeddedWebAppContext.java:28)
	at org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory.getWebServer(JettyServletWebServerFactory.java:158)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:183)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:161)
	... 21 common frames omitted
Wrapped by: org.springframework.context.ApplicationContextException: Unable to start web server
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:164)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:578)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)

david-romero avatar Nov 18 '22 07:11 david-romero

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0.0-RC2-Release-Notes#jetty

wilkinsona avatar Nov 18 '22 08:11 wilkinsona

Would it be possible to let spring-boot-starter-jetty have different dependencies?

Currently, both the Maven pom and the Gradle module explicitly request Servlet 6:

   <dependency>
     <groupId>jakarta.servlet</groupId>
     <artifactId>jakarta.servlet-api</artifactId>
     <version>6.0.0</version>
     <scope>compile</scope>
   </dependency>

https://repo.spring.io/artifactory/milestone/org/springframework/boot/spring-boot-starter-jetty/3.0.0-RC2/spring-boot-starter-jetty-3.0.0-RC2.pom

       {
         "group": "jakarta.servlet",
         "module": "jakarta.servlet-api",
         "version": {
           "requires": "6.0.0"
         }
       },

https://repo.spring.io/artifactory/milestone/org/springframework/boot/spring-boot-starter-jetty/3.0.0-RC2/spring-boot-starter-jetty-3.0.0-RC2.module

larsgrefer avatar Nov 20 '22 23:11 larsgrefer

It's possible, although it would require some surgery to Spring Boot's build. For the vast majority of users it would have no benefit as Spring Boot's dependency management would upgrade the dependency to 6.0.0 again anyway. When we were in a similar situation with Jetty in Spring Boot 2.x (when Jetty did not support Servlet 4.0 and Tomcat and Undertow did), we used the current arrangement and it seemed to work well.

wilkinsona avatar Nov 21 '22 08:11 wilkinsona

For the runtime setup, this works easily enough indeed, but as you rightly point out in the first message this isn't nearly as easy to work with for the test side of things (at least right now), and splitting tests into different maven modules is a rather nuclear approach to the issue.

So, realistically, most affected users will have to just stall the upgrade till Jetty supports servlet-api 6. Which might be fine or not, depending on how long it will likely take to happen. Couldn't find a reference to the matter on their repo but I'm also not too familiar with how they manage their roadmap for the upcoming Jetty 12 (which I imagine is the one that will target servlet-api 6)

Tristan971 avatar Nov 21 '22 08:11 Tristan971

Actually, scratch that, found someone asking the same question for the same reasons here https://www.eclipse.org/lists/jetty-users/msg10348.html

Quoting:

Date: Wed, 9 Nov 2022 13:59:43 -0600 Jetty 12 already has Alpha quality releases out that you can use to start experimenting with. We should be going to Betas (or Release candidates) in the next few weeks. Joakim Erdfelt / joakim@xxxxxxxxxxx

So hopefully not too long of a weird inter-version timeframe all-in-all (barring the usual delays one should expect with software development, ofc)

Tristan971 avatar Nov 21 '22 09:11 Tristan971

Unfortunately, as I understand it, there are some fairly significant breaking changes in Jetty 12. I believe @rstoyanchev saw quite a big impact on Spring Framework's WebSocket integration, for example. As such, Jetty 12 support may take some time to fully materialise.

wilkinsona avatar Nov 21 '22 09:11 wilkinsona

It's possible, although it would require some surgery to Spring Boot's build. For the vast majority of users it would have no benefit as Spring Boot's dependency management would upgrade the dependency to 6.0.0 again anyway. When we were in a similar situation with Jetty in Spring Boot 2.x (when Jetty did not support Servlet 4.0 and Tomcat and Undertow did), we used the current arrangement and it seemed to work well.

Something like this in spring-boot-project/spring-boot-starters/spring-boot-starter-jetty/build.gradle should do the trick (at least for Gradle users):

    api("jakarta.servlet:jakarta.servlet-api") {
        version {
            strictly "5.0.0"
            because "Jetty 11 does not support Servlet 6 yet"
        }
    }

larsgrefer avatar Nov 21 '22 22:11 larsgrefer

Unfortunately, it's not that simple. Internally, Boot's build is structured such our dependency management is enforced. This ensures that we know that we're compiling and testing against the versions in our dependency management. As I said, it would require some surgery to use a different version in spring-boot-starter-jetty. We don't believe it's worth it.

wilkinsona avatar Nov 22 '22 07:11 wilkinsona

FTR, this is how you get a working setup with gradle:

ext['jakarta-servlet.version'] = '5.0.0'

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation("org.springframework.boot:spring-boot-starter-jetty")
	modules {
		module("org.springframework.boot:spring-boot-starter-tomcat") {
			replacedBy("org.springframework.boot:spring-boot-starter-jetty", "Use Jetty instead of Tomcat")
		}
	}
}

mhalbritter avatar Nov 24 '22 11:11 mhalbritter

Unfortunately, it's not that simple. Internally, Boot's build is structured such our dependency management is enforced. This ensures that we know that we're compiling and testing against the versions in our dependency management. As I said, it would require some surgery to use a different version in spring-boot-starter-jetty. We don't believe it's worth it.

Ok, but for end users a fix would look like:

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>jakarta.servlet</groupId>
			<artifactId>jakarta.servlet-api</artifactId>
			<version>5.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-dependencies</artifactId>
			<version>3.0.0</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

?

We have a company wide BOM so my plan is to do something like this unless there's another concern not do so.

lpandzic avatar Nov 25 '22 08:11 lpandzic

Yes, I believe that will work as your dependency management for jakarta.servlet-api is nearer to the root so it will take precedence over what's in the imported spring-boot-dependencies.

wilkinsona avatar Nov 25 '22 11:11 wilkinsona

This leaves us with two arrangements that will work:

Tests use the Servlet 6.0 API and avoid starting Jetty by only using a mock web environment Tests use the Servlet 5.0 API and avoid using Framework's Servlet mocks by only using a full-blown web environment

The first option seems simple, that sounds like using @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) which is the default.

How would we go about using the second option which avoids using Framework's Servlet mocks?

EDIT: The second option would let you use WebEnvironment.RANDOM_PORT, DEFINED_PORT and NONE.

Sineaggi avatar Nov 28 '22 21:11 Sineaggi

Hi @wilkinsona,

I'm facing this issue in a real application, not only in tests. Do you know how to fix it?

Starters added:

  • spring-boot-starter-web

    • exclude

      • spring-boot-starter-tomcat
  • spring-boot-starter-jetty

  • spring-boot-starter-amqp

  • spring-boot-starter-data-redis

  • spring-boot-starter-actuator

  • spring-boot-starter-validation

  • spring-boot-starter-json

  • spring-boot-starter-webflux

  • spring-boot-starter-data-jpa

Version: 3.0.0-RC2

Error trace:

java.lang.ClassNotFoundException: jakarta.servlet.http.HttpSessionContext
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	... 41 common frames omitted
Wrapped by: java.lang.NoClassDefFoundError: jakarta/servlet/http/HttpSessionContext
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	at org.eclipse.jetty.server.session.SessionHandler.<clinit>(SessionHandler.java:136)
	at org.eclipse.jetty.servlet.ServletContextHandler.newSessionHandler(ServletContextHandler.java:339)
	at org.eclipse.jetty.servlet.ServletContextHandler.getSessionHandler(ServletContextHandler.java:432)
	at org.eclipse.jetty.servlet.ServletContextHandler.relinkHandlers(ServletContextHandler.java:257)
	at org.eclipse.jetty.servlet.ServletContextHandler.<init>(ServletContextHandler.java:180)
	at org.eclipse.jetty.webapp.WebAppContext.<init>(WebAppContext.java:301)
	at org.eclipse.jetty.webapp.WebAppContext.<init>(WebAppContext.java:228)
	at org.springframework.boot.web.embedded.jetty.JettyEmbeddedWebAppContext.<init>(JettyEmbeddedWebAppContext.java:28)
	at org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory.getWebServer(JettyServletWebServerFactory.java:158)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:183)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:161)
	... 21 common frames omitted
Wrapped by: org.springframework.context.ApplicationContextException: Unable to start web server
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:164)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:578)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)

we are facing the same issue during startup but with 3.0.0 released version. Thought we can directly jump to Boot 3 with our new service but it looks like we have to wait...

crusi avatar Dec 05 '22 19:12 crusi

There are workarounds for both Maven and Gradle:

Maven

    <properties>
        <jakarta-servlet.version>5.0.0</jakarta-servlet.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
    </dependencies>

Gradle

ext['jakarta-servlet.version'] = '5.0.0'

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation("org.springframework.boot:spring-boot-starter-jetty")
	modules {
		module("org.springframework.boot:spring-boot-starter-tomcat") {
			replacedBy("org.springframework.boot:spring-boot-starter-jetty", "Use Jetty instead of Tomcat")
		}
	}
}

Does that work for you?

mhalbritter avatar Dec 06 '22 07:12 mhalbritter

Hi, just wanted to report that for me, the gradle-based version adjustment you suggest did not work, it kept pulling version 6 in. Digging through the code a little, I also did not find how that mechanism would work, the only references I found were related to maven.

What worked for me was the following snippet, based on this link: https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/#managing-dependencies.gradle-bom-support.customizing

        configurations.all {          
          resolutionStrategy.eachDependency { DependencyResolveDetails details ->
            if (details.requested.group == 'jakarta.servlet') {
              details.useVersion '5.0.0'
            }
          }
        }

hborchardt avatar Dec 14 '22 15:12 hborchardt

FTR, this is how you get a working setup with gradle:

ext['jakarta-servlet.version'] = '5.0.0'

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation("org.springframework.boot:spring-boot-starter-jetty")
	modules {
		module("org.springframework.boot:spring-boot-starter-tomcat") {
			replacedBy("org.springframework.boot:spring-boot-starter-jetty", "Use Jetty instead of Tomcat")
		}
	}
}

This seems to be working. Thanks.

eocak avatar Dec 20 '22 10:12 eocak

Found a temporary fix for the problem. Move back to Jakarta 6.0.0 and add the following dependency:


<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>${jetty.version}</version>
</dependency>

With the latest version of jetty-server.

With this the service starts up and the unit tests with MockMvc works as expected.

Tak1za avatar Jan 12 '23 04:01 Tak1za

I tried the maven approach above, I tried adding the <jakarta-servlet.version>5.0.0</jakarta-servlet.version> in Maven properties, yet still no luck. Also tried the other approaches. But still getting that classes are not found.

simenaj96 avatar Mar 09 '23 08:03 simenaj96

I've had the same issue, and the previously suggested options were not working for everything. Either the service would start or all the tests (inc mockmvc) would succeed. But not everything. :-(

In the end, this setup has worked for all:

    ext {
        set("jakarta-servlet.version", '5.0.0')
    }

plus:

    testImplementation 
            'org.eclipse.jetty:jetty-server:11.0.14',
            'jakarta.servlet:jakarta.servlet-api:6.0.0',

tasosz avatar Mar 31 '23 13:03 tasosz

@tasosz @simenaj96 Did you try set only 'org.eclipse.jetty:jetty-server:11.0.14' in implementation section?

nibexo avatar Mar 31 '23 19:03 nibexo

I also tried the maven workarounds but still no success. I also tried to ugprade to jetty 12 beta maven plugin, but that didn't help. It's still the test that fail

Siedlerchr avatar Apr 29 '23 21:04 Siedlerchr

Update:

      <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
        </dependency>

        
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>${jetty.version}</version>
</dependency>

with

<properties>
<jetty.version>11.0.15</jetty.version>
<jakarta-servlet.version>5.0.0</jakarta-servlet.version>

</properties> 

worked

Siedlerchr avatar May 04 '23 15:05 Siedlerchr

In order to use jetty AND being able to run the unit test with spring boot 3.0.x, we use the following approach:

  • downgrade jakarta-servlet version to 5.0.0 as explained in the release notes
<properties>
   <jakarta-servlet.version>5.0.0</jakarta-servlet.version>
</properties> 

  • copy and paste in the src/test/java folder the interface jakarta.servlet.ServerConnection.java. It seems adding this interface in the test classpath is enough to fix one of the main issue to run unit tests. Source code for this interface can be found here.

Obviously, the second part is clearly a hack. I'm not sure to which extend we can trust the result of unit tests (but at least they can run)....

Nowheresly avatar May 12 '23 11:05 Nowheresly

@Nowheresly yours is a partial fix and works because the mockhttprequest (iirc) explicitly mocks this interface. However if you play with cookies, you'll get another error, since the Cookie class has been heavily modified.

Our "solution" is to package a local servlet-api with the cookie and servletconnection copied back.

Of course this will break should spring tests end up deliberately or accidentally referring to servlet 6 only other stuff.

https://github.com/opentable/servlet/compare/5.0.0-RELEASE...opentable:servlet:5.9.0 basically makes the idea concrete.

Another limitation besides the inherent fragility is of course you CANNOT open source any thing built with this, since of course the patched version doesn't exist in maven central.

I hasten to add this is a no good fragile solution. If Spring changes or another third party relies on Servlet 6 and uses it's methods, one will live to regret this solution

mikebell90 avatar Jun 21 '23 22:06 mikebell90

Hi, is there any updates? Thanks!

fzyzcjy avatar Jul 24 '23 23:07 fzyzcjy

@fzyzcjy No, I'm afraid not. We work in the open so any updates will appear in this issue. Anything that may be documented is already described in this issue.

wilkinsona avatar Jul 25 '23 07:07 wilkinsona

Thanks @Tak1za.

In the end it looks like this for me with gradle.

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-jetty")
    modules {
        module("org.springframework.boot:spring-boot-starter-tomcat") {
            replacedBy("org.springframework.boot:spring-boot-starter-jetty", "Use Jetty instead of Tomcat")
        }
    }
    implementation("org.eclipse.jetty:jetty-server:11.0.15")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

renannprado avatar Aug 09 '23 16:08 renannprado

Unfortunately, no of the suggestions above worked for me at all. I tried with jetty-server 12.0.1, servlet-api 5.0.0/6.0.0, spring-boot-dependencies 3.1.3 in the dependency-management, ...I always get: org.eclipse.jetty.server.handler.HandlerWrapper

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory]: Factory method 'jettyServletWebServerFactory' threw exception with message: org/eclipse/jetty/server/handler/HandlerWrapper
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655)
	... 97 more
Caused by: java.lang.NoClassDefFoundError: org/eclipse/jetty/server/handler/HandlerWrapper
	at org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedJetty.jettyServletWebServerFactory(ServletWebServerFactoryConfiguration.java:93)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139)
	... 98 more
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.server.handler.HandlerWrapper
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)

du-it avatar Sep 07 '23 10:09 du-it

@du-it Did you try use version 11.0.14 instead 12.0.1?

nibexo avatar Sep 07 '23 10:09 nibexo