Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RxJava 3 support #538

Closed
Noddy20 opened this issue Jul 2, 2019 · 14 comments
Closed

RxJava 3 support #538

Noddy20 opened this issue Jul 2, 2019 · 14 comments

Comments

@Noddy20
Copy link

Noddy20 commented Jul 2, 2019

How to use this with RxJava 3??
I'm getting duplicate files error on build.
Thank you.

@JakeWharton
Copy link
Member

Because RxJava 3 exists in a different groupId but the same package name you need to tell your build system to replace all dependencies on 2.x with your desired 3.x version.

If your build system is Gradle you can read about dependency substitution here: https://docs.gradle.org/current/userguide/customizing_dependency_resolution_behavior.html#sec:dependency_substitution_rules

Beyond this, you'll want to ask for help on the RxJava project directly or on StackOverflow since there's nothing specific to RxAndroid about the question aside from its 2.x dependency (which is no different than any other library).

@qingmei2
Copy link

qingmei2 commented Jul 11, 2019

Because RxJava 3 exists in a different groupId but the same package name you need to tell your build system to replace all dependencies on 2.x with your desired 3.x version.

If your build system is Gradle you can read about dependency substitution here: https://docs.gradle.org/current/userguide/customizing_dependency_resolution_behavior.html#sec:dependency_substitution_rules

Beyond this, you'll want to ask for help on the RxJava project directly or on StackOverflow since there's nothing specific to RxAndroid about the question aside from its 2.x dependency (which is no different than any other library).

That is correct , you just need exclude external RxJava2 dependency like this:

implementation ('io.reactivex.rxjava2:rxandroid:2.1.0')  {
  exclude group: 'io.reactivex.rxjava2', module: 'rxjava'
}

@JakeWharton
Copy link
Member

It'd be far better long-term to craft a substitution rule than playing whack-a-mole with excludes.

@qingmei2
Copy link

qingmei2 commented Jul 12, 2019

@JakeWharton

Yes, I'm not in the right way, thank you for your guidance. 👏

I read the documentation and configured it as follows,is that alright? 😄

configurations {
    compile.exclude group: 'io.reactivex.rxjava2', module: 'rxjava'
    all {
        resolutionStrategy {
            eachDependency { DependencyResolveDetails details ->
                if (details.requested.group == 'io.reactivex.rxjava3' &&
                        details.requested.name == 'rxjava') {
                    details.useVersion '3.0.0-RC0'
                    details.because 'Unified the version of RxJava3.'
                }
            }
        }
    }
}

dependencies {
    // ...
    implementation rootProject.ext.dependencies['rxjava3']
    implementation rootProject.ext.dependencies['rxandroid']
}

The code above is not in correct way, please refer to the reply below. ⬇️

@Aquarids
Copy link

Will rxAndroid be updated to 3.x with rxJava together?

@JakeWharton
Copy link
Member

JakeWharton commented Jul 23, 2019 via email

@JakeWharton
Copy link
Member

Reopening for tracking.

I would also not use exclude like you did above. Instead, either use a dependency substitution or rewrite the groupId and version of dependencies on RxJava 2. More details at https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html.

@JakeWharton JakeWharton reopened this Jul 25, 2019
@JakeWharton JakeWharton changed the title RxJava 3 RxJava 3 support Jul 25, 2019
@JDDJJ
Copy link

JDDJJ commented Jul 31, 2019

like this?

// add dependency substitution rules
configurations.all {
  resolutionStrategy.dependencySubstitution {
    // Substitute project and module dependencies
    substitute module('org.gradle:api') with project(':api')
    substitute project(':util') with module('org.gradle:util:3.0')

    // Substitute one module dependency for another
    substitute module('org.gradle:api:2.0') with module('org.gradle:api:2.1')
  }
}

@JakeWharton
Copy link
Member

Yes. This snippet is going to be copy/pasta'd around for quite some time:

resolutionStrategy.dependencySubstitution {
    substitute module('io.reactivex.rxjava2:rxjava') with module('io.reactivex.rxjava3:rxjava:3.0.0-RC1')
}

@JakeWharton
Copy link
Member

