Repository navigation
accept Iterable<? extends HttpHeader> in Java API header parameters - #1379
Merged
Merged
Conversation
Motivation: Java generics are invariant, so a caller holding a List<RawHeader> could not pass it to Java API methods that take Iterable<HttpHeader>. Modification: Widen the headers parameter to Iterable<? extends HttpHeader> in HttpMessage.MessageTransformations.addHeaders/withHeaders (and the scaladsl HttpMessage implementations), the RouteDirectives.complete overloads, and Marshaller.entityToResponse/entityToOKResponse. Add MiMa excludes for the generic-signature-only changes. Result: Java callers can pass collections of any HttpHeader subtype. The erased signatures are unchanged. Tests: - sbt "http-core/Test/testOnly ...HttpMessageTest" "http-tests/Test/testOnly ...RouteDirectivesTest" - passed on Scala 2.13 and 3.3.8 - sbt http-core/mimaReportBinaryIssues http/mimaReportBinaryIssues - passed References: Refs apache#1378
16 tasks
Motivation: The new Iterable<? extends HttpHeader> parameters should accept any java.lang.Iterable, not just Lists. Modification: Run addHeaders/withHeaders and every complete/entityToResponse overload with the same headers as an ArrayList, LinkedHashSet, ArrayDeque, unmodifiable Collection and a non-Collection Iterable. Add tests that the Iterable is traversed once, that withHeaders of an empty Iterable clears the headers, and that different header types keep their order. Result: The Java API header parameters are tested with several Iterable shapes. Tests: - sbt "http-core/Test/testOnly ...HttpMessageTest" "http-tests/Test/testOnly ...RouteDirectivesTest" - passed References: Refs apache#1378
He-Pin
approved these changes
Oct 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Java generics are invariant, so a Java caller holding a
List<RawHeader>(or any other collection of anHttpHeadersubtype) cannot pass it to Java API methods that takeIterable<HttpHeader>. They have to copy or cast it first. This is suggested PR 1 of #1378.Modification
Widen the headers parameter to
Iterable<? extends HttpHeader>(java.lang.Iterable[? <: HttpHeader]in Scala) in:HttpMessage.MessageTransformations.addHeaders/withHeaders(soHttpRequest/HttpResponse), plus the matching scaladslHttpMessageimplementationsRouteDirectives.complete(..., headers, ...)overloadsMarshaller.entityToResponseandMarshaller.entityToOKResponseThe Scala code that converts the headers upcasts the wildcard
Iterablebefore the existingasScalaconversion.java.lang.Iterableis read-only, so the upcast is safe.MiMa reports
IncompatibleSignatureProblemfor these methods because the generic signature changed. The erased JVM signatures are unchanged, so existing compiled callers still link and existing Java sources still compile. The excludes are in newjava-iterable-http-header-wildcard.excludesfiles inhttp-coreandhttp.One edge case is a third-party Scala class implementing
HttpMessage.MessageTransformationsdirectly. Such a class would need to update its override signature. This should be rare, since the interface exists forHttpRequest/HttpResponse.No docs change: the methods behave the same, they just accept more argument types.
Result
Java callers can pass collections of any
HttpHeadersubtype to these methods.Tests
sbt "http-core/Test/testOnly org.apache.pekko.http.javadsl.model.HttpMessageTest" "http-tests/Test/testOnly org.apache.pekko.http.javadsl.server.directives.RouteDirectivesTest": passed on Scala 2.13 and 3.3.8HttpMessageTestcase:addHeaders/withHeaderswith aList<RawHeader>RouteDirectivesTestcase: every changedcompleteoverload, plusMarshaller.entityToResponse/entityToOKResponse, with aList<RawHeader>, checking status, header and entityHttpMessageTest:addHeaders/withHeadersonHttpRequestandHttpResponsewith the same headers as anArrayList,LinkedHashSet,ArrayDeque, unmodifiableCollectionand a non-CollectionIterable(items::iterator); a one-shotIterablethat fails on a second traversal;withHeadersof an emptyIterableclears the headers; mixed header types (Location+RawHeader) keep their orderRouteDirectivesTest: every changedcompleteoverload andMarshaller.entityToResponse/entityToOKResponsewith each of thoseIterableshapes;completewith mixed header typessbt http-core/mimaReportBinaryIssues http/mimaReportBinaryIssues: passed with the new excludessbt docs/Test/compile: passedscalafmtCheckAll,javafmtCheck(JDK 17) andheaderCheckAllon the changed modules: passedReferences
Refs #1378