You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Already on GitHub?
Sign in
to your account
StackOverflowError when using WebFlux multipart file data handler with Undertow [SPR-16545]
#21088
StackOverflowError when using WebFlux multipart file data handler with Undertow [SPR-16545]
#21088
spring-projects-issues
opened this issue
Mar 2, 2018
· 14 comments
java.lang.StackOverflowError: null
at io.undertow.conduits.FixedLengthStreamSourceConduit.read(FixedLengthStreamSourceConduit.java:249) ~[undertow-core-1.4.22.Final.jar:1.4.22.Final]
at org.xnio.conduits.ConduitStreamSourceChannel.read(ConduitStreamSourceChannel.java:127) ~[xnio-api-3.3.8.Final.jar:3.3.8.Final]
at io.undertow.channels.DetachableStreamSourceChannel.read(DetachableStreamSourceChannel.java:209) ~[undertow-core-1.4.22.Final.jar:1.4.22.Final]
at io.undertow.server.HttpServerExchange$ReadDispatchChannel.read(HttpServerExchange.java:2332) ~[undertow-core-1.4.22.Final.jar:1.4.22.Final]
at org.springframework.http.server.reactive.UndertowServerHttpRequest$RequestBodyPublisher.read(UndertowServerHttpRequest.java:171) ~[spring-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.http.server.reactive.UndertowServerHttpRequest$RequestBodyPublisher.read(UndertowServerHttpRequest.java:127) ~[spring-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.readAndPublish(AbstractListenerReadPublisher.java:145) ~[spring-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.access$1000(AbstractListenerReadPublisher.java:47) ~[spring-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher$State$4.onDataAvailable(AbstractListenerReadPublisher.java:317) ~[spring-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.onDataAvailable(AbstractListenerReadPublisher.java:85) ~[spring-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.http.server.reactive.UndertowServerHttpRequest$RequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:155) ~[spring-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.changeToDemandState(AbstractListenerReadPublisher.java:177) ~[spring-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.access$900(AbstractListenerReadPublisher.java:47) ~[spring-web-5.0.3.RELEASE.jar:5.0.3.RELEASE]
In the process of upgrading the sample, I did find and address one other issue, see #21089. After that, with the latest (Boot 2.0 GA, Spring Framework 5.0.5 snapshot) I am unable to reproduce the Undertow issue. Note that in the sample I removed the explicit (outdated 1.0.2) version of nio-multipart-parser and relied to the Boot auto configured version (1.1.0).
Would you mind retrying with the updates to confirm?
I spend some time trying to get the docker-compose command to run but but failed (and I'm not familiar enough). Is it possible to provide something that doesn't require Docker and Kafka to demonstrate the issue? For example can you make it fail in the webflux-multipart sample?
Looking at your MultimediaHandler, this code looks problematic:
Even then the file reading and calls to importLine are synchronously executed and potentially blocking but they shouldn't block the event loop thread? I'm not sure if the send is blocking or not given it's Kafka. I presume it might in which case you might have to use publishOn.
All of those things aren't the original issue, but again I need a sample I can execute to be more specific or a full stack trace at least.
I have uploaded one without kafka/docker. Thanks for the suggestions.
My original intention was to send each line on the file as it arrives, but then I realized I would need to parse the characters for new line (because a line can be in more parts) so I just do with the tempfile approach.
Okay, thanks for that. I've been able to confirm the recursion issue:
at org.springframework.http.server.reactive.UndertowServerHttpRequest$RequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:156) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.changeToDemandState(AbstractListenerReadPublisher.java:177) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.access$900(AbstractListenerReadPublisher.java:47) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher$State$4.onDataAvailable(AbstractListenerReadPublisher.java:319) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.onDataAvailable(AbstractListenerReadPublisher.java:85) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.http.server.reactive.UndertowServerHttpRequest$RequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:156) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.changeToDemandState(AbstractListenerReadPublisher.java:177) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.access$900(AbstractListenerReadPublisher.java:47) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher$State$4.onDataAvailable(AbstractListenerReadPublisher.java:319) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.http.server.reactive.AbstractListenerReadPublisher.onDataAvailable(AbstractListenerReadPublisher.java:85) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.http.server.reactive.UndertowServerHttpRequest$RequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:156) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
This is triggered by the Expect: 100-continue header that curl sends in this case. However it would happen any time there is back pressure on the input side (i.e. demand present but waiting for data). It works with the "Expect" header forced to be empty:
I did not find anything in the WebFlux documentation, or by searching.
The codecs are documented here. We have planned #21081. Any clues what you searched on, or what you expected to find?
spring webflux ServerRequest.bodyToMono().block will freeze for HTTP post request whose header size + body size > 1024 [SPR-16579]
#21121
StackOverFlowError and memory leaking when sending large files slowly with Webflux + Undertow [SPR-16702]
#21243