From b3202e0d89bc7b92785554d02af602073eadd28c Mon Sep 17 00:00:00 2001 From: "Joel Sticha (ranma2913)" <4295880+ranma2913@users.noreply.github.com> Date: Mon, 13 Jul 2026 16:48:19 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Refactor=20`toReader`=20method?= =?UTF-8?q?=20in=20`CloudEventHttpUtils`=20to=20provide=20a=20temporary=20?= =?UTF-8?q?workaround=20to=20[#704](https://github.com/cloudevents/sdk-jav?= =?UTF-8?q?a/issues/704)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spring Framework 7 changed org.springframework.http.HttpHeaders so it no longer implements the Map / MultiValueMap contract. Current versions of io.cloudevents:cloudevents-spring pass HttpHeaders directly to: HttpMessageFactory.createReaderFromMultimap(headers, body.get()); The CloudEvents HTTP reader expects a Map>, so applications running Spring Framework 7 fail while deserializing inbound CloudEvents with: java.lang.IncompatibleClassChangeError: Class org.springframework.http.ReadOnlyHttpHeaders does not implement the requested interface java.util.Map In WebFlux, Reactor treats this linkage error as fatal. The HTTP exchange can remain incomplete, causing callers such as WebTestClient to report a timeout instead of the underlying exception. Signed-off-by: Joel Sticha (ranma2913) <4295880+ranma2913@users.noreply.github.com> --- .../spring/http/CloudEventHttpUtils.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/spring/src/main/java/io/cloudevents/spring/http/CloudEventHttpUtils.java b/spring/src/main/java/io/cloudevents/spring/http/CloudEventHttpUtils.java index 6c1e603a2..ed44d2b86 100644 --- a/spring/src/main/java/io/cloudevents/spring/http/CloudEventHttpUtils.java +++ b/spring/src/main/java/io/cloudevents/spring/http/CloudEventHttpUtils.java @@ -27,8 +27,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -55,10 +53,23 @@ private CloudEventHttpUtils() { * @return a {@link MessageReader} representing the {@link CloudEvent} * @throws CloudEventRWException if something goes wrong while resolving the {@link SpecVersion} or if the message has unknown encoding */ + @SuppressWarnings("unchecked") public static MessageReader toReader(HttpHeaders headers, Supplier body) throws CloudEventRWException { - Map> headersMap = new HashMap<>(); - headers.forEach((key, values) -> headersMap.put(key, new ArrayList<>(values))); - return HttpMessageFactory.createReaderFromMultimap(headersMap, body.get()); + MessageReader reader; + + // Temporary compatibility workaround for Spring Framework 7 HttpHeaders changes. + // Remove this branch and use the standard path once native Spring 7 support is released. + if (headers instanceof Map) { + reader = HttpMessageFactory.createReaderFromMultimap((Map>) headers, body.get()); + } else { + // Spring 7+ no longer guarantees HttpHeaders implements Map, so use the header visitor API. + reader = HttpMessageFactory.createReader( + processHeader -> headers.forEach( + (key, values) -> values.forEach(value -> processHeader.accept(key, value))), + body.get()); + } + + return reader; } /**