NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Maven Central, #377 by repository stars
Reactive Extensions for Java
Latest stable
2.2.21
Last release 6 years ago
no release in 18 months
Release timing varies
gaps range from 3 weeks to 7 months
Nearly every release is documented
notes for 50 of 50 stable releases
Nothing withdrawn
no release was ever pulled
10 years old
57 releases · first in 2016
Drag across the ruler to compare, or tap a release to open it.
:warning: This is the last planned update for the 2.x version line. After February 28, 2021, 2.x becomes End-of-Life (EoL); no further patches, bugfix
:warning: This is the last planned update for the 2.x version line. After February 28, 2021, 2.x becomes End-of-Life (EoL); no further patches, bugfixes, enhancements, documentation or support will be provided by the project.
Scheduler. (#7162)Schedulers to use System.nanoTime() for now(). (#7170)This project publishes no release notes. Between v2.2.20 and v2.2.21 there were 3 commits, 3 of them substantive:
:warning: The 2.x version line is now in maintenance mode and will be supported only through bugfixes until February 28, 2021. No new features, behavi
Your coding agent can read these notes before it upgrades. Set up the MCP server →
:warning: The 2.x version line is now in maintenance mode and will be supported only through bugfixes until February 28, 2021. No new features, behavior changes or documentation adjustments will be accepted or applied to 2.x. It is recommended to migrate to 3.x within this time period.
Observable.flatMap with maxConcurrency hangs (#6960)Observable.toFlowable(ERROR) not cancelling upon MissingBackpressureException (#7084)Flowable.concatMap backpressure with scalars. (#7091)This project publishes no release notes. Between v2.2.19 and v2.2.20 there were 4 commits, 3 of them substantive:
:warning: The 2.x version line is now in maintenance mode and will be supported only through bugfixes until February 28, 2021. No new features, behavi
:warning: The 2.x version line is now in maintenance mode and will be supported only through bugfixes until February 28, 2021. No new features, behavior changes or documentation adjustments will be accepted or applied to 2.x. It is recommended to migrate to 3.x within this time period.
switchMap not canceling properly during onNext-cancel races.This project publishes no release notes. Between v2.2.18 and v2.2.19 there were 2 commits, 2 of them substantive:
:warning: The 2.x version line is now in maintenance mode and will be supported only through bugfixes until February 28, 2021. No new features, behavi
:warning: The 2.x version line is now in maintenance mode and will be supported only through bugfixes until February 28, 2021. No new features, behavior changes or documentation adjustments will be accepted or applied to 2.x. It is recommended to migrate to 3.x within this time period.
groupBy not requesting more if a group is cancelled with buffered items.This project publishes no release notes. Between v2.2.17 and v2.2.18 there were 3 commits, 2 of them substantive:
Pull 6827: Fix Flowable.flatMap not canceling the inner sources on outer error.
This project publishes no release notes. Between v2.2.16 and v2.2.17 there were 2 commits, 1 of them substantive:
Pull 6754: Fix amb, combineLatest and zip Iterable overloads throwing ArrayStoreException for ObservableSources.
This project publishes no release notes. Between v2.2.15 and v2.2.16 there were 3 commits, 2 of them substantive:
Pull 6715: Fix MulticastProcessor not requesting more after limit is reached.
MulticastProcessor not requesting more after limit is reached.clear in observeOn while output-fused.parallel() on grouped flowable not replenishing properly.observeOn to mention its eagerness.j.u.c.Flow warnings due to RS 1.0.3.This project publishes no release notes. Between v2.2.14 and v2.2.15 there were 7 commits, 6 of them substantive:
Pull 6677: Fix concurrent clear() calls when fused chains are canceled.
This project publishes no release notes. Between v2.2.13 and v2.2.14 there were 5 commits, 4 of them substantive:
Commit cc690ff2: Upgrade to Reactive Streams 1.0.3.
System.getProperties().takeLast(time) last events time window calculation.window not creating windows properly.This project publishes no release notes. Between v2.2.12 and v2.2.13 there were 4 commits, 3 of them substantive:
Pull 6618: Fix switchMap incorrect sync-fusion & error management.
Pull 6560: Fix NPE when debouncing an empty source.
mergeWith not canceling other when the main fails.ObservableBlockingSubscribe compares with wrong object.replay() and ReplaySubject/Processor.Single.doOnTerminate refer to onComplete notification.Pull 6499: Add missing null check to BufferExactBoundedObserver.
Pull 6488: Fix zip not stopping the subscription upon eager error.
Pull 6442: Add missing undeliverable error handling logic for Completable.fromRunnable & fromAction operators.
Completable.fromRunnable & fromAction operators.CompositeDisposable.Creating-Observables wiki doc.Pull 6386: Add doOnTerminate to Single/Maybe for consistency.
Pull 6370: Add interruptible mode via the new Schedulers.from(Executor, boolean) overload.
Schedulers.from(Executor, boolean) overload.Observable.repeatWhen due to flooding repeat signal.Completable.andThen(Completable) not running on observeOn's Scheduler.Flowable.publish not requesting upon client change.replay() memory leak due to bad node retention.{Single|Maybe|Completable}.amb().CompositeException.getRootCause() detecting loops in the cause graph.timeout(fallback).ignoreElement to convert Single to Completable in the README.md.Pull 6344: Use correct return type in JavaDocs documentation in elementAtOrDefault.
elementAtOrDefault.@code.Pull 6278: Add Maybe/Single/Completable materialize operator,
Maybe/Single/Completable materialize operator,Single.dematerialize(selector) operator.Flowable/Observable dematerialize(selector) operator.doOn{Dispose|Cancel} handler at most once.Observable.flatMap to sustain concurrency level.io.reactivex.schedulers.onSubscribe null-checks to NPE docs on Flowable/Observable subscribe.Flowable.zip docs.Emitter interface methods.Flowable.groupBy.distinctUntilChanged requires non-mutating data to work as expected.generate examples to Creating-Observables.md.Creating-Observables.md docs stlye mistake.How-to-Contribute.md.SubscriptionHelper.isCancelled().Observable/Flowable cache() operators.Scheduler as System property.Flowable.toObservable backpressure annotation.Pull 6242: Add timed Completable.delaySubscription() operator.
Completable.delaySubscription() operator.ConnectableObservable.io.reactivex.functions.Functions nonexistent utility class.Observable.flatMap drain logic.TimeoutException message in the timeout operators.UndeliverableException and OnErrorNotImplementedException message to use the full inner exception.@Nullable annotations for blocking methods in Completable.Pull 6187: Fix refCount termination-reconnect race.
refCount termination-reconnect race.Undeliverable & OnErrorNotImplemented exceptions.null observer/subscriber return errors from RxJavaPlugins in detail.Additional-Reading.md.Flowable.reduce(BiFunction) JavaDoc; the operator does not signal NoSuchElementException.fromCallable & co.toFuture marbles and descriptions.Pull 6143: Add concatArrayEagerDelayError operator (expose feature).
concatArrayEagerDelayError operator (expose feature).concatMap and publish operator.Flowable.fromCallable consistent with the other fromCallables.Completable.fromCallable via RxJavaPlugins.observeOn not let worker.dispose() get called prematurely.Completable.onErrorResumeNext internals.Flowable.onErrorResumeNext improvements.Single.timer, Single.defer and Single.toXXX operators.Single.concat operator.Single operators.TestObserver.assertValueSet in docs and via tests.Maybe.flatMap events to MaybeSource.fromEmitter() in wiki._Sidebar.md with new order of topics.Creating-Observables.md wiki.Version 2.2.0 is the next minor release of the 2.x era and contains the standardization of many experimental API additions from the past year since ve
Version 2.2.0 is the next minor release of the 2.x era and contains the standardization of many experimental API additions from the past year since version 2.1.0. Therefore, the following components are now considered stable and will be supported throughout the rest of the life of RxJava 2.x.
Classes, Enums, Annotations
MulticastProcessorParallelFlowable, UndeliverableException, OnErrorNotImplementedExceptionParallelFailureHandling{Completable|Single|Maybe|Observable|Flowable|Parallel}Emitter, {Completable|Single|Maybe|Observable|Flowable|Parallel}Converter, LambdaConsumerIntrospection, ScheduledRunnableIntrospectionOperators
Flowable: as, concatMap{Single|Maybe|Completable}, limit, parallel, switchMap{Single|Maybe|Completable}, throttleLatestObservable: as, concatMap{Single|Maybe|Completable}, switchMap{Single|Maybe|Completable}, throttleLatestSingle: as, mergeDelayError, onTerminateDetach, unsubscribeOnMaybe: as, mergeDelayError, switchIfEmptyCompletable: as, fromMaybe, onTerminateDetach, takeUntilParallelFlowable: as, map|filter|doOnNext(errorHandling)˙, sequentialDelayErrorConnectable{Flowable, Observable}: refCount(count + timeout)Subject/FlowableProcessor: offer, cleanupBuffer, create(..., delayError)Test{Observer, Subscriber}: assertValueAt, assertValuesOnly, assertValueSetOnly(For the complete list and details on the promotions, see PR 6105.)
Release 2.2.0 is functionally identical to 2.1.17. Also to clarify, just like with previous minor version increments with RxJava, there won't be any further development or updates on the version 2.1.x (patch) level.
All Experimental/Beta APIs introduced up to version 2.1.17 are now standard with 2.2.
The project would like to thank the following contributors for their work on various code and documentation improvements (in the order they appear on the commit page):
@lcybo, @jnlopar, @UMFsimke, @apodkutin, @sircelsius, @romanzes, @Kiskae, @RomanWuattier, @satoshun, @hans123456, @fjoshuajr, @davidmoten, @vanniktech, @antego, @strekha, @artfullyContrived, @VeskoI, @Desislav-Petrov, @Apsaliya, @sidjain270592, @Milack27, @mekarthedev, @kjkrum, @zhyuri, @artem-zinnatullin, @vpriscan, @aaronhe42, @adamsp, @bangarharshit, @zhukic, @afeozzz, @btilbrook-nextfaze, @eventualbuddha, @shaishavgandhi05, @lukaszguz, @runningcode, @kimkevin, @JakeWharton, @hzsweers, @ggikko, @philleonard, @sadegh, @dsrees, @benwicks, @dweebo, @dimsuz, @levaja, @takuaraki, @PhilGlass, @bmaslakov, @tylerbwong, @AllanWang, @NickFirmani, @plackemacher, @matgabriel, @jemaystermind, @ansman, @Ganapathi004, @leonardortlima, @pwittchen, @youngam, @Sroka, @serj-lotutovici, @nathankooij, @mithunsasidharan, @devisnik, @mg6maciej, @Rémon S, @hvesalai, @kojilin, @ragunathjawahar, @brucezz, @paulblessing, @cypressf, @langara
(75 contributors)
The project would also thank its tireless reviewer @vanniktech for all his efforts on verifying and providing feedback on the many PRs from the project lead himself. :+1:
Pull 6079: Add Completable.takeUntil(Completable) operator.
Completable.takeUntil(Completable) operator.Completable.fromMaybe operator.Completable.delay operator internals.Single class.dl/dd entry stylesheet.Single, Maybe and Completable.dt/dd within the method details.Completable mergeX JavaDoc missing dt before dd.Observable#lift.Single.never method.Single.filter method.Maybe.hide marble diagram.Single.delay method.Single.hide operator.Completable marble diagrams (07/17a).Single.repeat operators.Completable marbles.Single.repeatUntil operator.Completable marbles (+17, 07/18a).Single.amb operators.Completable marbles (+19, 07/19a).Completable marbles (7/19b).Completable marbles (+26).This is a hotfix release for a late-identified issue with concatMapMaybe and concatMapSingle.
Pull 6026: Add blockingSubscribe overload with prefetch amount allowing bounded backpressure.
blockingSubscribe overload with prefetch amount allowing bounded backpressure.{PublishSubject|PublishProcessor}.subscribeActual to protected. They were accidentally made public and there is no reason to call them outside of RxJava internals.CompositeDisposable JavaDoc.MulticastProcessor JavaDoc comment.throttleWithTimout is an alias of debounce.Maybe marble diagrams 06/21/ablockingForEach() JavaDocs.{X}Processor JavaDocs by syncing with {X}Subject docs.Single.flatMapPublisher so it doesn't batch requests.{Single|Maybe}.flatMap{Publisher|Observable} & andThen(Observable|Publisher) implementations.Observable.takeUntil.Single.takeUntil, Maybe.takeUntil dispose behavior.groupBy eviction so that source is cancelled and reduce volatile reads.LambdaObserver.onError to route to global error handler.BlockingSubscriber that would always be false due to wrong variable.Pull 5982: Deprecate getValues() in Subjects/FlowableProcessors to be removed in 3.x.
Single.concatEager().ConnectableObservable.refCount() and ConnectableFlowable.refCount() with minimum consumer count & disconnect grace period.Observable.throttleLatest and Flowable.throttleLatest().MulticastProcessor.assertValueSetOnly and assertValueSequenceOnly to TestObserver/TestSubscriber.getValues() in Subjects/FlowableProcessors to be removed in 3.x.Maybe/Single JavaDocs; annotation cleanup.subscribeActual methods.blockingSubscribe JavaDoc clarifications.Single.doOnX methods.Observable javadoc cleanup.refCount() connect/subscribe/cancel deadlock.Flowable.take to route post-cancel errors to plugin error handler.switchMap to indicate boundary fusion.Release candidate for 2.1.14 testing the automatic JavaDoc pushback for release mode.
Release candidate for 2.1.14 testing the automatic JavaDoc pushback for release mode.
Please ignore this release and any subsequent RCx in case the pushback doesn't work properly.
Pull 5957: Add Single.ignoreElement, deprecate Single.toCompletable (will be removed in 3.0).
Single.ignoreElement, deprecate Single.toCompletable (will be removed in 3.0).Completable.toMaybe() @return javadoc.Observable javadoc mentioning doOnCancel instead of doOnDispose.blockingX JavaDoc to mention wrapping of checked Exceptions.AppendOnlyLinkedArrayList.forEachWhile.Observable.concatMapSingle dropping upstream items.Pull 5928: Fix concatMapSingle & concatMapMaybe dispose-cleanup crash.
Pull 5871: Add Flowable.concatMapCompletable{DelayError} operator.
Flowable.concatMapCompletable{DelayError} operator.Flowable.switchMapCompletable{DelayError} operator.Flowable.concatMap{Maybe,Single}{DelayError} operators.Flowable.switchMap{Maybe,Single}{DelayError} operators.Observable switchMapX and concatMapX operators.TestScheduler that takes the initial virtual time.Observable.concatMapCompletable.Observable.(concat|switch)Map{Completable|Single|Maybe}.Observable.switchMap inner source.Flowable.lift() operator.lift() operators.NoSuchElementException to Single.zip().dematerialize() and terminal items/signals.buffer() documentation to correctly describe onError behavior.window(Observable|Callable) upstream handling.Flowable.window(Publisher|Callable) upstream handling.ReplaySubject.Observable.flatMap scalar maxConcurrency overflow.publish(-|Function) subscriber swap possible data loss.replay components.Flowable.singleOrError().toFlowable() not signalling NoSuchElementException.FlowableWindowBoundary not cancelling the upstream on a missing backpressure case, causing NullPointerException.@Nullable annotations to subjects.Pull 5845: Add efficient concatWith(Single|Maybe|Completable) overloads to Flowable and Observable.
concatWith(Single|Maybe|Completable) overloads to Flowable and Observable.mergeWith(Single|Maybe|Completable) overloads to Flowable and Observable.Flowable.groupBy overload with evicting map factory.share() JavaDocs.Observable.blockingIterable(int) and add Observable.blockingLatest marbles.replay emission's item retention property.just() operator and reference other typical alternatives.SingleSubject JavaDoc.distinct() and distinctUntilChanged() in JavaDoc.Observer, SingleObserver, MaybeObserver and CompletableObserver.Scheduler API.{Flowable|Observable|Single|Maybe|Completable}Emitter interfaces in detail.Maybe.fromCallable JavaDoc.Observable.switchMap main onError not disposing the current inner source.Pull 5799: Add missing {Maybe|Single}.mergeDelayError variants.
{Maybe|Single}.mergeDelayError variants.Flowable retry/repeat.onTerminateDetach.BehaviorSubject JavaDoc + related clarifications.merge() error handling.Maybe doOn{Success,Error,Complete} JavaDoc.merge() operator JavaDocs.XSubject JavaDocs.Observable:
Subject and Processor marbles.Warning! Behavior change regarding handling illegal calls with `null` in `Processor`s and `Subject`s.
Warning! Behavior change regarding handling illegal calls with null in Processors and Subjects.
The Reactive Streams specification mandates that calling onNext and onError with null should
result in an immediate NullPointerException thrown from these methods. Unfortunately, this requirement was overlooked (it resulted in calls to onError with NullPointerException which meant the Processor/Subject variants entered their terminal state).
If, for some reason, the original behavior is required, one has to call onError with a NullPointerException explicitly:
PublishSubject<Integer> ps = PublishSubject.create();
TestObserver<Integer> to = ps.test();
// ps.onNext(null); // doesn't work anymore
ps.onError(new NullPointerException());
to.assertFailure(NullPointerException.class);
Workers from some Schedulers.RxJavaPlugins.unwrapRunnable to help with RxJava-internal wrappers in Schedulers.retry(times, predicate) to Single & Completable and verify behavior across them and Maybe.package-infos + remove unused imports.Observable marbles 11/28.Observable (12/06).autoConnect() JavaDoc + add its marble.@see to Completable.retryWhen() operators.BehaviorProcessor JavaDoc.TrampolineScheduler not calling RxJavaPlugins.onSchedule(), add tests for all schedulers.runnable == null in *Scheduler.schedule*().buffer() calling cancel unnecessarily.Subject/FlowableProcessor NPE fixes, add UnicastProcessor TCK.Pull 5729: Implement as() operator on the 6 base classes - similar to to() but dedicated functional interface for each base class instead of just Func
as() operator on the 6 base classes - similar to to() but dedicated functional interface for each base class instead of just Function.Schedulers.single() JavaDoc.flatMapSingle and flatMapMaybe.BaseTestConsumer values() and errors() thread-safety clarifications.Schedulers.take() operator about the thread onComplete may get signaled.ConnectableFlowable, GroupedFlowable, FlowableAutoConnect.Observable all, fromPublisher, zipArray.Completable.concat to use replace (don't dispose old).ScheduledRunnable.isDisposed before emitting in SingleFromCallable.toMap.Pull 5649: Add Observable.concatMapCompletable().
Observable.concatMapCompletable().Flowable.limit() to limit both item count and request amount.io.reactivex and io.reactivex.observers.subscribeWith documentation examples.Observable.just(2..10) and switchOnNextDelayError marbles.Observable.singleElement().Observable marble fixes.PublishProcessor cancel/emission overflow bug.parallel() a fusion-async-boundary.Pull 5616: Add Single.delay overload that delays errors.
Single.delay overload that delays errors.onTerminateDetach to Single and Completable.Observable.delay & Flowable.delay javadoc.fromPublisher().This is a pre-release of 2.1.5 to make sure the new nebula-plugin-free release process works.
This is a pre-release of 2.1.5 to make sure the new nebula-plugin-free release process works.
If the release fails at the bintray upload due to configuration mistakes, we'll adjust it an release RC4 and on. If it succeeds, that's fine as well because the final 2.1.5 will come in a couple of days.
RC1 failed due to wrong config: repo and name were not RxJava/RxJava.
RC2 failed due to wrong POM generated for maven.
RC3 still generated the wrong POM.
Pull 5568: Add BaseTestConsumer.assertValuesOnly.
BaseTestConsumer.assertValuesOnly.Maybe.switchIfEmpty(Single).LambdaConsumerIntrospection for detecting the lack of onError callback in subscribe() calls.NullPointerException comment to some Single operators.Single in some Observable operators.Observable.combineLatestDelayError sync initial error not emitting.BaseTestConsumer.assertValueSequence reversed error message.Observable.concatMapEager queueing of source items.Single.timeout unnecessary dispose calls.The Reactive-Streams dependency has been updated to version 1.0.1. This new version contains documentation changes and TCK (Test Compatibility Kit) fi
The Reactive-Streams dependency has been updated to version 1.0.1. This new version contains documentation changes and TCK (Test Compatibility Kit) fixes that doesn't affect RxJava's frontend. Other libraries that were using version 1.0.0 should have no issue running with 1.0.1.
RxJava 2 from now on is compatible with JDK 9, verified in a separate project whenever a new (non-trivial) update of the JDK or RxJava happens.
Compatibility means the RxJava 2 source code compiles with JDK 9 (targets 6, 8 and 9) and the unit tests pass.
assertValueAt(int, value) to TestObserver/TestConsumer.Observable marbles (07/30) via Issue 5319 comments.Schedulers.null check to fused Observable.fromCallable.Pull 5432: Fix/clarify the Observable class' javadoc.
Observable class' javadoc.Async and Publish processors javadoc.combineLatest operators accepting unspecified number of sources.subscribeOn.Flowable and Observable reduce.F.reduce(seed, reducer), F.reduceWith(seedSupplier, reducer) and O.reduce(seed, reducer).Maybe.defaultIfEmpty regarding toSingle.ReplaySubject.getValue() inconsistency with getValues() on old items.concat to report isDisposed consistently with termination.FlowableWithLatestFrom not requesting more when the other hasn't emitted yet.ReplayProcessor backpressure and NotificationLite emission bug.SpscLinkedArrayQueue.Single.delaySubscription methods.@NonNull annotation in Consumer method parameter.@NonNull annotation from Function.FlowableTimeoutTimed instead of an AtomicReference.Schedulers.io() javadoc {link missing the @ symbol.withLatestFrom conditional subscriber, test cold consumption.The emitter API (such as FlowableEmitter, SingleEmitter, etc.) now features a new method, tryOnError that tries to emit the Throwable if the sequence
The emitter API (such as FlowableEmitter, SingleEmitter, etc.) now features a new method, tryOnError that tries to emit the Throwable if the sequence is not cancelled/disposed. Unlike the regular onError, if the downstream is no longer willing to accept events, the method returns false and doesn't signal an UndeliverableException.
tryOnError to create/XEmitter API.subscribeOn overload to avoid same-pool deadlock with create.Maybe.toSingle.FunctionXObservableAction1 with Consumer in docs.SingleFlatMapIterableObservable.Single.doAfterTeminate mentioning doAfterSuccess.DefaultObserver javadoc fix: use subscribe, remove disposable code.DefaultSubscriber javadoc sample fix.Observable.reduce() and Observable.reduceWith().Single.delay documentation.interval+trampoline can be stopped.SingleMap not allow map function return null.doOnNext failure not triggering doOnError when fused.buffer(time, maxSize) duplicating buffers on time-size race.Version 2.1.0 is the next minor release of the 2.x era and contains the standardization of many experimental API additions from the past half a year s
Version 2.1.0 is the next minor release of the 2.x era and contains the standardization of many experimental API additions from the past half a year since version 2.0.0. Therefore, the following components are now considered stable and will be supported throughout the rest of the life of RxJava 2.x.
Classes, Enums, Annotations
CheckReturnValueCompletableSubject, MaybeSubject, SingleSubjectTestWaitStrategyOperators
Flowable: doAfterNext, doFinally, sample (emitLast)Observable: doAfterNext, doFinally, sample (emitLast)Single: doAfterSuccess, doAfterTerminate, doFinallyMaybe: doAfterSuccess, doFinally, flatMapSingleElementCompletable: cache, doFinally, hideTest{Observer, Subscriber}: assertNever, assertTimeout, assertNoTimeout, awaitCount, clearTimeout, isTimeout, withTagRxJavaPlugins: createComputationScheduler, createIoScheduler, createNewThreadScheduler, createSingleScheduler, getOnBeforeBlocking, setOnBeforeBlocking, isFailOnBlockingScheduler, setFailOnBlockingScheduler.Scheduler.when, TestSubscriber.requestMore(For the complete list and details on the promotions, see issue 5243.)
Release 2.1.0 is functionally identical to 2.0.9 except the removal of now unnecessary Flowable.strict() operator. To clarify, just like with previous minor version increments with RxJava, there won't be any further development or updates on the version 2.0.x (patch) level.
Some of the enhancements of RxJava 2.0.x were added recently which often represent complex additions to RxJava itself (such as the whole ParallelFlowable). We are confident their functionality adds value to the library but not enough time elapsed since their introduction for the community to try it out and provide feedback on them (i.e., naming, encompassed functionality, etc.). To indicate we are willing to support them and eventually standardize them in the next minor release, the following components have been promoted to the status of Beta:
OnErrorNotImplementedException, ProtocolViolationException, UndeliverableException,
ParallelFlowableFlowableSubscriberFlowable: parallel, subscribe(FlowableSubscriber)RxJavaPlugins: getOnParallelAssembly, onAssembly(ParallelFlowable), setOnParallelAssemblyObservableSource.defer to Observable.defer in Observable.scan() documentation.Flowable.toObservable referring to Publisher instead of Observable.The project would like to thank the following contributors for their work on various code and documentation improvements (in the order they appear on the commit page):
@vanniktech, @veyndan, @mauin, @smartbeng, @ImangazalievM, @bloderxd, @mibac138, @ggikko, @mostroverkhov, @sadegh, @nmorioka, @SleimanJneidi, @davidmoten, @hkurokawa, @jbarr21, @alexandre-dubois, @VeskoI, @Stephan202, @PaulWoitaschek, @soulkeykim, @stevepeak, @jschneider, @JakeWharton, @tonycosentini, @hzsweers, @passsy, @sergiomarquesmoura, @ikesyo, @benjchristensen, @zsavely, @DDesideria, @gaemi, @Jawnnypoo, @artem-zinnatullin, @mkobit, @abersnaze, @tbcs, @gengjiawen, @qwert2603, @DmitriyZaitsev
(40 contributors)
The project would also thank its tireless reviewers, @JakeWharton and @vanniktech for all their efforts on verifying and providing feedback on the many PRs from the project lead himself. :+1:
Pull 5302: Add Single.unsubscribeOn().
API enhancements
Single.unsubscribeOn().Bugfixes
Flowable.toList() onNext/cancel race.flatMapIterable appearing to be empty when fused.Single.subscribe(BiConsumer) to be consistent with isDisposed.BehaviorProcessor & BehaviorSubject terminate-subscribe race.Flowable.flatMapMaybe/Flowable.flatMapSingle maxConcurrency not requesting more.Documentation
Schedulers style.DisposableX copy-paste error in Javadoc.doOnDispose JavaDoc.Single.flatMapObservable().Single.flatMapObservable()'s function argument.Other
NullPointerException comments and ObjectHelper test code.@NonNull annotations from BiConsumer.IoScheduler.DisposableObserver).Pull 5161: Add Observable.switchMapSingle()
API enhancements
Observable.switchMapSingle()offer() method to PublishProcessor & BehaviorProcessor.ParallelTransformer interface.UnicastSubject fail-fast support.map(), filter() and doOnNext().UnicastProcessor fail-fast support.Bugfixes
Single.subscribe() to report isDisposed() true on success/error.LambdaObserver not cancelling the upstream.replay().refCount() leaking items between connections.flatMap emitting the terminal exception indicator on cancel.window() with time+size emission problems.CallbackCompletableObserver calling onError.Documentation
concatMapEager requires positive prefetch amount.refCount() return type.firstElement, flattenAsX, flatMapIterable, UnicastSubject and UnicastProcessor.DisposableSubscriber).Schedulers utility class.Functions “Function3” -> “BiFunction, Function3”Other
Pull 5112: Flowable.strict() deprecated and will be removed in 2.1.0 - the default Flowable behavior is now strict.
Reactive-Streams compliance
Related issue 5110, related pull 5112.
RxJava 2's Flowable was designed with Reactive-Streams compliance in mind but didn't follow all rules to the letter. A temporary workaround was the introduction of the strict() operator to enable full compliance. Unfortunately, according to the clarified stance from the specification leads, implementors of Publisher must honor the specification (despite its shortcomings) without excuses or workarounds.
Honoring the specification adds a per-item cost of two atomic increments, manifesting in between the Flowable and an arbitrary Reactive-Streams compliant org.reactivestreams.Subscriber. See Pull 5115 for the benchmark comparison.
Starting from 2.0.7, the Flowable.subscribe(org.reactivestreams.Subscriber) now follows the spec by wrapping via the StrictSubscriber of the strict() operator unless the consuming instance implements a new interface specific to RxJava 2: FlowableSubscriber.
The FlowableSubscriber extends org.reactivestreams.Subscriber but doesn't add any new methods and only overrides four of the textual rules of the specification to enable a relaxed operation within RxJava 2. All internal operators have been converted to use this new interface and thus don't have suffer the per-item overhead required by the specification, including the standard DisposableSubscriber, TestSubscriber and ResourceSubscriber. The lambda-based subscribe() operators were also retrofitted.
If you were implementing a Subscriber (directly or anonymously), you may want to change the interface to FlowableSubscriber. In order to avoid some of the runtime checks when subscribing to Flowable the new subscribe(FlowableSubscriber) has been introduced.
Note that the other reactive base types, Observable, Single, Maybe and Completable are not affected as these were never intended to implement the Reactive-Streams specification (they were only inspired by the spec and are RxJava 2 only to begin with).
API enhancements
ParallelFlowable.sequentialDelayError.TestSubscriber.withTag.TestSubscriber.awaitCount, assertTimeout & assertNoTimeout, improve assertion error messageAPI deprecations
Flowable.strict() deprecated and will be removed in 2.1.0 - the default Flowable behavior is now strict.Bugfixes
Maybe.concat() subscribe-after-cancel, verify others.doOnSubscribe signalling UndeliverableException instead of onError.window(time, size) not completing windows on timeout.Observable.combineLatest to dispose eagerly.Observable.zip to dispose eagerly.flatMap not cancelling the upstream eagerly.repeatWhen and retryWhen signatures.Other
One of the design goals of 2.x was that no errors can be lost. Sometimes, the sequence ends or gets cancelled before the source could emit an onError
Undeliverable exceptions
One of the design goals of 2.x was that no errors can be lost. Sometimes, the sequence ends or gets cancelled before the source could emit an onError which has nowhere to go at that point and gets routed to the RxJavaPlugins.onError.
Unlike 1.x, 2.x by default calls Thread.currentThread().getUncaughtExceptionHandler().uncaughtException() which crashes an Android app. Many developers have noticed the increased number of app crashes when porting to 2.x due to this behavior change. Note that this doesn't mean RxJava 2 is unstable but it means you likely had these exceptions all along but they were silently dropped.
Unfortunately, RxJava can't tell which of these out-of-lifecycle, undeliverable exceptions should or shouldn't crash your app. Identifying the source and reason for these exceptions can be tiresome, especially if they originate from a source and get routed to RxJavaPlugins.onError somewhere lower the chain.
Therefore, 2.0.6 introduces specific exception wrappers to help distinguish and track down what was happening the time of the error:
OnErrorNotImplementedException: reintroduced to detect when the user forgot to add error handling to subscribe().ProtocolViolationException: indicates a bug in an operatorUndeliverableException: wraps the original exception that can't be delivered due to lifecycle restrictions on a Subscriber/Observer. It is automatically applied by RxJavaPlugins.onError with intact stacktrace that may help find which exact operator rerouted the original error.If an undeliverable exception is an instance/descendant of NullPointerException, IllegalStateException (UndeliverableException and ProtocolViolationException extend this), IllegalArgumentException, CompositeException, MissingBackpressureException or OnErrorNotImplementedException, the UndeliverableException wrapping doesn't happen.
In addition, some 3rd party libraries/code throw when they get interrupted by a cancel/dispose call which leads to an undeliverable exception most of the time. Internal changes in 2.0.6 now consistently cancel or dispose a Subscription/Disposable before cancelling/disposing a task or worker (which causes the interrupt on the target thread).
// in some library
try {
doSomethingBlockingly()
} catch (InterruptedException ex) {
// check if the interrupt is due to cancellation
// if so, no need to signal the InterruptedException
if (!disposable.isDisposed()) {
observer.onError(ex);
}
}
If the library/code already did this, the undeliverable InterruptedExceptions should stop now. If this pattern was not employed before, we encourage updating the code/library in question.
API enhancements
OnErrorNotImplementedException for 0-1 arg subscribe.RxJavaPlugins, add missing params validationSingle.doAfterTerminateBugfixes
replay() cancel/dispose NullPointerException.scan(seed, f) to emit accumulated values without delay.Other
Single.zip implementation, no dispose on all-success.amb subscription ordering.@Nonnull annotations.@Nullable annotation to SimpleQueue.errorHandler.RxJavaPlugins.Completable.subscribe.The most notable enhancement of this version is the inclusion of the ParallelFlowable API that allows parallel execution of a few select operators suc
The most notable enhancement of this version is the inclusion of the ParallelFlowable API that allows parallel execution of a few select operators such as map, filter, concatMap, flatMap, collect, reduce and so on. Note that is a parallel mode for Flowable (a sub-domain specific language) instead of a new reactive base type.
Consequently, several typical operators such as take, skip and many others are not available and there is no ParallelObservable because backpressure is essential in not flooding the internal queues of the parallel operators as by expectation, we want to go parallel because the processing of the data is slow on one thread.
The easiest way of entering the parallel world is by using Flowable.parallel:
ParallelFlowable<Integer> source = Flowable.range(1, 1000).parallel();
By default, the parallelism level is set to the number of available CPUs (Runtime.getRuntime().availableProcessors()) and the prefetch amount from the sequential source is set to Flowable.bufferSize() (128). Both can be specified via overloads of parallel().
ParallelFlowable follows the same principles of parametric asynchrony as Flowable does, therefore, parallel() on itself doesn't introduce the asynchronous consumption of the sequential source but only prepares the parallel flow; the asynchrony is defined via the runOn(Scheduler) operator.
ParallelFlowable<Integer> psource = source.runOn(Schedulers.io());
The parallelism level (ParallelFlowable.parallelism()) doesn't have to match the parallelism level of the Scheduler. The runOn operator will use as many Scheduler.Worker instances as defined by the parallelized source. This allows ParallelFlowable to work for CPU intensive tasks via Schedulers.computation(), blocking/IO bound tasks through Schedulers.io() and unit testing via TestScheduler. You can specify the prefetch amount on runOn as well.
Once the necessary parallel operations have been applied, you can return to the sequential Flowable via the ParallelFlowable.sequential() operator.
Flowable<Integer> result = psource.filter(v -> v % 3 == 0).map(v -> v * v).sequential();
Note that sequential doesn't guarantee any ordering between values flowing through the parallel operators.
For further details, please visit the wiki page about Parallel flows. (New content will be added there as time permits.)
API enhancements
sample() overload that can emit the very last buffered item.strict() operator for strong Reactive-Streams conformanceSingle, Maybe and Completablecompose() genericsCompletable.hide()Flowable.parallel() and parallel operatorsBugfixes
LambdaObserver calling dispose when terminatingtakeUntil() other triggering twicewithLatestFrom null checks, lifecycleObservable.concatMapEager bad logic for immediate scalars.observeOn, flatMap & zipObservable.combineLatest consistent with Flowable, fix early termination cancelling the other sources and document empty source caseA.flatMapB to eagerly check for cancellations before subscribingExecutorScheduler.scheduleDirect to report isDisposed on task completionOther
@CheckReturnValue to create() methods of Subjects + Processorssample() overloads, Maybe and Maybe.switchIfEmpty()compile in the library's POMPull 4930: Add Completable.cache()
Pull 4899: FlowableScanSeed - prevent post-terminal events
Bugfixes
FlowableScanSeed - prevent post-terminal eventsFlowableScan - prevent multiple terminal emissionsdoAfterNext - prevent post-terminal emissionObservable.scan no seed fix post-terminal behaviourObservable.repeatWhen and retryWhenflatMapCompletable change Completable to CompletableSourceOther
t instead of value to allow for IDE namingPull 4858: add Maybe.flatMapSingleElement returning Maybe
API enhancements
Maybe.flatMapSingleElement returning Maybe@CheckReturnValue annotation to aid static verification toolsPerformance enhancements
reduce() op implementationsBugfixes
TestObserver shouldn't clear the upstream disposable on terminatedRxJavaPlugins.onAssembly on opsfirstOrError converted back to Observable/Flowable not reporting NoSuchElementException.Pull 4827: Porting the Scheduler.when operator from 1.x to 2.x
API enhancements
Scheduler.when operator from 1.x to 2.xFlowable.doFinally(Action) for handling post-terminal or cancel cleanup.doFinally to the rest of the reactive base classesFlowable.doAfterNext operatorObservable.doAfterNext and {Single|Maybe}.doAfterSuccess.TestSubscriber.requestMoreDocumentation fixes/enhancements
IllegalArgumentException instead of NullPointerException for calling with null parameter(s).Observable.toFlowable documentationObservableEmitter mentioning FlowableEmitter.Completable.retryWhen terminology about signal emission.Maybe.toSingle@throws implicationsBugfixes
This is it, general availability of RxJava 2! Rewritten from scratch to offer better performance, lower overhead, more features, a modern underlying t
This is it, general availability of RxJava 2! Rewritten from scratch to offer better performance, lower overhead, more features, a modern underlying technology and interoperation with the Reactive-Streams ecosystem. Big thanks goes to the several dozen people who gave feedback, fixes, enhancements and reviewed pull requests in the past, very intensive, 4 months.
Users are encouraged to read the wiki articles What's different in 2.0 and Writing operators for 2.0 to get a overview about changes and differences between working with RxJava 1 and 2. If you find something missing or under-explained, don't worry and open an issue about it!
Some other common libraries such as RxAndroid and Retrofit 2 Adapter were already following the 2.x development and you can expect them to release versions supporting the 2.0.0 GA shortly. In addition, there is an ongoing effort to port companion libraries of RxJava itself to support the 2.x line. For now, several ported features are available as part of the RxJava2Extensions project. RxJava 1 and 2 can live side by side in the same project and the RxJava2Interop library allows dataflow conversions between the two versions.
The sections below contain the changes since 2.0.0-RC5 beyond the general quality and test coverage improvements of the codebase.
API enhancements
Single.fromObservable(ObservableSource)BackpressureStrategy.NONE to MISSINGDocumentation enhancements
Disposables.fromFuturePerformance enhancements
Flowable.publish() and enable operator fusion on its inputFlowable.blockingSubscribe(), Observable.blockingSubscribe() and Flowable.subscribeOn()MapNotification, Materialize, OnErrorReturn last element backpressure under the same helper class.FlowableSequenceEqual in FlowableSequenceEqualSingle.Flowable.scan(T, BiFunction) now emits the initial value only when the upstream signals an event.Bugfixes
Flowable.materialize() terminal signal emission in face of backpressure.Flowable.onErrorReturn() terminal signal emission in face of backpressure.Flowable.flatMapSingle()and Flowable.flatMapMaybe() termination detectiondistinctUntilChanged to store the selected key instead of the valueFlowable.concatMapEager hang due to bad request management.Flowable operators.takeUntil to avoid onSubscribe() races.Flowable.skipUntil lifecycle and concurrency properties.Flowable.concatMapEager error management.subscribeOn to work with blocking create.This release contains API fixes, further cleanups to code and javadoc, better test coverage and bugfixes. Thanks to the respective contributors and @J
This release contains API fixes, further cleanups to code and javadoc, better test coverage and bugfixes. Thanks to the respective contributors and @JakeWharton for the reviews.
API enhancements
Maybe.fromSingle & fromCompletableObservable.rangeLong & Flowable.rangeLong.BaseTestConsumer add assertValueAt(index, Predicate<T>).FlowableOperator and co).Observable.sequenceEqual return Single<Boolean>Flowable.toList(Callable) return SingleretryWhenflatMapIterable(Function, int) overload and have flatMapIterable(Function) use the flatten operator.FlowableEmitter.BackpressureMode into BackpressureStrategyPerformance enhancements
Observable.observeOnBugfixes
Flowable + Single elementAt and elementAtOrError operators on empty sources.flatMapX over-cancellation in case of an inner error.doOnEvent NPE on dispose()CompositeException fix order of exceptionsThrowable order for CompletablePeekObservable.flatMap's dispose behavior and error accumulationFlowable.elementAt on empty sources.Observable.publish(Function) latecommer behaviorObservable.combineLatest error management, fix Observable.flatMap maxConcurrency behavior with scalars, use of unbounded queue, fix Observable.timeInterval not saving the DisposableObservable.just, fix Observable.replay() potential emission before onSubscribe callCollections down to onError in toListonBackpressureBuffer(long, Action, BufferOverflowStrategy) return type, fix concatMapDelayError wrong barrier mode selected.Flowable.flatMap error, cancellation and resource management.Removals
Maybe.toCompletable, use Maybe.ignoreElement.bufferSize overloads of Observable.publish as there is no need to buffer anything for an ObservableflatMapIterable(Function, int) overloadOther
This release contains new operators, further cleanups, better test coverage and bugfixes. Thanks to the respective contributors and @JakeWharton for t
(Maven)
This release contains new operators, further cleanups, better test coverage and bugfixes. Thanks to the respective contributors and @JakeWharton for the reviews.
API enhancements
singleOrError, firstOrError, lastOrError & elementAtOrError to Observable and FlowableCompletable.andThen(MaybeSource)Maybe.flatMapSingleSingle.flatMapMaybeSchedulers initialization via CallableTestSubscriber & TestObserver add assertValue(Predicate).BaseTestConsumer.assertError(Class/Throwable) to remove duplicate code, tests tweaks to remove few IDE warningsCompletable.fromRunnable()TestConsumer don't wrap with CompositeException when there is only one errorflattenAs{Observable,Flowable} to Single and MaybeObservable.compose to use ObservableTransformer.flatMap{Completable, Maybe, Single} operators to Flowable and Observable.Function from transformer interfaces to allow a single obj.Maybe.ignoreElement to return Completable.Performance enhancements
Observable.flatMapIterableonBackpressureBufferBugfixes
onError to Plugin when done.UnicastSubject fix onTerminateCompositeExcepetion thread-safe like 1.x and also fix some issues.ObservableAmb FlowableAmbMaybe and Single to use their Transformers in compose().ConcurrentHashMap to Map to avoid compatibility issue.Removals
takeFirst(predicate) from Observable & FlowableOther
AmbArray and AmbIterable into Amb for Single, Maybe and Completable types.This Release Candidate features mostly internal cleanups of code and Javadoc, Reactive-Streams Test Compatibility Kit implementations (and thus verifi
This Release Candidate features mostly internal cleanups of code and Javadoc, Reactive-Streams Test Compatibility Kit implementations (and thus verification) of our Flowable implementation and additional unit-test coverage. Big thanks to @vanniktech for the many contributions and @JakeWharton for the continued reviews.
Other notable changes:
Maybe type of RC2 now features all relevant operators.Observable and Flowable operators now return Single or Maybe.combineLatest and zip because Function<? super T[], R> doesn't work.delay operator to call onError on the provided schedulerisCancelled to isDisposed inside the varios emitters of create()XObserver implementation to Single, Maybe and CompletableResourceXObserver implementation to Single, Maybe and Completabletimeout operators not properly cancelling/disposing the upstream.Flowable.create()'s FlowableEmitter didn't handle nulls properly.TestSubscriber and TestObserver.In addition, the wiki page What's different in 2.0 has been extended with more information.
This Release Candidate features a large amount of internal fixes, cleanups and enhancements. Please refer to the closed PRs for its milestone. This in
This Release Candidate features a large amount of internal fixes, cleanups and enhancements. Please refer to the closed PRs for its milestone. This includes the bugfix for the Single.subscribeOn failing with Disposable already set! error printed to the console (Issue 4448, Pull 4450).
The library now has a new base reactive type: Maybe which is essentially a Single and Completable combined. You can have exactly 1 onSuccess, 1 onError or 1 onComplete signals with it. Note however that it doesn't have all the operators possible for this type of source but you can convert it back and forth to the other base reactive types (i.e., Flowable, Single, Completable and Observable). Unlike Project Reactor's Mono type, this doesn't implement the Reactive-Streams Publisher (but is designed along the idea) and doesn't have backpressure (as there is no chance of buffer-bloat like with unknown length Flowables and Observables).
RxJava 2.0 has been rewritten from scratch to be more performant, lower overhead (memory and cpu) and to natively implement the Reactive-Streams speci
RxJava 2.0 has been rewritten from scratch to be more performant, lower overhead (memory and cpu) and to natively implement the Reactive-Streams specification in its new Flowable type. The library still supports Java 6+ and is considered a 4th generation reactive library.
There have been hundreds of PRs and large amounts of changes compared to the 1.x version. The two are binary-incompatible but their distinct maven coordinates (io.reactivex.rxjava2:rxjava:2.0.0-RC1) allow them to co-exist. You can use the rxjava2-interop library to convert between 1.x and 2.x types.
Please refer to the wiki page about the differences between the two major versions.
Converting the companion libraries is an ongoing effort. For now, see the rxjava2-extensions project that contains the port of the RxJavaMath features. Note that most companion libraries of RxJava are currently not set up properly for release (the signing keys are missing from the CI release process) and is unknown if and when they will have their own 2.x release branch.
I'd like to thank for the contributions of the following community members (in LIFO commit-merge order):
@davidmoten, @JakeWharton, @vanniktech, @dimitar-asenov, @artem-zinnatullin, @bobvanderlinden, @DmitriyZaitsev, @zsxwing, @bcorne, @stevegury, @benjchristensen, @stealthcode, @adam-arold and @abersnaze.
A special thanks goes out to @smaldini, Project-Reactor lead at Pivotal. Our ongoing cooperation lead to the massive improvement of the RxJava 2.x architecture (originally designed in August 2015) by learning from and building upon the results of the Reactive-Streams-Commons research project.
One column per quarter.