Running this unit test:
(note the disableCookieManagement() option)
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
import org.junit.jupiter.api.Test;
import org.springframework.http.client.reactive.HttpComponentsClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;
public class WebClientTest {
@Test
void cookiesDisabledTest() {
CloseableHttpAsyncClient noCookieHttpClient = HttpAsyncClientBuilder.create()
.disableCookieManagement().build();
WebClient webClient = WebClient.builder()
.clientConnector(new HttpComponentsClientHttpConnector(noCookieHttpClient))
.build();
webClient.get().uri("https://spring.io/").exchange().block();
}
}
throws this exception:
org.springframework.web.reactive.function.client.WebClientRequestException: Cannot invoke "org.apache.hc.client5.http.cookie.CookieSpec.parse(org.apache.hc.core5.http.Header, org.apache.hc.client5.http.cookie.CookieOrigin)" because "cookieSpec" is null
at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:137)
Suppressed: The stacktrace has been enhanced by Reactor, refer to additional information below:
Error has been observed at the following site(s):
*__checkpoint ⇢ Request to GET https://spring.io/ [DefaultWebClient]
Original Stack Trace:
at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:137)
at reactor.core.publisher.MonoErrorSupplied.subscribe(MonoErrorSupplied.java:55)
at reactor.core.publisher.Mono.subscribe(Mono.java:4576)
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:222)
at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:222)
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onError(MonoIgnoreThen.java:280)
at reactor.core.publisher.MonoCreate$DefaultMonoSink.error(MonoCreate.java:205)
at org.springframework.http.client.reactive.HttpComponentsClientHttpConnector$ResultCallback.failed(HttpComponentsClientHttpConnector.java:186)
at org.apache.hc.core5.concurrent.BasicFuture.failed(BasicFuture.java:166)
at org.apache.hc.core5.concurrent.ComplexFuture.failed(ComplexFuture.java:79)
at org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient$2$1.failed(InternalAbstractHttpAsyncClient.java:315)
at org.apache.hc.core5.concurrent.BasicFuture.failed(BasicFuture.java:166)
at org.apache.hc.core5.reactive.ReactiveResponseConsumer.failed(ReactiveResponseConsumer.java:143)
at org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient$2.failed(InternalAbstractHttpAsyncClient.java:353)
at org.apache.hc.client5.http.impl.async.AsyncRedirectExec$1.failed(AsyncRedirectExec.java:246)
at org.apache.hc.client5.http.impl.async.AsyncHttpRequestRetryExec$1.failed(AsyncHttpRequestRetryExec.java:195)
at org.apache.hc.client5.http.impl.async.AsyncProtocolExec$1.failed(AsyncProtocolExec.java:295)
at org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec$1.failed(HttpAsyncMainClientExec.java:136)
at org.apache.hc.client5.http.impl.async.LoggingAsyncClientExchangeHandler.failed(LoggingAsyncClientExchangeHandler.java:177)
at org.apache.hc.core5.http.impl.nio.ClientHttp1StreamHandler.failed(ClientHttp1StreamHandler.java:291)
at org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexer.terminate(ClientHttp1StreamDuplexer.java:181)
at org.apache.hc.core5.http.impl.nio.AbstractHttp1StreamDuplexer.shutdownSession(AbstractHttp1StreamDuplexer.java:165)
at org.apache.hc.core5.http.impl.nio.AbstractHttp1StreamDuplexer.onException(AbstractHttp1StreamDuplexer.java:407)
at org.apache.hc.core5.http.impl.nio.AbstractHttp1IOEventHandler.exception(AbstractHttp1IOEventHandler.java:90)
at org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler.exception(ClientHttp1IOEventHandler.java:41)
at org.apache.hc.client5.http.impl.async.LoggingIOSession$1.exception(LoggingIOSession.java:253)
at org.apache.hc.core5.reactor.ssl.SSLIOSession$1.exception(SSLIOSession.java:243)
at org.apache.hc.core5.reactor.InternalDataChannel.onException(InternalDataChannel.java:181)
at org.apache.hc.core5.reactor.InternalChannel.handleIOEvent(InternalChannel.java:55)
at org.apache.hc.core5.reactor.SingleCoreIOReactor.processEvents(SingleCoreIOReactor.java:176)
at org.apache.hc.core5.reactor.SingleCoreIOReactor.doExecute(SingleCoreIOReactor.java:125)
at org.apache.hc.core5.reactor.AbstractSingleCoreIOReactor.execute(AbstractSingleCoreIOReactor.java:92)
at org.apache.hc.core5.reactor.IOReactorWorker.run(IOReactorWorker.java:44)
at java.base/java.lang.Thread.run(Thread.java:1583)
Suppressed: java.lang.Exception: #block terminated with an error
at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:104)
at reactor.core.publisher.Mono.block(Mono.java:1779)
at WebClientTest.cookiesDisabledTest(WebClientTest.java:16)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: java.lang.NullPointerException: Cannot invoke "org.apache.hc.client5.http.cookie.CookieSpec.parse(org.apache.hc.core5.http.Header, org.apache.hc.client5.http.cookie.CookieOrigin)" because "cookieSpec" is null
at org.springframework.http.client.reactive.HttpComponentsClientHttpResponse.adaptCookies(HttpComponentsClientHttpResponse.java:79)
at org.springframework.http.client.reactive.HttpComponentsClientHttpResponse.<init>(HttpComponentsClientHttpResponse.java:62)
at org.springframework.http.client.reactive.HttpComponentsClientHttpConnector$ResponseCallback.completed(HttpComponentsClientHttpConnector.java:153)
at org.springframework.http.client.reactive.HttpComponentsClientHttpConnector$ResponseCallback.completed(HttpComponentsClientHttpConnector.java:135)
at org.apache.hc.core5.concurrent.BasicFuture.completed(BasicFuture.java:148)
at org.apache.hc.core5.reactive.ReactiveResponseConsumer.consumeResponse(ReactiveResponseConsumer.java:127)
at org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient$2.handleResponse(InternalAbstractHttpAsyncClient.java:305)
at org.apache.hc.client5.http.impl.async.AsyncRedirectExec$1.handleResponse(AsyncRedirectExec.java:208)
at org.apache.hc.client5.http.impl.async.AsyncHttpRequestRetryExec$1.handleResponse(AsyncHttpRequestRetryExec.java:134)
at org.apache.hc.client5.http.impl.async.AsyncProtocolExec$1.handleResponse(AsyncProtocolExec.java:230)
at org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec$1.consumeResponse(HttpAsyncMainClientExec.java:243)
at org.apache.hc.client5.http.impl.async.LoggingAsyncClientExchangeHandler.consumeResponse(LoggingAsyncClientExchangeHandler.java:142)
at org.apache.hc.core5.http.impl.nio.ClientHttp1StreamHandler.consumeHeader(ClientHttp1StreamHandler.java:249)
at org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexer.consumeHeader(ClientHttp1StreamDuplexer.java:348)
at org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexer.consumeHeader(ClientHttp1StreamDuplexer.java:80)
at org.apache.hc.core5.http.impl.nio.AbstractHttp1StreamDuplexer.onInput(AbstractHttp1StreamDuplexer.java:299)
at org.apache.hc.core5.http.impl.nio.AbstractHttp1IOEventHandler.inputReady(AbstractHttp1IOEventHandler.java:64)
at org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler.inputReady(ClientHttp1IOEventHandler.java:41)
at org.apache.hc.client5.http.impl.async.LoggingIOSession$1.inputReady(LoggingIOSession.java:238)
at org.apache.hc.core5.reactor.ssl.SSLIOSession.decryptData(SSLIOSession.java:617)
at org.apache.hc.core5.reactor.ssl.SSLIOSession.access$200(SSLIOSession.java:74)
at org.apache.hc.core5.reactor.ssl.SSLIOSession$1.inputReady(SSLIOSession.java:202)
at org.apache.hc.core5.reactor.InternalDataChannel.onIOEvent(InternalDataChannel.java:143)
at org.apache.hc.core5.reactor.InternalChannel.handleIOEvent(InternalChannel.java:51)
at org.apache.hc.core5.reactor.SingleCoreIOReactor.processEvents(SingleCoreIOReactor.java:176)
at org.apache.hc.core5.reactor.SingleCoreIOReactor.doExecute(SingleCoreIOReactor.java:125)
at org.apache.hc.core5.reactor.AbstractSingleCoreIOReactor.execute(AbstractSingleCoreIOReactor.java:92)
at org.apache.hc.core5.reactor.IOReactorWorker.run(IOReactorWorker.java:44)
at java.base/java.lang.Thread.run(Thread.java:1583)
When cookies are disabled, it seems there is no CookieSpec in the context here: https://github.com/spring-projects/spring-framework/blob/v6.2.1/spring-web/src/main/java/org/springframework/http/client/reactive/HttpComponentsClientHttpResponse.java#L72
so the exception happens here: https://github.com/spring-projects/spring-framework/blob/v6.2.1/spring-web/src/main/java/org/springframework/http/client/reactive/HttpComponentsClientHttpResponse.java#L79
I assume this is a legitimate use case? In the case of a null CookieSpec, an empty map could be returned.
Comment From: pmv
Thank you!