Please see also ReactiveX/RxJava#6606 which is a discussion around the two problems with migration and compatibility of RxJava 3:

  1. Binary incompatible API changes (without a new groupId/package combo)
  2. New groupId despite the same package

Regardless of what happens with 1, if you're supportive of fixing 2 like I am (by retaining the groupId of 2.x and thus allowing build systems to treat them as providing the same APIs in the sam package) vote/weigh in on that issue.

@qingmei2
Copy link

qingmei2 commented Aug 2, 2019

I found a very strange case (I am not very familiar with the Gradle 😳 ), if my project use multi module like this:

if I just add resolutionStrategy.dependencySubstitution in library module(It seems to be taken for granted that dependency substitution should be configured in the bottom layer...... ):

mylibrary -> build.gradle

configurations.all {
    resolutionStrategy.dependencySubstitution {
        substitute module('io.reactivex.rxjava2:rxjava') with module('io.reactivex.rxjava3:rxjava:3.0.0-RC1')
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    api 'io.reactivex.rxjava3:rxjava:3.0.0-RC1'
    api 'io.reactivex.rxjava2:rxandroid:2.1.0'
}

app -> build.gradle(no resolutionStrategy.dependencySubstitution)

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(path: ':mylibrary')
    // ...
}

when I tried to build and run app, I got an error:


* What went wrong:
Execution failed for task ':app:checkDebugDuplicateClasses'.
> 1 exception was raised by workers:
  java.lang.RuntimeException: java.lang.RuntimeException: Duplicate class io.reactivex.BackpressureOverflowStrategy found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.BackpressureStrategy found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.Completable found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.CompletableConverter found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.CompletableEmitter found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.CompletableObserver found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.CompletableOnSubscribe found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.CompletableOperator found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.CompletableSource found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.CompletableTransformer found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.Emitter found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.Flowable found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.FlowableConverter found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.FlowableEmitter found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)
  Duplicate class io.reactivex.FlowableOnSubscribe found in modules rxjava-2.2.0.jar (io.reactivex.rxjava2:rxjava:2.2.0) and rxjava-3.0.0-RC1.jar (io.reactivex.rxjava3:rxjava:3.0.0-RC1)

I thought this way could not fulfill my needs, so I config mylibrary -> build.gradle like my reply above:

configurations {
    // use exclude
    compile.exclude group: 'io.reactivex.rxjava2', module: 'rxjava'
    all {
        resolutionStrategy {
            eachDependency { DependencyResolveDetails details ->
                if (details.requested.group == 'io.reactivex.rxjava3' &&
                        details.requested.name == 'rxjava') {
                    details.useVersion '3.0.0-RC0'
                    details.because 'Unified the version of RxJava3.'
                }
            }
        }
    }
}

Subsequent attempts

When I saw the solution code of Jake, I found that I took an indirect route, finally I tried it in my app -> build.gradle

configurations.all {
    resolutionStrategy.dependencySubstitution {
        substitute module('io.reactivex.rxjava2:rxjava') with module('io.reactivex.rxjava3:rxjava:3.0.0-RC1')
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(path: ':mylibrary')
}

and remove dependencySubstitution in mylibrary -> build.gradle:

//configurations.all {
//    resolutionStrategy.dependencySubstitution {
//        substitute module('io.reactivex.rxjava2:rxjava') with module('io.reactivex.rxjava3:rxjava:3.0.0-RC1')
//    }
//}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    api 'io.reactivex.rxjava3:rxjava:3.0.0-RC1'
    api 'io.reactivex.rxjava2:rxandroid:2.1.0'
    // ...
}

Moving the dependencySubstitution from library module to app module, and it works! 🎉

@drewhamilton
Copy link
Contributor

Now that RxJava 3.0.0-RC2 has moved everything to a new package, the dependency substitution workaround mentioned above no longer applies, and currently RxJavaBridge needs to be used to use RxAndroid with with RxJava 3.

Can I offer a PR upgrading RxAndroid to RxJava 3 so an alpha/RC/whatever can be released?

@JakeWharton
Copy link
Member

Landed on 3.x branch... I'll figure out Travis

@JakeWharton
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants