3.x: Potential migration/compatibility issues
See original GitHub issueIntro:
Since RxJava has a very compelling interface it is widely used as such. Some libraries also use it internally. RxJava 2 and 3 have some breaking changes but they both live in same packages.
Problem:
(I am not an expert in this field but here it goes) Dependencies in Java are resolved by the full name (i.e. package + class name). Since the package name has not changed between RxJava 2 and 3 there are duplicate classes found during compilation. If two libraries (first level dependencies) have a dependency different major versions of RxJava (as a second level dependency to your app) they will not compile together.
Using gradle
it is possible to make a first level dependency use a different second level dependency than it declares by using the below code in build.gradle
file:
resolutionStrategy.dependencySubstitution {
substitute module('io.reactivex.rxjava2:rxjava') with module('io.reactivex.rxjava3:rxjava:3.0.0-RC1')
}
But then there is a good chance that some of those libraries will face binary incompatibilities introduced between RxJava 2 and 3.
This poses a potential logistics problem for the applications consuming RxJava based libraries. There is no way to ensure that those libs dependent on RxJava 2 and 3 will work together — the app developer would need to substitute libs that do not allow to be used with one a specific RxJava version or postpone migration. Developers would potentially need to wait until all their dependencies will migrate to RxJava 3 before they can switch. There is no way to create an interop between RxJava 2 and 3 like it was the case with RxJava 1 and 2.
Question:
Has this problem been considered?
Ideas:
- Add new RxJava 3 operators to RxJava
2.3.x
. E.g.:
Supplier<T>
,Observable/Single.defer(Supplier<T>)
but keepObservable/Single.defer(Callable<T>)
(mark it as@Deprecated
and point to the new function), etc.Observable.startWithItem(T)
but keepObservable.startWith(T)
- others if possible This could make a usable subset of RxJava 2 binary compatible with RxJava 3 allowing it to easily swapped at a later point when adoption is high enough.
- Keep only
Observable
,Flowable
,Single
,Completable
and their.subcribe()
functions in the main package so they could be exposed as an API of all libraries that are ofRxLibrary
kind and the operator implementations in some extensions / other packages. This could make the usage more cumbersome in Java (but Kotlin language has extensions so this could be mitigated somewhat). This could make the Rx API more future-proof
This issue is a place for discussion (while somewhat related to #6524)
Issue Analytics
- State:
- Created 4 years ago
- Reactions:31
- Comments:19 (15 by maintainers)
After careful considerations of all target environments (Android/Desktop/Server) as well as any future major versions targeting Java 9+, I decided the path with the least problems will be having RxJava 3 reside in the new group id and in a new package entirely:
Group ID:
io.reactivex.rxjava3
Package:io.reactivex.rxjava3.**
.In addition, the base classes and interfaces (i.e.,
Flowable
,FlowableSubscriber
,Observable
) will be moved to a subpackagecore
:io.reactivex.rxjava3.core.Flowable
. A reason for this is that with modules, opening upio.reactivex.rxjava3
opens up all subpackages, includinginternal
which can’t be hidden then on as far as I know.Since
Flowable
s arePublisher
’s, interoperation between the v2 and v3 variants is a given: either use them as is with parameters/arguments declared asPublisher
or useFlowable.fromPublisher
.The other types won’t be such lucky as
ObservableSource
is present in both v2 and v3 and isn’t external unlike Reactive Streams. Those can’t talk to each other without an actual (trivial) bridge library.I have an android app that depends on 12 libraries all depending on rxjava2. I don’t understand my path forward.
Do I need to wait for all 12 to upgrade if one does and uses a new api?