Release Notes (2.0.x)

Apache Pekko 2.0.x releases support Java 17 and above.

2.0.0

Warning

Apache Pekko 2.0.0 is a new major release. Do not assume binary compatibility with Pekko 1.x: libraries built against Pekko 1.x need to be rebuilt against Pekko 2.0.0, and some code will need source changes. Please read the Migration Guide before upgrading.

Users who built and tested with the 2.0.0 milestone releases may find that the 2.0.0 release has further changes, so you should rebuild and retest against 2.0.0.

It could take months for the other Pekko modules, such as Pekko HTTP, Pekko Connectors, Pekko gRPC, Pekko Management and the persistence plugins, to have 2.0.0 releases. Until then, users might be able to use the 2.0.0 milestone releases of those modules with Pekko 2.0.0, but you should test very carefully before relying on this in production.

Many of the changes in this release were previewed in a series of milestone releases. See the GitHub milestones for 2.0.0-M1, 2.0.0-M2, 2.0.0-M3 and 2.0.0-M4 for a fuller list of changes. There was no 2.0.0-M5 release: the changes made after 2.0.0-M4 are listed in the 2.0.0-M5 GitHub milestone.

Some of the bug fixes listed below have also been backported to Pekko 1.x releases.

Main changes

  • Java 17 is the new minimum version (Java 8 and 11 are no longer supported) (#1730, PR1967)
  • Scala 2.12 support has been dropped. Pekko 2.0.0 is published for Scala 2.13 and Scala 3 (#39, PR1986)
  • A lot of code that was deprecated in Pekko 1.x (and in Akka before that) has been removed - see the Removed section below
  • Big change for Java DSL users due to the removal of pekko.japi.Function (and related classes, such as pekko.japi.function.FI and JAPI) in favour of pekko.japi.function.Function and the other pekko.japi.function types. Lambdas should recompile ok but if you declared variables or functions explicitly, then you may need to change your imports (PR2001, PR2064, PR2078, PR2079, PR2143, PR2198)
  • Java APIs no longer leak Scala types: Scala Future, Option, Tuple2 and Scala collections have been replaced with CompletionStage, Optional, pekko.japi.Pair and Java collections in a number of Java DSL methods, including the pekko-persistence Java APIs (PR1419, PR2007, PR2009, PR2092, #2086, PR3378, PR3388, PR3677)
  • Added many Akka changes that have recently become Apache Licensed (up to and including Akka 2.9.0) - see the Ported from Akka section below
  • sun.misc.Unsafe is no longer used. The code has been migrated to use VarHandles (PR1892, PR1894, PR1990, PR1995, PR3007, PR3008)
  • Reflection usage in core modules has been replaced with MethodHandles/VarHandles where possible (PR3300, PR3312)
  • New pekko-serialization-jackson3 module. Users who are happy with pekko-serialization-jackson, which uses Jackson 2, can stick with that (PR2348)
  • Switch to PEKK as the default magic header in pekko-remote Artery comms. See Changing TCP magic header for what this means for rolling updates (PR3425)
  • Java 21 and 25 support improvements, including virtual thread support for more dispatcher types and JDK-aware ForkJoinPool tuning (#2232, PR2169, PR2242, PR2871, PR2890)
  • Java DSL methods across streams, stream-typed, actor-typed, cluster-sharding-typed, distributed-data, persistence-typed and the testkits now use wildcard bounds (? super / ? extends) on their function, graph and collection parameters, so Java code can pass functions, sources, sinks and collections typed over a supertype or subtype without casts or upcast. Collections of graphs (for example in Source.combine, zipN and mergeAll) and the events passed to Effect.persist now accept any java.lang.Iterable instead of only java.util.List (PR3713, PR3714, PR3717, PR3718, PR3719, PR3720)
  • Added JSpecify nullness annotations to the Java DSL APIs of streams, persistence, actor-typed, cluster-sharding-typed and testkit (#2563, PR2617, PR2850, PR3380)
  • Serialization improvements: predefined JsonSerializable and CborSerializable marker traits, zstd compression for the Jackson serializers and automatic binding of ScalaPB messages to the protobuf serializer - see the Additions and Ported from Akka sections below
  • A number of security hardening changes - see the Security Hardening section below
  • A number of configuration defaults have changed. See the Configuration Changes section of the Migration Guide

Upgrade notes

Please read the Migration Guide before upgrading. It covers the breaking API changes, dependency changes (such as the Agrona 2.x --add-opens requirement) and the configuration defaults that have changed in Pekko 2.0.0.

Unless already waiting for the peer’s close_notify, cancelling a TLS operator’s transport output now reports SessionTruncated on its plaintext output if a session was established and the peer’s close_notify has not been processed, including when no inbound data is buffered or a renegotiation is in progress (PR3740). Previously this path could complete silently after discarding received records. Consumers using the TLS BidiFlow directly must handle SessionTruncated as well as SessionBytes. The Scala and Java Tcp.bindWithTls and Tcp.outgoingConnectionWithTls APIs filter out this signal and continue to expose ByteString streams. The final signal obeys backpressure; cancel the plaintext output too if it will no longer be consumed. See Stream IO for details.

Security Hardening

  • Pekko Remote TLS: optional hostname verification for classic remoting, warnings when hostname verification is not enabled or when TLS is not used, a new keystore-password config, eager SSLContext initialization in Artery so that misconfiguration fails fast and support for multiple certificates in the rotating keys engine ca-cert-file (PR3164, PR3200, PR3397, PR3398, PR3400, PR3479, PR3528)
  • Jackson JsonTypeInfo.Id.MINIMAL_CLASS is now treated as dangerous, like Id.CLASS (PR3304)
  • Resolve, check and parse manifests more carefully in the Jackson serializers (PR3503)
  • New max-decompressed-size limit for Jackson payload decompression and for other compressed payloads (defaults to unlimited for Jackson) (PR3491, PR3502, #3504, PR3515, PR3597)
  • Support unlimited for the Jackson stream-read constraints (PR3522)
  • Bound inbound Artery TCP frame length at framing (PR3492, PR3524)
  • Bound nesting depth when deserializing enclosed payloads (PR3500)
  • Bound the number of entries in an Artery compression table advertisement (PR3510)
  • Bound compression-pointer hops in DNS name parsing (PR3490)
  • Don’t resolve HOCON includes in config that arrived in a message (PR3505)
  • Match actor selection wildcards without backtracking (PR3506)
  • Reject messages whose parallel repeated protobuf fields disagree in length (PR3507)
  • Bounds check the lookup table indexes in cluster gossip (PR3508)
  • Don’t dereference a null superclass in the protobuf allow list check (PR3509)
  • Bound persistence event replay batches (PR3325)
  • Add maxTotalBufferSize to MergeHub for an aggregate queue bound (PR3392)
  • Check the remote deployment allow list before deserializing the constructor arguments of a remotely deployed actor (PR3493)
  • Stop resolving a wire-supplied manifest class for serializers that declare includeManifest = false, so a peer can no longer use them to drive class loading (PR3495)

Bug Fixes

Actors, dispatchers and logging

  • High concurrency issues introduced when switching from sun.misc.Unsafe to VarHandles (PR3007, PR3008)
  • Stop handing a reused Mailbox object to the fork-join dispatcher, which could permanently damage a ForkJoinPool work queue or stop a mailbox from running again. Mailbox no longer extends ForkJoinTask (#3613, #3620, PR3621, PR3628)
  • Stop dispatcher failure reporting from recursing into a StackOverflowError (#3613, PR3622)
  • Keep colliding virtual nodes in ConsistentHash, so the ring no longer depends on the order in which nodes were added or removed. Routing only changes for keys that land on a colliding ring position, but during a rolling update nodes on 1.x and 2.x could route those few keys differently (PR3611)
  • Fix reentrant BatchingExecutor execution (PR3331)
  • Deliver stashed timer messages for UnboundedStash and UnrestrictedStash (PR3264, #3265)
  • Clean up stopped FSM transition listeners (PR3096)
  • Discard stale ReceiveTimeout after cancelReceiveTimeout to avoid NPE in actor-typed (PR3086)
  • Suppress dead-letter logging during a terminating shutdown when disabled (PR3262)
  • Expand Array arguments in MarkerLoggingAdapter log templates (PR3263)
  • Resolve a LogSource for getClass results on Scala 3, so Logging(system, getClass) compiles (#1538, PR3609)
  • Keep the StashBufferImpl instrumentation hooks from being inlined by the Scala 2.13 optimizer (PR3616)
  • Enforce resizer bounds and minimum pool size for AdjustPoolSize, including in ClusterRouterPool (#3253, PR3364, PR3393)
  • Handle post-Java 8 constant pool entries in LineNumbers (PR3465)
  • Make AbstractPersistentActorWithTimers and AbstractFSMWithStash subclassable from Java when using Scala 3 (PR3475)
  • Use Locale.ROOT for toLowerCase/toUpperCase calls (PR3159)
  • Fix ByteString1C serialization to use a SerializationProxy (PR2929)
  • Fix ProducerController crash on restart with an empty unconfirmed buffer (durable queue) (#2760, PR2762)

Streams

  • Fix close being called in cancel for statefulMap (PR2365, PR2385)
  • Fix recoverWith on a failed stage (PR2631, PR2674, PR2712)
  • Fix Source.combine with a single source and type-transforming fan-in strategies (PR2726)
  • Fix close handling in unfoldResource and unfoldResourceAsync (avoid double close and delay close until a pending read completes) (PR3157, PR3172)
  • MapAsyncPartitioned fixes: ordered stage completion after trailing resumed failures, parallel processing preserving order within a partition and a demand-resume deadlock (PR3009, #2886, PR3365)
  • Await in-flight completion on partner termination in SinkRef (PR3016)
  • Prevent double materialization of SourceRef and SinkRef (PR3114)
  • Release references to completed stage logics and to the initial interpreter shell in GraphInterpreter to avoid memory retention (PR3030, PR3031, #3243)
  • Fix the current message reported to supervision in timer stages (PR3294)
  • Initialize timer stage deadlines in preStart instead of at construction (PR3111)
  • Preserve throttler tokens on failed writes (PR3097)
  • Notify BroadcastHub and PartitionHub consumers on materializer shutdown (#3345, PR3346, PR3347)
  • Preserve StageActor demand across fused streams (#3459, PR3461)
  • Handle unexpected stop of the TLS actor gracefully (PR2801)
  • Wait for transport demand instead of failing with Stuck in unwrap loop when TLS unwrap needs a wrap, in both TLS engines (#442, #3732, PR3734)
  • Fix deferred TLS output handling on inbound close and abort the TLS transport on session verification failure (PR3323, PR3324)

IO, TCP and DNS

  • Harden async DNS request id handling (PR2960)
  • Avoid NPE in the outbound TCP stage when upstream finishes before connect (PR3259)
  • Close unregistered TCP channels on setup failure (PR3273)
  • Close IO resources left open on abrupt or failing paths: the resolv.conf file parser, the InputStream of StreamConverters.fromInputStream on abrupt termination and the Artery Aeron UDP port auto-selection channel (PR3532)

Remoting

  • Classic remoting robustness fixes: ignore stale ACKs, harden EndpointReader against dispatch errors, resume the reader after a failed handoff and buffer messages during passive handoff (PR3158, PR3166, PR3173, PR3205, PR3361)
  • Validate the full UniqueAddress in Artery system message ACK/NACK handling (PR3175)
  • Bound Artery stream shutdown (PR3317)
  • Distribute ActorSelection messages across the Artery outbound lanes by target path, instead of sending them all to the same lane when outbound-lanes is greater than 1 (PR3092)
  • Use a Seq rather than a Set to hold TCP magic ByteStrings (PR3484)

Cluster and Cluster Sharding

  • Release lease on shard stop, and log an error when the release fails (PR2738, #3705, PR3733)
  • Stop cluster sharding entities stuck in passivation after a timeout (PR3573)
  • Filter messages from the remember-entities store (PR3411)
  • Recreate a sharding replicator that has stopped (for example because its durable store failed to load) when another entity type is started, instead of reusing the stopped replicator (PR3700)
  • Support java.math.BigInteger/BigDecimal in cluster-metrics (#3385, PR3382)

Persistence

  • Replaying a replicated event sourced actor from a snapshot caused a bug (PR2372)
  • Emit DeletedDurableState for deleted durable state objects (PR2397)
  • Invoke lifecycle signal handlers during snapshot recovery (PR3358)
  • Stop PersistentActor by default when the RecoveryCompleted handler fails (PR3359)

Testkit

  • Return a proper non-cancelled Cancellable from StubbedActorContext.scheduleOnce (PR3268)
  • The multi-node test conductor answers address queries asynchronously, so a bind failure fails the caller’s Future instead of escaping the message handler (#3693, PR3707)
  • Allow overriding testKit with a val in ScalaTestWithActorTestKit (#1140, PR3610)

Ported from Akka

These changes were copied from Akka releases (up to and including Akka 2.9.0) that are now available under the Apache License, version 2.0.

Actors and Actor Typed

  • Optimize PropsAdapter, typed actor context and system adapter (PR2743, PR2750)
  • Improve error message for actorOf on a typed ActorSystem (PR2798)
  • Include sourceThread in the typed actor MDC (PR3357)
  • Include the exception type in StatusReply toString when not text (PR3271)
  • Support ActorSystem/ClassicActorSystemProvider serializer constructors and improve the error message (PR2948)

Streams

  • Fine-grained stream error logging control (PR2805)
  • Support default attributes on materializers (PR3647)

Remoting and DNS

  • Handle Artery uid collisions gracefully: the colliding peer is quarantined and told that it is quarantined, and the handshake fails instead of leaving the association in a broken state. Artery system uids are also generated in a way that makes collisions much less likely (PR3652, PR3676)
  • Include roundtrip latency and sequence number in the heartbeat debug log (PR2736)
  • Auto-select SRV lookup for the name lookup if the entry looks like an SRV name (PR2745)
  • DnsResolutionActor and in-flight request deduplication (PR2919)

Cluster, Cluster Sharding and Distributed Data

  • ShardedDaemonProcess: throttle keep-alive messages and limit them to a subset of nodes (PR2734)
  • Improve the cluster sharding StopShards coordinator command and fix the coordinator role (PR2783, PR2918)
  • Disable ClusterShardingHealthCheck after a configured duration post member-up (PR2785)
  • Remember entities throttling per region instead of per shard and improved DData remember entities logging and consistency (PR2786, PR2799)
  • Add ScheduledClock to reduce nanoTime overhead in recency-based passivation (PR2766)
  • Consistent-hashing shard allocation strategy (PR3270)
  • Initialize the DistributedData extension from ExternalShardAllocationStrategy (PR2923)
  • Make it possible to define the cluster appVersion later (PR2947)
  • Define a custom lease name for Cluster Sharding and Cluster Singleton (PR3648)
  • Distributed Data: wildcard prefix subscriptions in the Replicator (PR2735)
  • Use ClusterShuttingDown in the Distributed Data Replicator (PR2765)
  • Report the effective timeout in the shard hand off stop warnings (PR3644)

Persistence

  • Custom stash support in persistence-typed (PR2433)
  • Run the DurableStateBehavior delete effect asynchronously like persist (PR2752)
  • Snapshot retention: only-one-snapshot optimization and only one retention cycle in progress at a time (PR2767, PR2797)
  • Add filtered, source and tags fields to typed EventEnvelope, EventsByPersistenceIdTyped queries and withTaggerForState (PR2807, PR2920)
  • Add with methods to the typed query EventEnvelope (PR3646)
  • Support for external transport of replicated events in Replicated Event Sourcing (PR2808)
  • Runtime plugin configuration for DurableState (PR3058)
  • FilteredPayload placeholder for filtered journal events (PR3275)
  • Scalable fan-out persistence query abstraction (EventsBySliceFirehoseQuery) and EventsBySliceStartingFromSnapshotsQuery (PR3277)
  • Add SerializedEvent for writing events that are already serialized (PR3650)
  • EventWriter improvements: optionally fill sequence number gaps with FilteredPayload, fail waiting writes instead of restarting when the sequence number lookup fails, handle snapshot events and bypass the journal circuit breaker for the duplicate writes it relies on (PR3653)

Serialization

  • Predefined JsonSerializable and CborSerializable marker traits in pekko-serialization-jackson and pekko-serialization-jackson3, bound to jackson-json and jackson-cbor (PR3649, PR3666)
  • Bind ScalaPB messages to the protobuf serializer when ScalaPB is on the classpath (PR3651, PR3665)

Testkit

  • Unpersistent versions of persistent behaviors for testing, renamed to PersistenceProbeBehavior (PR2456, PR2494)
  • Asking support in the typed BehaviorTestKit (PR2450, PR2453)

Other

  • Other Akka 2.9.0 changes (PR3432)

Additions

Actors

  • Add ActorSystem.terminateAndAwait and ActorSystem.close (PR2096, PR2486)
  • Add UntypedAbstractActorWithStash, UntypedAbstractActorWithUnboundedStash and UntypedAbstractActorWithUnrestrictedStash (PR2097)
  • Add actor-typed Java DSL AbstractMatchingBehavior (#2108, PR2379)
  • Add logging variants for the Java DSL stash and timer actor base classes (#2520, PR3387)
  • Add the timeout duration to the ReceiveTimeout message (PR3399)
  • Add StatusReply.fromTry and StatusReply.fromCallable (PR2810, PR2812)

Streams

  • Add Sink.source and materializeIntoSource operators (#2222, PR2250, PR1831)
  • Add Sink#count operator (#2182, PR2244)
  • Add onErrorResume (including Java DSL, SubFlow and SubSource variants) and more recover operators for the Java DSL (#2116, PR2120, PR2336, PR2337)
  • Add onErrorContinue operator (#2159, PR2322)
  • Add doOnFirst operator (#2183, PR2363)
  • Add doOnCancel operator (#2374, PR2375)
  • Add gzipDecompress operator, replacing the deprecated gunzip (which has been removed) (PR2406)
  • Add Compression.zstd and Compression.zstdDecompress operators, with optional compression dictionaries and a configurable decompression window limit (ZstdDecompressionSettings.withWindowLogMax). zstd-jni is an optional dependency that you need to add yourself, and the window limit needs zstd-jni 1.5.7-25 or later (#2404, PR3639, PR3710, PR3721)
  • Add Source.fromOption and mapOption operators (#2408, #2403, PR2413, PR2414)
  • Add Source.items and an array based Source.apply (#2416, PR2424, PR2428, PR2429)
  • Add withContext operators (PR3199)
  • Add an alsoTo overload with configurable cancellation propagation (PR3127)
  • Add supervision strategy support to more operators that accept user functions (groupedWeightedWithin, batch, expand and extrapolate) and log supervision Resume/Restart in mapAsync operators (#3110, PR3124, PR3180, PR3184, PR3185)
  • Add an opt-in GraphStage based TLS engine (the actor based implementation remains the default). Later fixes drain plaintext already accepted when the plaintext output is cancelled (including after a TLS 1.3 close_notify or KeyUpdate) and fall back to heap buffers when the TCP buffer pool is too small for the SSLEngine (PR2878, PR3727, PR3728, PR3731, PR3738)

Dispatchers and IO

  • Add virtualize support for thread-pool-executor (including the blocking IO dispatcher) and support setting the starting number of virtual threads (#2163, PR2169, PR2242)
  • Make ForkJoinPool minimum-runnable configurable and auto-tune it on JDK 25+ (PR2871, PR2890)
  • Support the SO_REUSEPORT socket option (PR2915)

Java API utilities

  • Add andThen and compose to pekko.japi.function.Function (#2144, PR2147)
  • Add a throwing boolean supplier, sneakyThrow and OptionalUtil Java utilities (PR2199, PR2218, PR2464)
  • Add CompletionStages utility and make timeoutCompletionStage/afterCompletionStage accept Java Duration (PR2060, PR2063, PR2067)

Persistence

  • Add JournalPersistFailed and JournalPersistRejected signals (PR1961)
  • Add an AsyncWriteJournal option for disabling the Resequencer (PR2027)

Testkit

  • PersistenceTestKitReadJournal tag and slice queries support resuming from a TimestampOffset (#1765, PR3615)
  • Add DurableStateBehaviorTestKit (PR3360)
  • The Java test kits now support JUnit Jupiter (JUnit 5 and 6). Pekko’s own Java tests have been migrated from JUnit 4 (#967, PR2289, PR2724, PR2865)
  • Java DSL TestKit shutdownActorSystem that takes Java Duration params (#2226, PR2277)

Serialization

  • Add zstd compression to the Jackson serializers (compression.algorithm = zstd). zstd-jni is an optional dependency that you need to add yourself (PR3641)

Other

  • Add ByteString.endsWith, indexOf with from and to, lastIndexOfSlice, copyToArray and decodeString overloads that read a sub-range without slicing, and make ByteString.copyToBuffer(buffer, offset) public (PR2271, PR2855, PR2862, PR2946, PR3464)
  • Add OSGi headers to pekko-pki and pekko-cluster-typed and compute OSGi imports for Pekko packages dynamically (PR2107, PR2112, PR2313)
  • Add LeaseHealthCheck, which checks that a lease implementation’s API is reachable by trying to acquire and release a test lease (PR3423)
  • Add Scala 3.8 and 3.9 compatibility (Pekko is still published using Scala 3.3 LTS) (PR3072, PR3073, PR3074, PR3295, PR3303)

Changes

API changes

  • Make SubFlow and SubSource final classes and switch the type parameter order of UnfoldResourceSource and UnfoldResourceSourceAsync (PR615, PR616, PR619)
  • Remove the unnecessary empty parameter list from watchTermination (#2376, PR2378)
  • Change Futures#find and other Futures methods to return Java CompletionStage (#2008, PR2009)
  • Stream Java DSL now uses pekko.japi.function types throughout (#2118, PR2143)
  • Fix the Java DSL SourceWithContext/FlowWithContext shape to use pekko.japi.Pair (#2510, PR3388)
  • Replace scala.Tuple2 with pekko.japi.Pair in FSMTransitionHandlerBuilder (PR3378)
  • Use CompletionStage and Java collections in the Java shard allocation strategy API (ShardCoordinator.AbstractShardAllocationStrategy) (PR3677)
  • Widen Java DSL function, graph and collection parameters with wildcard bounds, and accept java.lang.Iterable for collections of graphs and in Effect.persist (PR3713, PR3714, PR3717, PR3718, PR3719, PR3720)
  • In typed persistence (event sourcing and durable state, Scala and Java DSLs), thenStop is only available on the new ReplyEffectWithStop returned by reply, noReply, thenReply and thenNoReply, so stash().thenStop(), which discarded the stashed command without a reply, no longer compiles (PR3682)
  • Replace immutable.Traversable in the public io and stream APIs (PR3467, PR3468)
  • Remove ExecutorServiceFactoryProvider from ThreadPoolConfig (#2171, PR2175)
  • Replace the actor based fanout publisher runtime (Sink.asPublisher(fanout = true)) with a GraphStage bridge (PR2874)
  • Remove the deprecated annotation from recoverWith and undeprecate the getFirst/getFirstAttribute methods (PR2119, PR3404)
  • Mark public sealed traits and abstract classes with @DoNotInherit (#1270, PR3386)
  • Remove @ApiMayChange from APIs that have proven stable, including the log markers, RotatingKeysSSLEngineProvider, ExternalShardAllocation, RetryFlow, the MaterializerState API and the typed persistence query APIs (PR3607, PR3636, PR3656)

Removed legacy support

  • Remove the Akka 2.6.4 rolling-migration manifests from ClusterMessageSerializer (PR3516)
  • ClusterShardingSettings: remove backward-compat passivation code (PR3026)
  • Remove the ssl-config dependency (#2125, PR2127, PR2359)
  • Remove usage of SecurityManager (#1970, PR2106)

Remoting and serialization

  • Replace CountMinSketch with FastFrequencySketch in Artery compression (PR3023)
  • Fail ActorSystem startup when both pekko-serialization-jackson and pekko-serialization-jackson3 are on the classpath. They register serializers with the same names and identifiers, so one would silently take over the other’s bindings (#3671, PR3673)

Build and code modernisation

Documentation

  • Many documentation improvements, including a list of configuration changes in the migration guide, docs for the jackson3 module, the JUnit Jupiter test kit, custom Durable State store plugins, migrating off the deprecated Source.queue overloads and the removed PekkoSSLConfig APIs, clearer typed actor and persistence lifecycle guidance, separate build tool (sbt, Maven, Gradle) and language selectors, and stream operator reference pages for previously undocumented operators (PR2391, PR2468, PR3274, PR3513, PR3583, PR3585, #3589, PR3590, PR3605, PR3654, PR3655, PR3658, PR3660, PR3661, PR3663, PR3664)

Performance

  • SIMD within a register (SWAR) and VarHandle based ByteString search (indexOf, lastIndexOf, indexOfSlice, contains) (#1264, #2150, PR2148, PR2306, PR2309, PR2838, PR2839, PR2863)
  • Other ByteString improvements: faster equality, concatenation, slicing, fragment lookup, ByteStringBuilder.result and multi-byte reads (PR2847, PR2924, PR3427, PR3428, PR3463, PR3471, PR3526)
  • Faster UnsynchronizedByteArrayInputStream usage (PR2300, PR3541)
  • Batch elements across internal async stream boundaries (PR3288, PR3296, #3459, PR3461)
  • Optimize Source.from iterable, Source.future, Source.futureSource and Source.apply for Seq (PR2556, PR2560, PR2562)
  • Avoid substream materialization for value-presented sources in FlattenMerge and concat (PR2977, PR2978)
  • GraphInterpreter hot path optimizations (PR2986, PR3119, PR3373)
  • Stream materializer wiring and stage actor optimizations (PR3035, PR3062, PR3063)
  • Optimize Source.actorRef with a direct-push fast path (PR3091)
  • Avoid Holder allocation in ordered mapAsync for already-completed futures (PR3018)
  • Use an ArrayList in BroadcastHub (PR2262)
  • Avoid quadratic cursor scans in fanout publishers (Sink.asPublisher(fanout = true)) with many subscribers (PR3730)
  • Reduce receive-timeout state allocations and avoid type pollution (PR3332, PR3334)
  • Validate actor path elements without String.charAt (PR3542)
  • Avoid redundant bounds checks on ByteString indexed reads in ByteStringParser and the DNS over TCP client (PR3533)
  • Defer log message rendering in typed persistence and the testkit log capturing by using slf4j placeholders (PR3537)

Removed

Much of the code that was deprecated in Pekko 1.x (and in Akka before that) has been removed. At a high level:

  • Typed Actors (the classic TypedActor API, not Pekko Typed) (#571, PR1969)
  • ActorMaterializer class and deprecated materializer, ActorMaterializerSettings, IOSettings and StreamRefSettings factory methods (PR2011, PR2137, PR3293)
  • Deprecated stream operators and methods, including the Future based operators, stream converters, OverflowStrategy.dropNew, SubstreamCancelStrategy, the old splitWhen/splitAfter overloads, GraphStage.onDownstreamFinish() and the stream testkit probe methods (PR1958, PR1996, PR2006, PR2012, PR2017, PR2073, PR2129, PR2146, PR2440, PR3292)
  • Deprecated actor, scheduler, testkit, remote, cluster, cluster-sharding (including old backoff classes and settings), distributed-data, persistence and DNS code (PR1945, PR1959, PR1965, PR1966, PR1969, PR1981, PR1983, PR2018, PR2023, PR2037, PR3289)
  • pekko.japi.Function and related classes, FI, JAPI and pekko.japi.Option (PR2007, PR2078, PR2079, PR2193)
  • Scala version compatibility classes in pekko.util (such as ccompat, FutureConverters, OptionConverters, ExecutionContexts.parasitic) as Pekko now uses the Scala 2.13 standard library equivalents (PR2207, PR2208, PR2212, PR2234, PR2582)
  • Internal and unused code such as ReentrantGuard, AbruptIOTerminationException, ActorProcessor and the classic remoting disassociate methods (#2160, PR2065, PR2072, PR2074, PR2161, PR3027)
  • The ssl-config configuration sections (PR2359)
  • Support for removing Cluster Sharding coordinator data stored by Akka 2.3.x from RemoveInternalClusterShardingData (PR3608)

Deprecations

Some additional APIs have been deprecated and will be removed in a future release.

  • org.apache.pekko.dispatch.Futures (#1417, PR3377)
  • Patterns.timeout (PR2050)
  • Source.future in the Java DSL (PR2593)
  • BalancingDispatcherConfigurator, which is now also marked as internal API (#3384, PR3391)
  • The pekko.persistence.dispatchers configuration (PR2482)

Dependency Changes

  • Java 17 is the minimum supported version
  • Scala 2.13.18 and 3.3.9
  • netty 4.2.19.Final
  • jackson 2.22.4 (pekko-serialization-jackson) and jackson 3.2.4 (pekko-serialization-jackson3)
  • aeron 1.54.0 and agrona 2.7.0
  • protobuf-java 4.36.2
  • lightbend/config 1.4.9
  • slf4j 2.0.20
  • lz4-java 1.12.1 (at.yawk.lz4:lz4-java)
  • zstd-jni 1.5.7-25 (optional, only needed for the zstd stream operators and zstd compression in the Jackson serializers)
  • junit-jupiter 6.1.3
  • The ssl-config dependency has been removed

Known Issues

  • MergeLatest does not backpressure upstreams and buffers without bound (#3592).
  • Serialization.deserialize with serializer id 0 (NullSerializer) and a non-empty manifest returns Success(null), whatever the bytes contain (#3749). Previously this failed with NotSerializableException unless the manifest named a loadable class. Id 0 is a common default for a missing int value, so a corrupt stored record can load as a null payload instead of failing. As a workaround, code that reads serializer ids from storage should treat a record with id 0 and non-empty bytes as a failure before calling deserialize. NullSerializer only ever writes an empty array, so such a record cannot be valid.