Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Add wildcard bounds to Java DSL parameters that are needlessly invariant

Open
#3,712 5 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@pjfanning is already working on this.

Since Oct 27, 2026.

  • #3720 by @pjfanning — open

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
52/100
Issue type
Feature
Clarity
Clearly specified
Activity status
Active
Tech stack
java, scala
Domain
api, backend

Research direction

Read the Java DSL signatures for Source, Sink, Flow, SubFlow, SubSource, and FlowWithContext, plus persistence-typed javadsl Effect.persist(events). Start with the Java tests that exercise these parameters and add narrower-typed variables to verify they compile. Done means the listed wildcard bounds are consistent, those tests pass, and mimaReportBinaryIssues stays clean for stream and persistence-typed.

Written by the indexing model from the issue text.

Description

Java generics are invariant, so several Java DSL parameters reject values that a Java user would reasonably expect to pass, typically a variable whose declared type is a narrower generic (e.g. List<Source<T, NotUsed>> or List<ItemAdded>). Lambdas mostly adapt to the target type; pre-typed variables, fields and method references do not.

Adding wildcard bounds only changes the generic signature, not the erased descriptor, so this should be binary compatible (MiMa clean) and source compatible for existing Java and Scala callers.

Parameters that reject ordinary Java variables
Location Today Suggested
javadsl.Source.combine rest java.util.List[Source[T, ? <: Any]] java.util.List[? <: Graph[SourceShape[T], ?]]
javadsl.Source.zipN, zipWithN java.util.List[Source[T, ? <: Any]] java.util.List[? <: Graph[SourceShape[T], ?]]
javadsl.Source.mergePrioritizedN java.util.List[Pair[Source[T, ? <: Any], Integer]] java.util.List[? <: Pair[? <: Graph[SourceShape[T], ?], Integer]]
javadsl.Sink.combine rest java.util.List[Sink[U, ?]] java.util.List[? <: Graph[SinkShape[U], ?]]
persistence-typed javadsl.Effect.persist(events) java.util.List[Event] java.util.List[? <: Event]

For example, List<Source<Integer, NotUsed>> sources = ...; Source.zipN(sources) does not compile today, and neither does passing a List<ItemAdded> to Effect().persist(...) when the behavior's event type is Event. The newer list-based Source.combine / Sink.combine overloads and mergeAll already use java.util.List[? <: Graph[...]], and the scaladsl persist takes a covariant immutable.Seq[Event].

Inconsistencies with sibling operators

The same operator has a bound in one class but not in its siblings:

  • mapConcat: Source, SourceWithContext and FlowWithContext use Function[Out, ? <: java.lang.Iterable[T]]; Flow, SubFlow and SubSource take a plain java.lang.Iterable[T].
  • statefulMapConcat: the inner function returns a plain java.lang.Iterable[T] in Source, Flow, SubFlow and SubSource; should be ? <: java.lang.Iterable[T].
  • recoverWith / recoverWithRetries: Source and Flow recoverWith(pf) use ? <: Graph[SourceShape[Out], NotUsed]; SubFlow, SubSource and Flow.recoverWithRetries do not.
  • fanInStrategy / fanOutStrategy: Source.combine(first, second, rest, ...) uses Function[Integer, ? <: Graph[...]]; the list-based Source.combine overload and Sink.combine / Sink.combineMat do not.
Tests

Java tests should pass a variable of the narrower type (which fails to compile before the change), and mimaReportBinaryIssues for stream and persistence-typed should stay clean.

Dominant language
Scala
Stars
1.7k
Forks
212
Avg merge
20h 44m
Merged PRs (30d)
104

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/pekko

All issues in apache/pekko

Similar issues

More Scala issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.