-
Notifications
You must be signed in to change notification settings - Fork 40.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document how to downgrade dependencies to use embedded Jetty 11 #33044
Comments
Hi @wilkinsona, I'm facing this issue in a real application, not only in tests. Starters added:
Version: 3.0.0-RC2 Error trace:
|
Would it be possible to let Currently, both the Maven pom and the Gradle module explicitly request Servlet 6:
|
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. |
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) |
Actually, scratch that, found someone asking the same question for the same reasons here https://www.eclipse.org/lists/jetty-users/msg10348.html Quoting:
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) |
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. |
Something like this in api("jakarta.servlet:jakarta.servlet-api") {
version {
strictly "5.0.0"
because "Jetty 11 does not support Servlet 6 yet"
}
} |
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 |
FTR, this is how you get a working setup with gradle:
|
Ok, but for end users a fix would look like:
? We have a company wide BOM so my plan is to do something like this unless there's another concern not do so. |
Yes, I believe that will work as your dependency management for |
The first option seems simple, that sounds like using How would we go about using the second option which EDIT: The second option would let you use |
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... |
There are workarounds for both Maven and Gradle: Maven
Gradle
Does that work for you? |
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
|
This seems to be working. Thanks. |
Found a temporary fix for the problem.
With the latest version of jetty-server. With this the service starts up and the unit tests with MockMvc works as expected. |
I tried the maven approach above, I tried adding the |
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:
plus:
|
@tasosz @simenaj96 |
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 |
Update:
with
worked |
In order to use jetty AND being able to run the unit test with spring boot 3.0.x, we use the following approach:
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 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. opentable/servlet@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 |
Hi, is there any updates? Thanks! |
@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. |
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")
} |
Unfortunately, no of the suggestions above worked for me at all.
|
@du-it |
@du-it As I already said on Stack Overflow Jetty 12 is not yet supported. #36073 will add Jetty 12 support and will hopefully be part of Spring Boot 3.2. In the meantime, as @nibexo suggests, you need to use Jetty 11.0.x. |
you save my day. |
A part of this has been done while working on #37238. |
I have a similar issue and I have used something like that
After adding this in configuration of build.gradle my application is working fine but I am getting issue while running the testcase.
Any workaround how to manage both application and testcases for the same. |
I faced the same issue with |
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 ofHttpSessionContext
when run against the Servlet 6.0 API. This leaves us with two arrangements that will work: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.
The text was updated successfully, but these errors were encountered: