From 28a559483b991fe094141cc99e54dd8b9adb8f8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Apr 2021 12:05:02 +0200 Subject: [PATCH 001/348] Bump com.vanniktech.maven.publish from 0.14.2 to 0.15.0 (#7246) Bumps [com.vanniktech.maven.publish](https://github.com/vanniktech/gradle-maven-publish-plugin) from 0.14.2 to 0.15.0. - [Release notes](https://github.com/vanniktech/gradle-maven-publish-plugin/releases) - [Changelog](https://github.com/vanniktech/gradle-maven-publish-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/vanniktech/gradle-maven-publish-plugin/compare/0.14.2...0.15.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7358b2609b..061e15d08b 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ plugins { id("com.github.hierynomus.license") version "0.15.0" id("com.jfrog.artifactory") version "4.21.0" id("biz.aQute.bnd.builder") version "5.3.0" - id("com.vanniktech.maven.publish") version "0.14.2" + id("com.vanniktech.maven.publish") version "0.15.0" } ext { From 0792e059237ec804f2992ebd665fd0a65020698c Mon Sep 17 00:00:00 2001 From: David Karnok Date: Mon, 26 Apr 2021 12:28:44 +0200 Subject: [PATCH 002/348] Update env names for release plugin v0.15 (#7247) #7246 --- .github/workflows/gradle_release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index 432d4d3eef..9683482ad2 100644 --- a/.github/workflows/gradle_release.yml +++ b/.github/workflows/gradle_release.yml @@ -44,8 +44,8 @@ jobs: env: # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions # ------------------------------------------------------------------------------ - ORG_GRADLE_PROJECT_SONATYPE_NEXUS_USERNAME: ${{ secrets.SONATYPE_USER }} - ORG_GRADLE_PROJECT_SONATYPE_NEXUS_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + ORG_GRADLE_PROJECT_mavenCentralRepositoryUsername: ${{ secrets.SONATYPE_USER }} + ORG_GRADLE_PROJECT_mavenCentralRepositoryPassword: ${{ secrets.SONATYPE_PASSWORD }} ORG_GRADLE_PROJECT_SIGNING_PRIVATE_KEY: ${{ secrets.SIGNING_PRIVATE_KEY }} ORG_GRADLE_PROJECT_SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} - name: Publish release @@ -53,8 +53,8 @@ jobs: env: # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions # ------------------------------------------------------------------------------ - ORG_GRADLE_PROJECT_SONATYPE_NEXUS_USERNAME: ${{ secrets.SONATYPE_USER }} - ORG_GRADLE_PROJECT_SONATYPE_NEXUS_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + ORG_GRADLE_PROJECT_mavenCentralRepositoryUsername: ${{ secrets.SONATYPE_USER }} + ORG_GRADLE_PROJECT_mavenCentralRepositoryPassword: ${{ secrets.SONATYPE_PASSWORD }} - name: Push Javadocs run: ./push_javadoc.sh env: From 3ad6bc105bc74aaa9f04026d207755f9cc40ae28 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Mon, 3 May 2021 11:51:05 +0200 Subject: [PATCH 003/348] Update gradle_release.yml Rename maven central credential properties --- .github/workflows/gradle_release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index 9683482ad2..891fa0859a 100644 --- a/.github/workflows/gradle_release.yml +++ b/.github/workflows/gradle_release.yml @@ -44,8 +44,8 @@ jobs: env: # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions # ------------------------------------------------------------------------------ - ORG_GRADLE_PROJECT_mavenCentralRepositoryUsername: ${{ secrets.SONATYPE_USER }} - ORG_GRADLE_PROJECT_mavenCentralRepositoryPassword: ${{ secrets.SONATYPE_PASSWORD }} + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USER }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} ORG_GRADLE_PROJECT_SIGNING_PRIVATE_KEY: ${{ secrets.SIGNING_PRIVATE_KEY }} ORG_GRADLE_PROJECT_SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} - name: Publish release @@ -53,8 +53,8 @@ jobs: env: # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions # ------------------------------------------------------------------------------ - ORG_GRADLE_PROJECT_mavenCentralRepositoryUsername: ${{ secrets.SONATYPE_USER }} - ORG_GRADLE_PROJECT_mavenCentralRepositoryPassword: ${{ secrets.SONATYPE_PASSWORD }} + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USER }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} - name: Push Javadocs run: ./push_javadoc.sh env: From 94ed352d49ed102086b466ae268afbd6ae17951b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 12:08:09 +0200 Subject: [PATCH 004/348] Bump com.vanniktech.maven.publish from 0.15.0 to 0.15.1 (#7250) Bumps [com.vanniktech.maven.publish](https://github.com/vanniktech/gradle-maven-publish-plugin) from 0.15.0 to 0.15.1. - [Release notes](https://github.com/vanniktech/gradle-maven-publish-plugin/releases) - [Changelog](https://github.com/vanniktech/gradle-maven-publish-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/vanniktech/gradle-maven-publish-plugin/compare/0.15.0...0.15.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 061e15d08b..9c0aa000f5 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ plugins { id("com.github.hierynomus.license") version "0.15.0" id("com.jfrog.artifactory") version "4.21.0" id("biz.aQute.bnd.builder") version "5.3.0" - id("com.vanniktech.maven.publish") version "0.15.0" + id("com.vanniktech.maven.publish") version "0.15.1" } ext { From 56cd564f67a263923500ec590965548644d1bd93 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Mon, 3 May 2021 14:15:38 +0200 Subject: [PATCH 005/348] Try fixing snapshot releases, attempt 1 --- .github/workflows/gradle_snapshot.yml | 10 ++++---- build.gradle | 36 ++++++++++++--------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index 099f5e9e91..ddd72b67bb 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -32,14 +32,14 @@ jobs: - name: Grant execute permission for push run: chmod +x push_javadoc.sh - name: Build and Snapshot branch - run: ./gradlew -PreleaseMode=branch -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" build --stacktrace + run: ./gradlew -PreleaseMode=branch build --stacktrace --no-daemon + - name: Upload Snapshot + run: ./gradlew -PreleaseMode=branch javadocCleanup uploadArchives --no-daemon --no-parallel --stacktrace env: # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions # ------------------------------------------------------------------------------ - bintrayUser: ${{ secrets.BINTRAY_USER }} - bintrayKey: ${{ secrets.BINTRAY_KEY }} - sonatypeUsername: ${{ secrets.SONATYPE_USER }} - sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }} + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USER }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} - name: Upload to Codecov uses: codecov/codecov-action@v1 - name: Push Javadocs diff --git a/build.gradle b/build.gradle index 9c0aa000f5..da06dfbc85 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,6 @@ plugins { id("ru.vyarus.animalsniffer") version "1.5.3" id("me.champeau.gradle.jmh") version "0.5.3" id("com.github.hierynomus.license") version "0.15.0" - id("com.jfrog.artifactory") version "4.21.0" id("biz.aQute.bnd.builder") version "5.3.0" id("com.vanniktech.maven.publish") version "0.15.1" } @@ -209,27 +208,24 @@ if (rootProject.hasProperty("releaseMode")) { logger.lifecycle("ReleaseMode: {}", rootProject.releaseMode) if ("branch".equals(rootProject.releaseMode)) { - // From https://github.com/ReactiveX/RxAndroid/blob/2.x/rxandroid/build.gradle#L94 - artifactory { - contextUrl = "https://oss.jfrog.org" - - publish { - repository { - repoKey = "oss-snapshot-local" - - username = rootProject.bintrayUser - password = rootProject.bintrayKey - } - - defaults { - publishConfigs("archives") - } - - fixPom() + + if (version.endsWith("-SNAPSHOT")) { + fixPom() + + publishing { + repositories { + maven { + url = "https://s01.oss.sonatype.org/content/repositories/snapshots/" + } } + } + + mavenPublish { + nexus { + stagingProfile = "io.reactivex" + } + } } - - build.finalizedBy(artifactoryPublish) } if ("full".equals(rootProject.releaseMode)) { From c4163c96549c18c21595ff30bc647c805ef103a9 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Mon, 3 May 2021 14:17:40 +0200 Subject: [PATCH 006/348] Don't do full build yet, saves time with trying the new snapshot push --- .github/workflows/gradle_snapshot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index ddd72b67bb..4db8fbfb8f 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -32,7 +32,7 @@ jobs: - name: Grant execute permission for push run: chmod +x push_javadoc.sh - name: Build and Snapshot branch - run: ./gradlew -PreleaseMode=branch build --stacktrace --no-daemon + run: ./gradlew -PreleaseMode=branch assemble --stacktrace --no-daemon - name: Upload Snapshot run: ./gradlew -PreleaseMode=branch javadocCleanup uploadArchives --no-daemon --no-parallel --stacktrace env: From 4aa1c43b0b620eecb65e91f19c8e56ee5d9bf46a Mon Sep 17 00:00:00 2001 From: akarnokd Date: Mon, 3 May 2021 14:29:37 +0200 Subject: [PATCH 007/348] Re-enable snapshot full build, update README --- .github/workflows/gradle_snapshot.yml | 2 +- README.md | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index 4db8fbfb8f..ddd72b67bb 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -32,7 +32,7 @@ jobs: - name: Grant execute permission for push run: chmod +x push_javadoc.sh - name: Build and Snapshot branch - run: ./gradlew -PreleaseMode=branch assemble --stacktrace --no-daemon + run: ./gradlew -PreleaseMode=branch build --stacktrace --no-daemon - name: Upload Snapshot run: ./gradlew -PreleaseMode=branch javadocCleanup uploadArchives --no-daemon --no-parallel --stacktrace env: diff --git a/README.md b/README.md index b14ae42f84..8e894869f7 100644 --- a/README.md +++ b/README.md @@ -565,7 +565,20 @@ and for Ivy: ### Snapshots -Snapshots are available via https://oss.jfrog.org/libs-snapshot/io/reactivex/rxjava3/rxjava/ +Snapshots after May 1st, 2021 are available via https://oss.sonatype.org/content/repositories/snapshots/io/reactivex/rxjava3/rxjava/ + +```groovy +repositories { + maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } +} + +dependencies { + implementation 'io.reactivex.rxjava3:rxjava:3.0.0-SNAPSHOT' +} +``` + +Snapshots before May 1st, 2021 are available via https://oss.jfrog.org/libs-snapshot/io/reactivex/rxjava3/rxjava/ +(Note that due to the Sunset of Bintray, our jfrog access has been severed, hence the new snapshot repo above.) ```groovy repositories { @@ -573,7 +586,7 @@ repositories { } dependencies { - compile 'io.reactivex.rxjava3:rxjava:3.0.0-SNAPSHOT' + implementation 'io.reactivex.rxjava3:rxjava:3.0.0-SNAPSHOT' } ``` From 93e5216ac1f352aea78eda14f933d2bf536a6a50 Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Tue, 4 May 2021 23:28:55 -0700 Subject: [PATCH 008/348] Remove fixPom method from build.gradle (#7253) The pom is generated with the reactive-streams scope set to 'compile' by default. To test that this works, the below gradle tasks were run: ./gradlew -PreleaseMode=full cleanGeneratePomFileForMavenPublication generatePomFileForMavenPublication ./gradlew -PreleaseMode=branch cleanGeneratePomFileForMavenPublication generatePomFileForMavenPublication Both tasks generated a pom file with the reactive-streams set to 'compile' scope. --- build.gradle | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/build.gradle b/build.gradle index da06dfbc85..5d66ba9bfd 100644 --- a/build.gradle +++ b/build.gradle @@ -191,27 +191,12 @@ checkstyle { apply from: file("gradle/javadoc_cleanup.gradle") -def fixPom() { - // Reactive-Streams as compile dependency - publishing.publications.all { - pom.withXml { - asNode().dependencies."*".findAll() { - it.scope.text() == "runtime" && project.configurations.compile.allDependencies.find { dep -> - dep.name == it.artifactId.text() - } - }.each { it.scope*.value = "compile"} - } - } -} - if (rootProject.hasProperty("releaseMode")) { logger.lifecycle("ReleaseMode: {}", rootProject.releaseMode) if ("branch".equals(rootProject.releaseMode)) { if (version.endsWith("-SNAPSHOT")) { - fixPom() - publishing { repositories { maven { @@ -229,8 +214,6 @@ if (rootProject.hasProperty("releaseMode")) { } if ("full".equals(rootProject.releaseMode)) { - fixPom() - signing { if (project.hasProperty("SIGNING_PRIVATE_KEY") && project.hasProperty("SIGNING_PASSWORD")) { useInMemoryPgpKeys(project.getProperty("SIGNING_PRIVATE_KEY"), project.getProperty("SIGNING_PASSWORD")) From 06294de92d5f6ebb4870e64a84055460163630cc Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Wed, 5 May 2021 10:47:48 -0700 Subject: [PATCH 009/348] Update Gradle task dependencies to remove dependsOn 'build' task (#7255) It is generally discouraged to add dependencies on 'build', so 'javadocCleanup' and 'jacocoTestReport' have been removed and put on better tasks. Also, 'jacocoTestReport' needs input from the test results. Updated task dependencies: - Gradle 'javadoc' task is finalized by 'javadocCleanup', and 'javadocCleanup' no longer directly invoked by 'build' - Gradle 'jacocoTestReport' task run by 'check' instead of 'build', and 'jacocoTestReport' depends on 'test' and 'testng' Changes due to dependency updates: - Add 'javadoc' generation task on Github actions that only 'build' - Remove 'javadocCleanup' task from Github action as 'publish...' tasks already dependent on 'javadoc' Miscellaneous tangential cleanup: - Remove "pr" parameter on command line in Github workflow as parameter is no longer functional - Enclose source/target compatibility in Gradle java block --- .github/workflows/gradle_branch.yml | 4 +++- .github/workflows/gradle_jdk11.yml | 6 +++--- .github/workflows/gradle_pr.yml | 6 ++++-- .github/workflows/gradle_release.yml | 2 +- .github/workflows/gradle_snapshot.yml | 3 +-- build.gradle | 19 +++++++++++++------ gradle/javadoc_cleanup.gradle | 1 - 7 files changed, 25 insertions(+), 16 deletions(-) diff --git a/.github/workflows/gradle_branch.yml b/.github/workflows/gradle_branch.yml index 214939c0d9..96acfc3a9d 100644 --- a/.github/workflows/gradle_branch.yml +++ b/.github/workflows/gradle_branch.yml @@ -27,6 +27,8 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build branch without snapshot - run: ./gradlew -PreleaseMode=pr build --stacktrace + run: ./gradlew build --stacktrace - name: Upload to Codecov uses: codecov/codecov-action@v1 + - name: Generate Javadocs + run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_jdk11.yml b/.github/workflows/gradle_jdk11.yml index 9bbafd6615..697bcca364 100644 --- a/.github/workflows/gradle_jdk11.yml +++ b/.github/workflows/gradle_jdk11.yml @@ -29,6 +29,6 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build PR - run: ./gradlew -PreleaseMode=pr build --stacktrace - #- name: Upload to Codecov - # uses: codecov/codecov-action@v1 + run: ./gradlew build --stacktrace + - name: Generate Javadocs + run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_pr.yml b/.github/workflows/gradle_pr.yml index 5b8310c635..9d3b33d517 100644 --- a/.github/workflows/gradle_pr.yml +++ b/.github/workflows/gradle_pr.yml @@ -1,7 +1,7 @@ # This workflow will build a Java project with Gradle # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle -name: PR +name: Pull Request on: pull_request: @@ -27,6 +27,8 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build PR - run: ./gradlew -PreleaseMode=pr build --stacktrace + run: ./gradlew build --stacktrace - name: Upload to Codecov uses: codecov/codecov-action@v1 + - name: Generate Javadocs + run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index 891fa0859a..2050936863 100644 --- a/.github/workflows/gradle_release.yml +++ b/.github/workflows/gradle_release.yml @@ -40,7 +40,7 @@ jobs: - name: Upload to Codecov uses: codecov/codecov-action@v1 - name: Upload release - run: ./gradlew -PreleaseMode=full javadocCleanup uploadArchives --no-daemon --no-parallel --stacktrace + run: ./gradlew -PreleaseMode=full uploadArchives --no-daemon --no-parallel --stacktrace env: # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions # ------------------------------------------------------------------------------ diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index ddd72b67bb..8d4457a497 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -34,7 +34,7 @@ jobs: - name: Build and Snapshot branch run: ./gradlew -PreleaseMode=branch build --stacktrace --no-daemon - name: Upload Snapshot - run: ./gradlew -PreleaseMode=branch javadocCleanup uploadArchives --no-daemon --no-parallel --stacktrace + run: ./gradlew -PreleaseMode=branch uploadArchives --no-daemon --no-parallel --stacktrace env: # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions # ------------------------------------------------------------------------------ @@ -48,4 +48,3 @@ jobs: # ------------------------------------------------------------------------------ env: JAVADOCS_TOKEN: ${{ secrets.JAVADOCS_TOKEN }} - diff --git a/build.gradle b/build.gradle index 5d66ba9bfd..9a2c3de5cd 100644 --- a/build.gradle +++ b/build.gradle @@ -36,9 +36,6 @@ group = "io.reactivex.rxjava3" version = project.properties["VERSION_NAME"] description = "RxJava: Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM." -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 - repositories { mavenCentral() } @@ -57,10 +54,17 @@ dependencies { testImplementation "com.google.guava:guava:$guavaVersion" } +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + tasks.withType(JavaCompile) { options.compilerArgs << "-parameters" } +apply from: file("gradle/javadoc_cleanup.gradle") + javadoc { failOnError = false exclude "**/internal/**" @@ -80,6 +84,8 @@ javadoc { "https://docs.oracle.com/javase/8/docs/api/", "http://www.reactive-streams.org/reactive-streams-${reactiveStreamsVersion}-javadoc/" ) + + finalizedBy javadocCleanup } animalsniffer { @@ -172,13 +178,16 @@ jacoco { } jacocoTestReport { + dependsOn test + dependsOn testng + reports { xml.enabled = true html.enabled = true } } -build.dependsOn jacocoTestReport +check.dependsOn jacocoTestReport checkstyle { configFile = rootProject.file("config/checkstyle/checkstyle.xml") @@ -189,8 +198,6 @@ checkstyle { ] } -apply from: file("gradle/javadoc_cleanup.gradle") - if (rootProject.hasProperty("releaseMode")) { logger.lifecycle("ReleaseMode: {}", rootProject.releaseMode) diff --git a/gradle/javadoc_cleanup.gradle b/gradle/javadoc_cleanup.gradle index f6811fdcaf..f9f365f4a3 100644 --- a/gradle/javadoc_cleanup.gradle +++ b/gradle/javadoc_cleanup.gradle @@ -57,4 +57,3 @@ def fixJavadocFile(file) { file.setText(fileContents, 'UTF-8'); } -build.dependsOn javadocCleanup \ No newline at end of file From 8fb4640688a1229ed2e09d6618bce10fcb622cf2 Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Wed, 5 May 2021 13:54:51 -0700 Subject: [PATCH 010/348] Remove redundant addition of JMH to classpath (#7257) Remove manual addition of JMH classpath in build file. Gradle adds classpath for all sourceSets to Eclipse by default as fixed in Gradle 6.8 by PR 14534. The JMH sourceSet is added by the JMH Plugin. Tested by running 'eclipse' task in Eclipse 2021-03 (4.19.0). Then refreshing, and JMH still on classpath and viewable in Eclipse. Then removed project from Eclipse, ran 'cleanEclipse', and re-imported project to Eclipse. All successful. --- build.gradle | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build.gradle b/build.gradle index 9a2c3de5cd..1a4e6ace04 100644 --- a/build.gradle +++ b/build.gradle @@ -126,10 +126,6 @@ jmh { } } -plugins.withType(EclipsePlugin) { - project.eclipse.classpath.plusConfigurations += [configurations.jmh] -} - test { testLogging { // showing skipped occasionally should prevent CI timeout due to lack of standard output From ac5e569072dee77402f3bb85fa60ce94f5581987 Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Wed, 5 May 2021 23:51:16 -0700 Subject: [PATCH 011/348] Remove Javadoc not failing on error (#7258) The 'javadoc' task should fail when there is an error. The 'javadocCleanup' task failed for PR 7239 due to a plugin issue 242, while it should have been the 'javadoc' task that failed the build. Also, publishing when javadocs fail is not desired. --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1a4e6ace04..d39a630675 100644 --- a/build.gradle +++ b/build.gradle @@ -66,7 +66,6 @@ tasks.withType(JavaCompile) { apply from: file("gradle/javadoc_cleanup.gradle") javadoc { - failOnError = false exclude "**/internal/**" exclude "**/test/**" exclude "**/perf/**" From 0a9b09e62511174edd13194c9e3b2e43c906b1a6 Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Thu, 6 May 2021 22:02:29 -0700 Subject: [PATCH 012/348] 3.x: Gradle wrapper 7 0 (#7259) * Update Gradle Wrapper to 7.0 * Update com.github.hierynomus.license from 0.15.0 to 0.16.1 --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d39a630675..b1b07a7e5a 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { id("maven-publish") id("ru.vyarus.animalsniffer") version "1.5.3" id("me.champeau.gradle.jmh") version "0.5.3" - id("com.github.hierynomus.license") version "0.15.0" + id("com.github.hierynomus.license") version "0.16.1" id("biz.aQute.bnd.builder") version "5.3.0" id("com.vanniktech.maven.publish") version "0.15.1" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 442d9132ea..f371643eed 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 2f4815d79287d50589a226db5395ab7525bfbcc6 Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Thu, 6 May 2021 22:21:45 -0700 Subject: [PATCH 013/348] 3.x: Move Gradle properties into gradle.properties file (#7260) * Move Gradle properties into gradle.properties file Moved version, group, and description into gradle.properties file. Removed POM_ARTIFACT property as the 'name' property in the settings file is used when building the POM. Removed 'release.scope' property as it does not appear to be used. Removed VERSION_NAME property and references to it, in favor of 'version' property. * Replace POM_ARTIFACT_ID in gradle.properties Added POM_ARTIFACT_ID=rxjava in gradle.properties file --- build.gradle | 8 ++------ gradle.properties | 6 +++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index b1b07a7e5a..b2fd3f888b 100644 --- a/build.gradle +++ b/build.gradle @@ -27,15 +27,11 @@ if (releaseTag != null && !releaseTag.isEmpty()) { if (releaseTag.startsWith("v")) { releaseTag = releaseTag.substring(1) } - project.setProperty("VERSION_NAME" , releaseTag) + project.version = releaseTag - logger.info("Releasing with version: {}", version) + logger.lifecycle("Releasing with version: " + project.version) } -group = "io.reactivex.rxjava3" -version = project.properties["VERSION_NAME"] -description = "RxJava: Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM." - repositories { mavenCentral() } diff --git a/gradle.properties b/gradle.properties index 8da73143fa..e685b8103a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ -release.scope=patch -VERSION_NAME=3.0.0-SNAPSHOT +group=io.reactivex.rxjava3 +version=3.0.0-SNAPSHOT +description=RxJava: Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM. -GROUP=io.reactivex.rxjava3 POM_ARTIFACT_ID=rxjava POM_NAME=RxJava POM_PACKAGING=jar From 177256eecde749dbf120a51e19f8af4555cae3f1 Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Fri, 7 May 2021 01:24:27 -0700 Subject: [PATCH 014/348] Remove toolVersion for jacoco and checkstyle (#7261) Remove versioning of Jacoco and Checkstyle. Instead they will be updated by Gradle when it is updated. Dependabot does not update tool versions. If issues come up, they can be corrected when Gradle is updated. --- build.gradle | 7 ------- 1 file changed, 7 deletions(-) diff --git a/build.gradle b/build.gradle index b2fd3f888b..329e8347fe 100644 --- a/build.gradle +++ b/build.gradle @@ -18,8 +18,6 @@ ext { mockitoVersion = "3.9.0" jmhLibVersion = "1.21" guavaVersion = "30.1.1-jre" - jacocoVersion = "0.8.4" - checkstyleVersion = "8.41" } def releaseTag = System.getenv("BUILD_TAG") @@ -164,10 +162,6 @@ task testng(type: Test) { check.dependsOn testng -jacoco { - toolVersion = jacocoVersion -} - jacocoTestReport { dependsOn test dependsOn testng @@ -182,7 +176,6 @@ check.dependsOn jacocoTestReport checkstyle { configFile = rootProject.file("config/checkstyle/checkstyle.xml") - toolVersion = checkstyleVersion configProperties = [ "checkstyle.suppressions.file": rootProject.file("config/checkstyle/suppressions.xml"), "checkstyle.header.file": rootProject.file("config/license/HEADER_JAVA") From 74ab2485b9b44b541fffad557d106a41b4ff39f5 Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Fri, 7 May 2021 02:12:30 -0700 Subject: [PATCH 015/348] Rename workflow tasks (#7262) Change 'build' tasks name to Build RxJava. Update Javadoc task names. --- .github/workflows/gradle_branch.yml | 4 ++-- .github/workflows/gradle_jdk11.yml | 4 ++-- .github/workflows/gradle_pr.yml | 4 ++-- .github/workflows/gradle_release.yml | 6 +++--- .github/workflows/gradle_snapshot.yml | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/gradle_branch.yml b/.github/workflows/gradle_branch.yml index 96acfc3a9d..f0454433b3 100644 --- a/.github/workflows/gradle_branch.yml +++ b/.github/workflows/gradle_branch.yml @@ -26,9 +26,9 @@ jobs: restore-keys: ${{ runner.os }}-gradle-${{ secrets.CACHE_VERSION }} - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Build branch without snapshot + - name: Build RxJava run: ./gradlew build --stacktrace - name: Upload to Codecov uses: codecov/codecov-action@v1 - - name: Generate Javadocs + - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_jdk11.yml b/.github/workflows/gradle_jdk11.yml index 697bcca364..13a89abd91 100644 --- a/.github/workflows/gradle_jdk11.yml +++ b/.github/workflows/gradle_jdk11.yml @@ -28,7 +28,7 @@ jobs: restore-keys: ${{ runner.os }}-gradle-1- - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Build PR + - name: Build RxJava run: ./gradlew build --stacktrace - - name: Generate Javadocs + - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_pr.yml b/.github/workflows/gradle_pr.yml index 9d3b33d517..dbf3d6f1ca 100644 --- a/.github/workflows/gradle_pr.yml +++ b/.github/workflows/gradle_pr.yml @@ -26,9 +26,9 @@ jobs: restore-keys: ${{ runner.os }}-gradle-1- - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Build PR + - name: Build RxJava run: ./gradlew build --stacktrace - name: Upload to Codecov uses: codecov/codecov-action@v1 - - name: Generate Javadocs + - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index 2050936863..bbce6f6b43 100644 --- a/.github/workflows/gradle_release.yml +++ b/.github/workflows/gradle_release.yml @@ -35,8 +35,8 @@ jobs: run: chmod +x push_javadoc.sh - name: Extract version tag run: echo "BUILD_TAG=${GITHUB_REF:10}" >> $GITHUB_ENV - - name: Build and Release - run: ./gradlew -PreleaseMode=full build --stacktrace --no-daemon + - name: Build RxJava + run: ./gradlew build --stacktrace --no-daemon - name: Upload to Codecov uses: codecov/codecov-action@v1 - name: Upload release @@ -55,7 +55,7 @@ jobs: # ------------------------------------------------------------------------------ ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USER }} ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} - - name: Push Javadocs + - name: Push Javadoc run: ./push_javadoc.sh env: # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index 8d4457a497..d0d0ddea2c 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -31,8 +31,8 @@ jobs: run: chmod +x gradlew - name: Grant execute permission for push run: chmod +x push_javadoc.sh - - name: Build and Snapshot branch - run: ./gradlew -PreleaseMode=branch build --stacktrace --no-daemon + - name: Build RxJava + run: ./gradlew build --stacktrace --no-daemon - name: Upload Snapshot run: ./gradlew -PreleaseMode=branch uploadArchives --no-daemon --no-parallel --stacktrace env: @@ -42,7 +42,7 @@ jobs: ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} - name: Upload to Codecov uses: codecov/codecov-action@v1 - - name: Push Javadocs + - name: Push Javadoc run: ./push_javadoc.sh # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions # ------------------------------------------------------------------------------ From 63fcf838988f33fbad10dc67072c8d6e4a517ac5 Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Fri, 7 May 2021 04:10:20 -0700 Subject: [PATCH 016/348] Updated javadocCleanup to use logger and remove semi-colons (#7264) --- gradle/javadoc_cleanup.gradle | 75 +++++++++++++++++------------------ 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/gradle/javadoc_cleanup.gradle b/gradle/javadoc_cleanup.gradle index f9f365f4a3..a391375af4 100644 --- a/gradle/javadoc_cleanup.gradle +++ b/gradle/javadoc_cleanup.gradle @@ -1,59 +1,58 @@ // remove the excessive whitespaces between method arguments in the javadocs task javadocCleanup(dependsOn: "javadoc") doLast { - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/core/Flowable.html')); - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/core/Observable.html')); - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/core/Single.html')); - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/core/Maybe.html')); - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/core/Completable.html')); + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/core/Flowable.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/core/Observable.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/core/Single.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/core/Maybe.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/core/Completable.html')) - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/flowables/ConnectableFlowable.html')); - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/observables/ConnectableObservable.html')); + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/flowables/ConnectableFlowable.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/observables/ConnectableObservable.html')) - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/subjects/ReplaySubject.html')); - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/processors/ReplayProcessor.html')); - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/plugins/RxJavaPlugins.html')); + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/subjects/ReplaySubject.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/processors/ReplayProcessor.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/plugins/RxJavaPlugins.html')) - fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/parallel/ParallelFlowable.html')); + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/parallel/ParallelFlowable.html')) } def fixJavadocFile(file) { - println("Cleaning up: " + file); + logger.lifecycle("Cleaning up: " + file) String fileContents = file.getText('UTF-8') // lots of spaces after the previous method argument - fileContents = fileContents.replaceAll(",\\s{4,}", ",\n "); + fileContents = fileContents.replaceAll(",\\s{4,}", ",\n ") // lots of spaces after the @NonNull annotations - fileContents = fileContents.replaceAll("@NonNull\\s{4,}", "@NonNull "); + fileContents = fileContents.replaceAll("@NonNull\\s{4,}", "@NonNull ") // lots of spaces after the @Nullable annotations - fileContents = fileContents.replaceAll("@Nullable\\s{4,}", "@Nullable "); + fileContents = fileContents.replaceAll("@Nullable\\s{4,}", "@Nullable ") // javadoc bug: duplicates the link to @NonNull for some reason - def nonNullText1 = "@NonNull"; - - fileContents = fileContents.replace(nonNullText1 + " " + nonNullText1, nonNullText1); - fileContents = fileContents.replace(nonNullText1 + "\n " + nonNullText1, nonNullText1); - fileContents = fileContents.replace(nonNullText1 + "\r\n " + nonNullText1, nonNullText1); + def nonNullText1 = "@NonNull" - def nonNullText2 = "@NonNull"; - fileContents = fileContents.replace(nonNullText2 + " " + nonNullText2, nonNullText2); - fileContents = fileContents.replace(nonNullText2 + "\n " + nonNullText2, nonNullText2); - fileContents = fileContents.replace(nonNullText2 + "\r\n " + nonNullText2, nonNullText2); + fileContents = fileContents.replace(nonNullText1 + " " + nonNullText1, nonNullText1) + fileContents = fileContents.replace(nonNullText1 + "\n " + nonNullText1, nonNullText1) + fileContents = fileContents.replace(nonNullText1 + "\r\n " + nonNullText1, nonNullText1) + + def nonNullText2 = "@NonNull" + fileContents = fileContents.replace(nonNullText2 + " " + nonNullText2, nonNullText2) + fileContents = fileContents.replace(nonNullText2 + "\n " + nonNullText2, nonNullText2) + fileContents = fileContents.replace(nonNullText2 + "\r\n " + nonNullText2, nonNullText2) // javadoc bug: duplicates the link to @Nullable for some reason - def nullableText1 = "@Nullable"; - - fileContents = fileContents.replace(nullableText1 + " " + nullableText1, nullableText1); - fileContents = fileContents.replace(nullableText1 + "\n " + nullableText1, nullableText1); - fileContents = fileContents.replace(nullableText1 + "\r\n " + nullableText1, nullableText1); - - def nullableText2 = "@Nullable"; - - fileContents = fileContents.replace(nullableText2 + " " + nullableText2, nullableText2); - fileContents = fileContents.replace(nullableText2 + "\n " + nullableText2, nullableText2); - fileContents = fileContents.replace(nullableText2 + "\r\n " + nullableText2, nullableText2); - - file.setText(fileContents, 'UTF-8'); -} + def nullableText1 = "@Nullable" + + fileContents = fileContents.replace(nullableText1 + " " + nullableText1, nullableText1) + fileContents = fileContents.replace(nullableText1 + "\n " + nullableText1, nullableText1) + fileContents = fileContents.replace(nullableText1 + "\r\n " + nullableText1, nullableText1) + def nullableText2 = "@Nullable" + + fileContents = fileContents.replace(nullableText2 + " " + nullableText2, nullableText2) + fileContents = fileContents.replace(nullableText2 + "\n " + nullableText2, nullableText2) + fileContents = fileContents.replace(nullableText2 + "\r\n " + nullableText2, nullableText2) + + file.setText(fileContents, 'UTF-8') +} From a5dad0c66a9fab7685efbcc504d64b3c6d80330f Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Fri, 7 May 2021 06:10:41 -0700 Subject: [PATCH 017/348] 3.x: Consolidate test logging (#7263) * Consolidate test logging Move test logging to consolidated block. Change all 'rootProject' to 'project'. * Only do parallel testing on non-CI machines --- build.gradle | 67 +++++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/build.gradle b/build.gradle index 329e8347fe..535aefc268 100644 --- a/build.gradle +++ b/build.gradle @@ -71,7 +71,7 @@ javadoc { options.addStringOption("top").value = "" options.addStringOption("doctitle").value = "" options.addStringOption("header").value = "" - options.stylesheetFile = rootProject.file("gradle/stylesheet.css") + options.stylesheetFile = project.file("gradle/stylesheet.css") options.links( "https://docs.oracle.com/javase/8/docs/api/", @@ -99,7 +99,7 @@ jar { } license { - header rootProject.file("config/license/HEADER") + header project.file("config/license/HEADER") ext.year = Calendar.getInstance().get(Calendar.YEAR) skipExistingHeaders true ignoreFailures true @@ -120,51 +120,38 @@ jmh { } test { + maxHeapSize = "1200m" +} + +task testNG(type: Test) { + useTestNG() +} + +check.dependsOn testNG + +tasks.withType(Test) { testLogging { - // showing skipped occasionally should prevent CI timeout due to lack of standard output - events=["skipped", "failed"] // "started", "passed" - // showStandardStreams = true - exceptionFormat="full" + events = ["skipped", "failed"] + exceptionFormat = "full" debug.events = ["skipped", "failed"] - debug.exceptionFormat="full" + debug.exceptionFormat = "full" info.events = ["failed", "skipped"] - info.exceptionFormat="full" - + info.exceptionFormat = "full" + warn.events = ["failed", "skipped"] - warn.exceptionFormat="full" + warn.exceptionFormat = "full" } - maxHeapSize = "1200m" - if (System.getenv("CI") == null) { maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 } } -task testng(type: Test) { - useTestNG() - testLogging { - events=["skipped", "failed"] - exceptionFormat="full" - - debug.events = ["skipped", "failed"] - debug.exceptionFormat="full" - - info.events = ["failed", "skipped"] - info.exceptionFormat="full" - - warn.events = ["failed", "skipped"] - warn.exceptionFormat="full" - } -} - -check.dependsOn testng - jacocoTestReport { dependsOn test - dependsOn testng + dependsOn testNG reports { xml.enabled = true @@ -175,18 +162,18 @@ jacocoTestReport { check.dependsOn jacocoTestReport checkstyle { - configFile = rootProject.file("config/checkstyle/checkstyle.xml") + configFile = project.file("config/checkstyle/checkstyle.xml") configProperties = [ - "checkstyle.suppressions.file": rootProject.file("config/checkstyle/suppressions.xml"), - "checkstyle.header.file": rootProject.file("config/license/HEADER_JAVA") + "checkstyle.suppressions.file": project.file("config/checkstyle/suppressions.xml"), + "checkstyle.header.file": project.file("config/license/HEADER_JAVA") ] } -if (rootProject.hasProperty("releaseMode")) { - logger.lifecycle("ReleaseMode: {}", rootProject.releaseMode) +if (project.hasProperty("releaseMode")) { + logger.lifecycle("ReleaseMode: {}", project.releaseMode) + + if ("branch" == project.releaseMode) { - if ("branch".equals(rootProject.releaseMode)) { - if (version.endsWith("-SNAPSHOT")) { publishing { repositories { @@ -204,7 +191,7 @@ if (rootProject.hasProperty("releaseMode")) { } } - if ("full".equals(rootProject.releaseMode)) { + if ("full" == project.releaseMode) { signing { if (project.hasProperty("SIGNING_PRIVATE_KEY") && project.hasProperty("SIGNING_PASSWORD")) { useInMemoryPgpKeys(project.getProperty("SIGNING_PRIVATE_KEY"), project.getProperty("SIGNING_PASSWORD")) From aeb5e683b6474482ce540f03cea73d22c3af25f8 Mon Sep 17 00:00:00 2001 From: benjamintboyle Date: Sat, 8 May 2021 14:06:32 -0700 Subject: [PATCH 018/348] Fix minor formatting issues in build.gradle (#7265) --- build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 535aefc268..c47fbdd8f7 100644 --- a/build.gradle +++ b/build.gradle @@ -74,8 +74,8 @@ javadoc { options.stylesheetFile = project.file("gradle/stylesheet.css") options.links( - "https://docs.oracle.com/javase/8/docs/api/", - "http://www.reactive-streams.org/reactive-streams-${reactiveStreamsVersion}-javadoc/" + "https://docs.oracle.com/javase/8/docs/api/", + "http://www.reactive-streams.org/reactive-streams-${reactiveStreamsVersion}-javadoc/" ) finalizedBy javadocCleanup @@ -124,13 +124,13 @@ test { } task testNG(type: Test) { - useTestNG() + useTestNG() } check.dependsOn testNG tasks.withType(Test) { - testLogging { + testLogging { events = ["skipped", "failed"] exceptionFormat = "full" @@ -165,7 +165,7 @@ checkstyle { configFile = project.file("config/checkstyle/checkstyle.xml") configProperties = [ "checkstyle.suppressions.file": project.file("config/checkstyle/suppressions.xml"), - "checkstyle.header.file": project.file("config/license/HEADER_JAVA") + "checkstyle.header.file" : project.file("config/license/HEADER_JAVA") ] } From f92590088decda924da7dd2922059b8825c3cb09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 May 2021 09:14:33 +0200 Subject: [PATCH 019/348] Bump gradle/wrapper-validation-action from 1 to 1.0.3 (#7268) Bumps [gradle/wrapper-validation-action](https://github.com/gradle/wrapper-validation-action) from 1 to 1.0.3. - [Release notes](https://github.com/gradle/wrapper-validation-action/releases) - [Commits](https://github.com/gradle/wrapper-validation-action/compare/v1...v1.0.3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 405a2b3065..b7256f2ec9 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -7,4 +7,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/wrapper-validation-action@v1.0.3 From c3f5e3999512e6455c1a8ede6434793f9c56de9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 May 2021 09:41:06 +0200 Subject: [PATCH 020/348] Bump codecov/codecov-action from 1 to 1.5.0 (#7270) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1 to 1.5.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v1...v1.5.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gradle_branch.yml | 2 +- .github/workflows/gradle_pr.yml | 2 +- .github/workflows/gradle_release.yml | 2 +- .github/workflows/gradle_snapshot.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gradle_branch.yml b/.github/workflows/gradle_branch.yml index f0454433b3..952a2b89c0 100644 --- a/.github/workflows/gradle_branch.yml +++ b/.github/workflows/gradle_branch.yml @@ -29,6 +29,6 @@ jobs: - name: Build RxJava run: ./gradlew build --stacktrace - name: Upload to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v1.5.0 - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_pr.yml b/.github/workflows/gradle_pr.yml index dbf3d6f1ca..962203d3df 100644 --- a/.github/workflows/gradle_pr.yml +++ b/.github/workflows/gradle_pr.yml @@ -29,6 +29,6 @@ jobs: - name: Build RxJava run: ./gradlew build --stacktrace - name: Upload to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v1.5.0 - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index bbce6f6b43..15503e17b6 100644 --- a/.github/workflows/gradle_release.yml +++ b/.github/workflows/gradle_release.yml @@ -38,7 +38,7 @@ jobs: - name: Build RxJava run: ./gradlew build --stacktrace --no-daemon - name: Upload to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v1.5.0 - name: Upload release run: ./gradlew -PreleaseMode=full uploadArchives --no-daemon --no-parallel --stacktrace env: diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index d0d0ddea2c..6ca347425f 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -41,7 +41,7 @@ jobs: ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USER }} ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} - name: Upload to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v1.5.0 - name: Push Javadoc run: ./push_javadoc.sh # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions From fc11bd33a7a9dd722750f7998e5c94edf292a238 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 May 2021 09:56:29 +0200 Subject: [PATCH 021/348] Bump actions/checkout from 2 to 2.3.4 (#7269) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 2.3.4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v2.3.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- .github/workflows/gradle_branch.yml | 2 +- .github/workflows/gradle_jdk11.yml | 2 +- .github/workflows/gradle_pr.yml | 2 +- .github/workflows/gradle_release.yml | 2 +- .github/workflows/gradle_snapshot.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index b7256f2ec9..792b87079d 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -6,5 +6,5 @@ jobs: name: "Validation" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - uses: gradle/wrapper-validation-action@v1.0.3 diff --git a/.github/workflows/gradle_branch.yml b/.github/workflows/gradle_branch.yml index 952a2b89c0..3824624722 100644 --- a/.github/workflows/gradle_branch.yml +++ b/.github/workflows/gradle_branch.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - name: Set up JDK 8 uses: actions/setup-java@v2 with: diff --git a/.github/workflows/gradle_jdk11.yml b/.github/workflows/gradle_jdk11.yml index 13a89abd91..14c6951714 100644 --- a/.github/workflows/gradle_jdk11.yml +++ b/.github/workflows/gradle_jdk11.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - name: Set up JDK 11 uses: actions/setup-java@v2 with: diff --git a/.github/workflows/gradle_pr.yml b/.github/workflows/gradle_pr.yml index 962203d3df..583b09dab4 100644 --- a/.github/workflows/gradle_pr.yml +++ b/.github/workflows/gradle_pr.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - name: Set up JDK 8 uses: actions/setup-java@v2 with: diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index 15503e17b6..10242b730f 100644 --- a/.github/workflows/gradle_release.yml +++ b/.github/workflows/gradle_release.yml @@ -17,7 +17,7 @@ jobs: env: CI_BUILD_NUMBER: ${{ github.run_number }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - name: Set up JDK 8 uses: actions/setup-java@v2 with: diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index 6ca347425f..934f3bde83 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -15,7 +15,7 @@ jobs: # ------------------------------------------------------------------------------ CI_BUILD_NUMBER: ${{ github.run_number }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - name: Set up JDK 8 uses: actions/setup-java@v2 with: From b7e2f19378dd7e07ae254ed5ce0ede3f9646ce99 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 12 May 2021 14:21:01 +0200 Subject: [PATCH 022/348] 3.x: Fix copy-paste error in Completable javadoc (#7272) --- src/main/java/io/reactivex/rxjava3/core/Completable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/reactivex/rxjava3/core/Completable.java b/src/main/java/io/reactivex/rxjava3/core/Completable.java index 805cd8f63f..05b3f8b240 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Completable.java +++ b/src/main/java/io/reactivex/rxjava3/core/Completable.java @@ -52,7 +52,7 @@ * Note that as with the {@code Observable} protocol, {@code onError} and {@code onComplete} are mutually exclusive events. *

* Like {@code Observable}, a running {@code Completable} can be stopped through the {@link Disposable} instance - * provided to consumers through {@link SingleObserver#onSubscribe}. + * provided to consumers through {@link CompletableObserver#onSubscribe}. *

* Like an {@code Observable}, a {@code Completable} is lazy, can be either "hot" or "cold", synchronous or * asynchronous. {@code Completable} instances returned by the methods of this class are cold From 3ba64ceb023614836f09961c8a0f3f94cbfcc2ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 May 2021 09:10:10 +0200 Subject: [PATCH 023/348] Bump mockito-core from 3.9.0 to 3.10.0 (#7273) Bumps [mockito-core](https://github.com/mockito/mockito) from 3.9.0 to 3.10.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.9.0...v3.10.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c47fbdd8f7..a7d5418d75 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ ext { reactiveStreamsVersion = "1.0.3" junitVersion = "4.13.2" testNgVersion = "7.4.0" - mockitoVersion = "3.9.0" + mockitoVersion = "3.10.0" jmhLibVersion = "1.21" guavaVersion = "30.1.1-jre" } From 771616c401061f989bed17ce441e60791b3cf7ea Mon Sep 17 00:00:00 2001 From: David Karnok Date: Fri, 14 May 2021 22:08:20 +0200 Subject: [PATCH 024/348] 3.x: Javadoc: Fix wording of *OnSubscribe interfaces (#7274) --- .../java/io/reactivex/rxjava3/core/CompletableOnSubscribe.java | 2 +- .../java/io/reactivex/rxjava3/core/FlowableOnSubscribe.java | 2 +- src/main/java/io/reactivex/rxjava3/core/MaybeOnSubscribe.java | 2 +- .../java/io/reactivex/rxjava3/core/ObservableOnSubscribe.java | 2 +- src/main/java/io/reactivex/rxjava3/core/SingleOnSubscribe.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/reactivex/rxjava3/core/CompletableOnSubscribe.java b/src/main/java/io/reactivex/rxjava3/core/CompletableOnSubscribe.java index 0ac107e64b..e73fae2d5c 100644 --- a/src/main/java/io/reactivex/rxjava3/core/CompletableOnSubscribe.java +++ b/src/main/java/io/reactivex/rxjava3/core/CompletableOnSubscribe.java @@ -17,7 +17,7 @@ /** * A functional interface that has a {@code subscribe()} method that receives - * an instance of a {@link CompletableEmitter} instance that allows pushing + * a {@link CompletableEmitter} instance that allows pushing * an event in a cancellation-safe manner. */ @FunctionalInterface diff --git a/src/main/java/io/reactivex/rxjava3/core/FlowableOnSubscribe.java b/src/main/java/io/reactivex/rxjava3/core/FlowableOnSubscribe.java index c289a9e30b..6c5263b779 100644 --- a/src/main/java/io/reactivex/rxjava3/core/FlowableOnSubscribe.java +++ b/src/main/java/io/reactivex/rxjava3/core/FlowableOnSubscribe.java @@ -17,7 +17,7 @@ /** * A functional interface that has a {@code subscribe()} method that receives - * an instance of a {@link FlowableEmitter} instance that allows pushing + * a {@link FlowableEmitter} instance that allows pushing * events in a backpressure-safe and cancellation-safe manner. * * @param the value type pushed diff --git a/src/main/java/io/reactivex/rxjava3/core/MaybeOnSubscribe.java b/src/main/java/io/reactivex/rxjava3/core/MaybeOnSubscribe.java index 6c235bac84..67994d3d40 100644 --- a/src/main/java/io/reactivex/rxjava3/core/MaybeOnSubscribe.java +++ b/src/main/java/io/reactivex/rxjava3/core/MaybeOnSubscribe.java @@ -17,7 +17,7 @@ /** * A functional interface that has a {@code subscribe()} method that receives - * an instance of a {@link MaybeEmitter} instance that allows pushing + * a {@link MaybeEmitter} instance that allows pushing * an event in a cancellation-safe manner. * * @param the value type pushed diff --git a/src/main/java/io/reactivex/rxjava3/core/ObservableOnSubscribe.java b/src/main/java/io/reactivex/rxjava3/core/ObservableOnSubscribe.java index 587ab9372c..056441620a 100644 --- a/src/main/java/io/reactivex/rxjava3/core/ObservableOnSubscribe.java +++ b/src/main/java/io/reactivex/rxjava3/core/ObservableOnSubscribe.java @@ -17,7 +17,7 @@ /** * A functional interface that has a {@code subscribe()} method that receives - * an instance of an {@link ObservableEmitter} instance that allows pushing + * an {@link ObservableEmitter} instance that allows pushing * events in a cancellation-safe manner. * * @param the value type pushed diff --git a/src/main/java/io/reactivex/rxjava3/core/SingleOnSubscribe.java b/src/main/java/io/reactivex/rxjava3/core/SingleOnSubscribe.java index 9372cb5bdf..e8b9e89f8b 100644 --- a/src/main/java/io/reactivex/rxjava3/core/SingleOnSubscribe.java +++ b/src/main/java/io/reactivex/rxjava3/core/SingleOnSubscribe.java @@ -17,7 +17,7 @@ /** * A functional interface that has a {@code subscribe()} method that receives - * an instance of a {@link SingleEmitter} instance that allows pushing + * a {@link SingleEmitter} instance that allows pushing * an event in a cancellation-safe manner. * * @param the value type pushed From 1d7e8acb3e1fa035a30248a9195a35c7537200b7 Mon Sep 17 00:00:00 2001 From: Ikko Ashimine Date: Thu, 27 May 2021 15:38:19 +0900 Subject: [PATCH 025/348] 3.x: fix typo in ObservableRetryTest.java (#7277) seperate -> separate --- .../internal/operators/observable/ObservableRetryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableRetryTest.java b/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableRetryTest.java index 285299b83d..13f19fb547 100644 --- a/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableRetryTest.java +++ b/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableRetryTest.java @@ -572,7 +572,7 @@ public void run() { } } - /** Observer for listener on seperate thread. */ + /** Observer for listener on separate thread. */ static final class AsyncObserver extends DefaultObserver { protected CountDownLatch latch = new CountDownLatch(1); From 327fa44fc7bc93e87057bf14f7be37b7a3e496ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 May 2021 09:08:49 +0200 Subject: [PATCH 026/348] Bump actions/cache from 2.1.5 to 2.1.6 (#7278) Bumps [actions/cache](https://github.com/actions/cache) from 2.1.5 to 2.1.6. - [Release notes](https://github.com/actions/cache/releases) - [Commits](https://github.com/actions/cache/compare/v2.1.5...v2.1.6) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gradle_branch.yml | 2 +- .github/workflows/gradle_jdk11.yml | 2 +- .github/workflows/gradle_pr.yml | 2 +- .github/workflows/gradle_release.yml | 2 +- .github/workflows/gradle_snapshot.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/gradle_branch.yml b/.github/workflows/gradle_branch.yml index 3824624722..a0d99b4ade 100644 --- a/.github/workflows/gradle_branch.yml +++ b/.github/workflows/gradle_branch.yml @@ -19,7 +19,7 @@ jobs: distribution: 'adopt' java-version: '8' - name: Cache Gradle packages - uses: actions/cache@v2.1.5 + uses: actions/cache@v2.1.6 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-${{ secrets.CACHE_VERSION }}-${{ hashFiles('**/*.gradle') }} diff --git a/.github/workflows/gradle_jdk11.yml b/.github/workflows/gradle_jdk11.yml index 14c6951714..9b30f8da56 100644 --- a/.github/workflows/gradle_jdk11.yml +++ b/.github/workflows/gradle_jdk11.yml @@ -21,7 +21,7 @@ jobs: distribution: 'adopt' java-version: '11' - name: Cache Gradle packages - uses: actions/cache@v2.1.5 + uses: actions/cache@v2.1.6 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-1-${{ hashFiles('**/*.gradle') }} diff --git a/.github/workflows/gradle_pr.yml b/.github/workflows/gradle_pr.yml index 583b09dab4..7490665ca4 100644 --- a/.github/workflows/gradle_pr.yml +++ b/.github/workflows/gradle_pr.yml @@ -19,7 +19,7 @@ jobs: distribution: 'adopt' java-version: '8' - name: Cache Gradle packages - uses: actions/cache@v2.1.5 + uses: actions/cache@v2.1.6 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-1-${{ hashFiles('**/*.gradle') }} diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index 10242b730f..9b15018c13 100644 --- a/.github/workflows/gradle_release.yml +++ b/.github/workflows/gradle_release.yml @@ -24,7 +24,7 @@ jobs: distribution: 'adopt' java-version: '8' - name: Cache Gradle packages - uses: actions/cache@v2.1.5 + uses: actions/cache@v2.1.6 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-${{ secrets.CACHE_VERSION }}-${{ hashFiles('**/*.gradle') }} diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index 934f3bde83..ca58fa2e5f 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -22,7 +22,7 @@ jobs: distribution: 'adopt' java-version: '8' - name: Cache Gradle packages - uses: actions/cache@v2.1.5 + uses: actions/cache@v2.1.6 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-${{ secrets.CACHE_VERSION }}-${{ hashFiles('**/*.gradle') }} From 47c599cb7f976f147b53a32482fb853ecf875da7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 May 2021 10:58:59 +0200 Subject: [PATCH 027/348] Bump gradle/wrapper-validation-action from 1.0.3 to 1.0.4 (#7279) Bumps [gradle/wrapper-validation-action](https://github.com/gradle/wrapper-validation-action) from 1.0.3 to 1.0.4. - [Release notes](https://github.com/gradle/wrapper-validation-action/releases) - [Commits](https://github.com/gradle/wrapper-validation-action/compare/v1.0.3...v1.0.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 792b87079d..184acdb502 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -7,4 +7,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.3.4 - - uses: gradle/wrapper-validation-action@v1.0.3 + - uses: gradle/wrapper-validation-action@v1.0.4 From 0df952e007814da9f2d4566097676590b977c708 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Jun 2021 09:37:53 +0200 Subject: [PATCH 028/348] Bump mockito-core from 3.10.0 to 3.11.0 (#7280) Bumps [mockito-core](https://github.com/mockito/mockito) from 3.10.0 to 3.11.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.10.0...v3.11.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a7d5418d75..1fb0f2ee22 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ ext { reactiveStreamsVersion = "1.0.3" junitVersion = "4.13.2" testNgVersion = "7.4.0" - mockitoVersion = "3.10.0" + mockitoVersion = "3.11.0" jmhLibVersion = "1.21" guavaVersion = "30.1.1-jre" } From e38337779936d053b86001a0d5a98bccb83341f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Jun 2021 08:47:43 +0200 Subject: [PATCH 029/348] Bump codecov/codecov-action from 1.5.0 to 1.5.2 (#7282) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1.5.0 to 1.5.2. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v1.5.0...v1.5.2) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gradle_branch.yml | 2 +- .github/workflows/gradle_pr.yml | 2 +- .github/workflows/gradle_release.yml | 2 +- .github/workflows/gradle_snapshot.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gradle_branch.yml b/.github/workflows/gradle_branch.yml index a0d99b4ade..27a45e5ccc 100644 --- a/.github/workflows/gradle_branch.yml +++ b/.github/workflows/gradle_branch.yml @@ -29,6 +29,6 @@ jobs: - name: Build RxJava run: ./gradlew build --stacktrace - name: Upload to Codecov - uses: codecov/codecov-action@v1.5.0 + uses: codecov/codecov-action@v1.5.2 - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_pr.yml b/.github/workflows/gradle_pr.yml index 7490665ca4..dbc5418a92 100644 --- a/.github/workflows/gradle_pr.yml +++ b/.github/workflows/gradle_pr.yml @@ -29,6 +29,6 @@ jobs: - name: Build RxJava run: ./gradlew build --stacktrace - name: Upload to Codecov - uses: codecov/codecov-action@v1.5.0 + uses: codecov/codecov-action@v1.5.2 - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index 9b15018c13..d25da22464 100644 --- a/.github/workflows/gradle_release.yml +++ b/.github/workflows/gradle_release.yml @@ -38,7 +38,7 @@ jobs: - name: Build RxJava run: ./gradlew build --stacktrace --no-daemon - name: Upload to Codecov - uses: codecov/codecov-action@v1.5.0 + uses: codecov/codecov-action@v1.5.2 - name: Upload release run: ./gradlew -PreleaseMode=full uploadArchives --no-daemon --no-parallel --stacktrace env: diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index ca58fa2e5f..76b402cf15 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -41,7 +41,7 @@ jobs: ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USER }} ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} - name: Upload to Codecov - uses: codecov/codecov-action@v1.5.0 + uses: codecov/codecov-action@v1.5.2 - name: Push Javadoc run: ./push_javadoc.sh # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions From 17366435ba5df7f37b97ad50e38748bf3917ff9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Jun 2021 10:13:32 +0200 Subject: [PATCH 030/348] Bump mockito-core from 3.11.0 to 3.11.1 (#7283) Bumps [mockito-core](https://github.com/mockito/mockito) from 3.11.0 to 3.11.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.11.0...v3.11.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1fb0f2ee22..bd5035b4a5 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ ext { reactiveStreamsVersion = "1.0.3" junitVersion = "4.13.2" testNgVersion = "7.4.0" - mockitoVersion = "3.11.0" + mockitoVersion = "3.11.1" jmhLibVersion = "1.21" guavaVersion = "30.1.1-jre" } From df0dd4c9cf5955ae8519545482a36b45519609cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Jun 2021 10:28:30 +0200 Subject: [PATCH 031/348] Bump com.vanniktech.maven.publish from 0.15.1 to 0.16.0 (#7285) Bumps [com.vanniktech.maven.publish](https://github.com/vanniktech/gradle-maven-publish-plugin) from 0.15.1 to 0.16.0. - [Release notes](https://github.com/vanniktech/gradle-maven-publish-plugin/releases) - [Changelog](https://github.com/vanniktech/gradle-maven-publish-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/vanniktech/gradle-maven-publish-plugin/compare/0.15.1...0.16.0) --- updated-dependencies: - dependency-name: com.vanniktech.maven.publish dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index bd5035b4a5..9fd4473214 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { id("me.champeau.gradle.jmh") version "0.5.3" id("com.github.hierynomus.license") version "0.16.1" id("biz.aQute.bnd.builder") version "5.3.0" - id("com.vanniktech.maven.publish") version "0.15.1" + id("com.vanniktech.maven.publish") version "0.16.0" } ext { From 578b4f880abd64400a5c64914ef668d20d580983 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Mon, 21 Jun 2021 10:55:45 +0200 Subject: [PATCH 032/348] Rollback the publish plugin --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9fd4473214..bd5035b4a5 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { id("me.champeau.gradle.jmh") version "0.5.3" id("com.github.hierynomus.license") version "0.16.1" id("biz.aQute.bnd.builder") version "5.3.0" - id("com.vanniktech.maven.publish") version "0.16.0" + id("com.vanniktech.maven.publish") version "0.15.1" } ext { From 91a10d46ff993aba749c393035d402d607bd7424 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Jun 2021 08:08:53 +0200 Subject: [PATCH 033/348] Bump mockito-core from 3.11.1 to 3.11.2 (#7287) Bumps [mockito-core](https://github.com/mockito/mockito) from 3.11.1 to 3.11.2. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.11.1...v3.11.2) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index bd5035b4a5..dcc510846b 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ ext { reactiveStreamsVersion = "1.0.3" junitVersion = "4.13.2" testNgVersion = "7.4.0" - mockitoVersion = "3.11.1" + mockitoVersion = "3.11.2" jmhLibVersion = "1.21" guavaVersion = "30.1.1-jre" } From 4749ab3879dcfb4afcf84edcade6141a7221c194 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Mon, 5 Jul 2021 13:27:48 +0200 Subject: [PATCH 034/348] 3.x: Update withLatestFrom doc about upstream early complete (#7289) * 3.x: Update withLatestFrom doc about upstream early complete * Fix singular wording --- .../io/reactivex/rxjava3/core/Flowable.java | 17 +++++++++++++++++ .../io/reactivex/rxjava3/core/Observable.java | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/main/java/io/reactivex/rxjava3/core/Flowable.java b/src/main/java/io/reactivex/rxjava3/core/Flowable.java index 5a6579fb34..a9f7b0a3b6 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Flowable.java +++ b/src/main/java/io/reactivex/rxjava3/core/Flowable.java @@ -19233,6 +19233,13 @@ public final Flowable> window( /** * Merges the specified {@link Publisher} into the current {@code Flowable} sequence by using the {@code resultSelector} * function only when the current {@code Flowable} (this instance) emits an item. + * + *

Note that this operator doesn't emit anything until the other source has produced at + * least one value. The resulting emission only happens when the current {@code Flowable} emits (and + * not when the other source emits, unlike combineLatest). + * If the other source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before the other source has produced at least one value, the sequence completes + * without emission. *

* * @@ -19277,6 +19284,8 @@ public final Flowable> window( * least one value. The resulting emission only happens when the current {@code Flowable} emits (and * not when any of the other sources emit, unlike combineLatest). * If a source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before all other sources have produced at least one value, the sequence completes + * without emission. * *

*
Backpressure:
@@ -19317,6 +19326,8 @@ public final Flowable> window( * least one value. The resulting emission only happens when the current {@code Flowable} emits (and * not when any of the other sources emit, unlike combineLatest). * If a source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before all other sources have produced at least one value, the sequence completes + * without emission. * *
*
Backpressure:
@@ -19362,6 +19373,8 @@ public final Flowable> window( * least one value. The resulting emission only happens when the current {@code Flowable} emits (and * not when any of the other sources emit, unlike combineLatest). * If a source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before all other sources have produced at least one value, the sequence completes + * without emission. * *
*
Backpressure:
@@ -19411,6 +19424,8 @@ public final Flowable> window( * least one value. The resulting emission only happens when the current {@code Flowable} emits (and * not when any of the other sources emit, unlike combineLatest). * If a source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before all other sources have produced at least one value, the sequence completes + * without emission. * *
*
Backpressure:
@@ -19445,6 +19460,8 @@ public final Flowable> window( * least one value. The resulting emission only happens when the current {@code Flowable} emits (and * not when any of the other sources emit, unlike combineLatest). * If a source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before all other sources have produced at least one value, the sequence completes + * without emission. * *
*
Backpressure:
diff --git a/src/main/java/io/reactivex/rxjava3/core/Observable.java b/src/main/java/io/reactivex/rxjava3/core/Observable.java index 3e343bf248..27d46ad8c5 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Observable.java +++ b/src/main/java/io/reactivex/rxjava3/core/Observable.java @@ -16074,6 +16074,13 @@ public final Observable> window( /** * Merges the specified {@link ObservableSource} into the current {@code Observable} sequence by using the {@code resultSelector} * function only when the current {@code Observable} emits an item. + * + *

Note that this operator doesn't emit anything until the other source has produced at + * least one value. The resulting emission only happens when the current {@code Observable} emits (and + * not when the other source emits, unlike combineLatest). + * If the other source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before the other source has produced at least one value, the sequence completes + * without emission. *

* * @@ -16112,6 +16119,8 @@ public final Observable withLatestFrom(@NonNull ObservableSource * *

@@ -16150,6 +16159,8 @@ public final Observable withLatestFrom( * least one value. The resulting emission only happens when the current {@code Observable} emits (and * not when any of the other sources emit, unlike combineLatest). * If a source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before all other sources have produced at least one value, the sequence completes + * without emission. *

* *

@@ -16192,6 +16203,8 @@ public final Observable withLatestFrom( * least one value. The resulting emission only happens when the current {@code Observable} emits (and * not when any of the other sources emit, unlike combineLatest). * If a source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before all other sources have produced at least one value, the sequence completes + * without emission. *

* *

@@ -16238,6 +16251,8 @@ public final Observable withLatestFrom( * least one value. The resulting emission only happens when the current {@code Observable} emits (and * not when any of the other sources emit, unlike combineLatest). * If a source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before all other sources have produced at least one value, the sequence completes + * without emission. *

* *

@@ -16269,6 +16284,8 @@ public final Observable withLatestFrom(@NonNull ObservableSource[] oth * least one value. The resulting emission only happens when the current {@code Observable} emits (and * not when any of the other sources emit, unlike {@code combineLatest}). * If a source doesn't produce any value and just completes, the sequence is completed immediately. + * If the upstream completes before all other sources have produced at least one value, the sequence completes + * without emission. *

* *

From 3ba0ce4779717c41de563a8c655091813d6dc423 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jul 2021 08:36:50 +0200 Subject: [PATCH 035/348] Bump com.vanniktech.maven.publish from 0.15.1 to 0.17.0 (#7290) Bumps [com.vanniktech.maven.publish](https://github.com/vanniktech/gradle-maven-publish-plugin) from 0.15.1 to 0.17.0. - [Release notes](https://github.com/vanniktech/gradle-maven-publish-plugin/releases) - [Changelog](https://github.com/vanniktech/gradle-maven-publish-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/vanniktech/gradle-maven-publish-plugin/compare/0.15.1...0.17.0) --- updated-dependencies: - dependency-name: com.vanniktech.maven.publish dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index dcc510846b..af6102f1c9 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { id("me.champeau.gradle.jmh") version "0.5.3" id("com.github.hierynomus.license") version "0.16.1" id("biz.aQute.bnd.builder") version "5.3.0" - id("com.vanniktech.maven.publish") version "0.15.1" + id("com.vanniktech.maven.publish") version "0.17.0" } ext { From 828afc786bde58b3d26d8064baaa40b1d2025491 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 7 Jul 2021 08:56:59 +0200 Subject: [PATCH 036/348] Fix 0.17.0 plugin config https://github.com/vanniktech/gradle-maven-publish-plugin/issues/275#issuecomment-864967048 --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index af6102f1c9..367a9b3678 100644 --- a/build.gradle +++ b/build.gradle @@ -172,6 +172,7 @@ checkstyle { if (project.hasProperty("releaseMode")) { logger.lifecycle("ReleaseMode: {}", project.releaseMode) + /* if ("branch" == project.releaseMode) { if (version.endsWith("-SNAPSHOT")) { @@ -190,6 +191,7 @@ if (project.hasProperty("releaseMode")) { } } } + */ if ("full" == project.releaseMode) { signing { @@ -197,10 +199,12 @@ if (project.hasProperty("releaseMode")) { useInMemoryPgpKeys(project.getProperty("SIGNING_PRIVATE_KEY"), project.getProperty("SIGNING_PASSWORD")) } } + /* mavenPublish { nexus { stagingProfile = "io.reactivex" } } + */ } } From 9ecf8ab36362f2e664f31ed7b9938e028b860140 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 7 Jul 2021 09:17:25 +0200 Subject: [PATCH 037/348] Update gradle_snapshot.yml release plugin now uses the "publish" command --- .github/workflows/gradle_snapshot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index 76b402cf15..ed101d8536 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -34,7 +34,7 @@ jobs: - name: Build RxJava run: ./gradlew build --stacktrace --no-daemon - name: Upload Snapshot - run: ./gradlew -PreleaseMode=branch uploadArchives --no-daemon --no-parallel --stacktrace + run: ./gradlew -PreleaseMode=branch publish --no-daemon --no-parallel --stacktrace env: # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions # ------------------------------------------------------------------------------ From c5883dcb390ebb17a484871038e37078e210052a Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 7 Jul 2021 09:23:29 +0200 Subject: [PATCH 038/348] Update gradle_release.yml Release plugin 0.17.0 uses "publish" --- .github/workflows/gradle_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index d25da22464..81962b6028 100644 --- a/.github/workflows/gradle_release.yml +++ b/.github/workflows/gradle_release.yml @@ -40,7 +40,7 @@ jobs: - name: Upload to Codecov uses: codecov/codecov-action@v1.5.2 - name: Upload release - run: ./gradlew -PreleaseMode=full uploadArchives --no-daemon --no-parallel --stacktrace + run: ./gradlew -PreleaseMode=full publish --no-daemon --no-parallel --stacktrace env: # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions # ------------------------------------------------------------------------------ From 333094355a19a6fb1b9f88d30bb68534504fac3c Mon Sep 17 00:00:00 2001 From: Christos Gkekas Date: Fri, 16 Jul 2021 07:32:35 +0100 Subject: [PATCH 039/348] Removes the purge thread in favor of standard ScheduledThreadPoolExecutor APIs (#7293) The RXSchedulerPurge thread is currently enabled by default and runs every second to call purge() on each executor in the pool. This is causing significant issues for low powered devices (e.g. mobile phones), because it needs to periodically wake up the CPU to perform purging. The RXSchedulerPurge thread could be completely removed in favor of using the standard setRemoveOnCancelPolicy() API on the ScheduledThreadPoolExecutor which became available in Java 7 and offers removal of cancelled tasks at the moment they are cancelled in O(1). --- .../schedulers/SchedulerPoolFactory.java | 99 +------------------ .../rxjava3/schedulers/Schedulers.java | 5 +- .../schedulers/SchedulerPoolFactoryTest.java | 86 ---------------- .../schedulers/ExecutorSchedulerTest.java | 2 +- 4 files changed, 4 insertions(+), 188 deletions(-) diff --git a/src/main/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactory.java b/src/main/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactory.java index 043569334c..515c2f2061 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactory.java +++ b/src/main/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactory.java @@ -31,86 +31,11 @@ private SchedulerPoolFactory() { static final String PURGE_ENABLED_KEY = "rx3.purge-enabled"; - /** - * Indicates the periodic purging of the ScheduledExecutorService is enabled. - */ public static final boolean PURGE_ENABLED; - static final String PURGE_PERIOD_SECONDS_KEY = "rx3.purge-period-seconds"; - - /** - * Indicates the purge period of the ScheduledExecutorServices created by create(). - */ - public static final int PURGE_PERIOD_SECONDS; - - static final AtomicReference PURGE_THREAD = - new AtomicReference<>(); - - // Upcast to the Map interface here to avoid 8.x compatibility issues. - // See http://stackoverflow.com/a/32955708/61158 - static final Map POOLS = - new ConcurrentHashMap<>(); - - /** - * Starts the purge thread if not already started. - */ - public static void start() { - tryStart(PURGE_ENABLED); - } - - static void tryStart(boolean purgeEnabled) { - if (purgeEnabled) { - for (;;) { - ScheduledExecutorService curr = PURGE_THREAD.get(); - if (curr != null) { - return; - } - ScheduledExecutorService next = Executors.newScheduledThreadPool(1, new RxThreadFactory("RxSchedulerPurge")); - if (PURGE_THREAD.compareAndSet(curr, next)) { - - next.scheduleAtFixedRate(new ScheduledTask(), PURGE_PERIOD_SECONDS, PURGE_PERIOD_SECONDS, TimeUnit.SECONDS); - - return; - } else { - next.shutdownNow(); - } - } - } - } - - /** - * Stops the purge thread. - */ - public static void shutdown() { - ScheduledExecutorService exec = PURGE_THREAD.getAndSet(null); - if (exec != null) { - exec.shutdownNow(); - } - POOLS.clear(); - } - static { SystemPropertyAccessor propertyAccessor = new SystemPropertyAccessor(); PURGE_ENABLED = getBooleanProperty(true, PURGE_ENABLED_KEY, true, true, propertyAccessor); - PURGE_PERIOD_SECONDS = getIntProperty(PURGE_ENABLED, PURGE_PERIOD_SECONDS_KEY, 1, 1, propertyAccessor); - - start(); - } - - static int getIntProperty(boolean enabled, String key, int defaultNotFound, int defaultNotEnabled, Function propertyAccessor) { - if (enabled) { - try { - String value = propertyAccessor.apply(key); - if (value == null) { - return defaultNotFound; - } - return Integer.parseInt(value); - } catch (Throwable ex) { - Exceptions.throwIfFatal(ex); - return defaultNotFound; - } - } - return defaultNotEnabled; } static boolean getBooleanProperty(boolean enabled, String key, boolean defaultNotFound, boolean defaultNotEnabled, Function propertyAccessor) { @@ -142,28 +67,8 @@ public String apply(String t) { * @return the ScheduledExecutorService */ public static ScheduledExecutorService create(ThreadFactory factory) { - final ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, factory); - tryPutIntoPool(PURGE_ENABLED, exec); + final ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1, factory); + exec.setRemoveOnCancelPolicy(PURGE_ENABLED); return exec; } - - static void tryPutIntoPool(boolean purgeEnabled, ScheduledExecutorService exec) { - if (purgeEnabled && exec instanceof ScheduledThreadPoolExecutor) { - ScheduledThreadPoolExecutor e = (ScheduledThreadPoolExecutor) exec; - POOLS.put(e, exec); - } - } - - static final class ScheduledTask implements Runnable { - @Override - public void run() { - for (ScheduledThreadPoolExecutor e : new ArrayList<>(POOLS.keySet())) { - if (e.isShutdown()) { - POOLS.remove(e); - } else { - e.purge(); - } - } - } - } } diff --git a/src/main/java/io/reactivex/rxjava3/schedulers/Schedulers.java b/src/main/java/io/reactivex/rxjava3/schedulers/Schedulers.java index 0c0ecbdbe5..f5dbe6ce7c 100644 --- a/src/main/java/io/reactivex/rxjava3/schedulers/Schedulers.java +++ b/src/main/java/io/reactivex/rxjava3/schedulers/Schedulers.java @@ -38,8 +38,7 @@ *
  • {@code rx3.computation-priority} (int): sets the thread priority of the {@link #computation()} {@code Scheduler}, default is {@link Thread#NORM_PRIORITY}
  • *
  • {@code rx3.newthread-priority} (int): sets the thread priority of the {@link #newThread()} {@code Scheduler}, default is {@link Thread#NORM_PRIORITY}
  • *
  • {@code rx3.single-priority} (int): sets the thread priority of the {@link #single()} {@code Scheduler}, default is {@link Thread#NORM_PRIORITY}
  • - *
  • {@code rx3.purge-enabled} (boolean): enables periodic purging of all {@code Scheduler}'s backing thread pools, default is {@code false}
  • - *
  • {@code rx3.purge-period-seconds} (int): specifies the periodic purge interval of all {@code Scheduler}'s backing thread pools, default is 1 second
  • + *
  • {@code rx3.purge-enabled} (boolean): enables purging of all {@code Scheduler}'s backing thread pools, default is {@code true}
  • *
  • {@code rx3.scheduler.use-nanotime} (boolean): {@code true} instructs {@code Scheduler} to use {@link System#nanoTime()} for {@link Scheduler#now(TimeUnit)}, * instead of default {@link System#currentTimeMillis()} ({@code false})
  • * @@ -556,7 +555,6 @@ public static void shutdown() { newThread().shutdown(); single().shutdown(); trampoline().shutdown(); - SchedulerPoolFactory.shutdown(); } /** @@ -569,7 +567,6 @@ public static void start() { newThread().start(); single().start(); trampoline().start(); - SchedulerPoolFactory.start(); } static final class IOTask implements Supplier { diff --git a/src/test/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactoryTest.java b/src/test/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactoryTest.java index dd5667ffbb..5d93dabc09 100644 --- a/src/test/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactoryTest.java +++ b/src/test/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactoryTest.java @@ -30,50 +30,6 @@ public void utilityClass() { TestHelper.checkUtilityClass(SchedulerPoolFactory.class); } - @Test - public void multiStartStop() { - SchedulerPoolFactory.shutdown(); - - SchedulerPoolFactory.shutdown(); - - SchedulerPoolFactory.tryStart(false); - - assertNull(SchedulerPoolFactory.PURGE_THREAD.get()); - - SchedulerPoolFactory.start(); - - // restart schedulers - Schedulers.shutdown(); - - Schedulers.start(); - } - - @Test - public void startRace() throws InterruptedException { - try { - for (int i = 0; i < TestHelper.RACE_DEFAULT_LOOPS; i++) { - SchedulerPoolFactory.shutdown(); - - Runnable r1 = new Runnable() { - @Override - public void run() { - SchedulerPoolFactory.start(); - } - }; - - TestHelper.race(r1, r1); - } - - } finally { - // restart schedulers - Schedulers.shutdown(); - - Thread.sleep(200); - - Schedulers.start(); - } - } - @Test public void boolPropertiesDisabledReturnsDefaultDisabled() throws Throwable { assertTrue(SchedulerPoolFactory.getBooleanProperty(false, "key", false, true, failingPropertiesAccessor)); @@ -98,30 +54,6 @@ public void boolPropertiesReturnsValue() throws Throwable { assertFalse(SchedulerPoolFactory.getBooleanProperty(true, "false", false, true, Functions.identity())); } - @Test - public void intPropertiesDisabledReturnsDefaultDisabled() throws Throwable { - assertEquals(-1, SchedulerPoolFactory.getIntProperty(false, "key", 0, -1, failingPropertiesAccessor)); - assertEquals(-1, SchedulerPoolFactory.getIntProperty(false, "key", 1, -1, failingPropertiesAccessor)); - } - - @Test - public void intPropertiesEnabledMissingReturnsDefaultMissing() throws Throwable { - assertEquals(-1, SchedulerPoolFactory.getIntProperty(true, "key", -1, 0, missingPropertiesAccessor)); - assertEquals(-1, SchedulerPoolFactory.getIntProperty(true, "key", -1, 1, missingPropertiesAccessor)); - } - - @Test - public void intPropertiesFailureReturnsDefaultMissing() throws Throwable { - assertEquals(-1, SchedulerPoolFactory.getIntProperty(true, "key", -1, 0, failingPropertiesAccessor)); - assertEquals(-1, SchedulerPoolFactory.getIntProperty(true, "key", -1, 1, failingPropertiesAccessor)); - } - - @Test - public void intPropertiesReturnsValue() throws Throwable { - assertEquals(1, SchedulerPoolFactory.getIntProperty(true, "1", 0, 4, Functions.identity())); - assertEquals(2, SchedulerPoolFactory.getIntProperty(true, "2", 3, 5, Functions.identity())); - } - static final Function failingPropertiesAccessor = new Function() { @Override public String apply(String v) throws Throwable { @@ -135,22 +67,4 @@ public String apply(String v) throws Throwable { return null; } }; - - @Test - public void putIntoPoolNoPurge() { - int s = SchedulerPoolFactory.POOLS.size(); - - SchedulerPoolFactory.tryPutIntoPool(false, null); - - assertEquals(s, SchedulerPoolFactory.POOLS.size()); - } - - @Test - public void putIntoPoolNonThreadPool() { - int s = SchedulerPoolFactory.POOLS.size(); - - SchedulerPoolFactory.tryPutIntoPool(true, null); - - assertEquals(s, SchedulerPoolFactory.POOLS.size()); - } } diff --git a/src/test/java/io/reactivex/rxjava3/schedulers/ExecutorSchedulerTest.java b/src/test/java/io/reactivex/rxjava3/schedulers/ExecutorSchedulerTest.java index c4ba94189c..bb3e759884 100644 --- a/src/test/java/io/reactivex/rxjava3/schedulers/ExecutorSchedulerTest.java +++ b/src/test/java/io/reactivex/rxjava3/schedulers/ExecutorSchedulerTest.java @@ -93,7 +93,7 @@ public void run() { System.out.println("Wait before second GC"); System.out.println("JDK 6 purge is N log N because it removes and shifts one by one"); - int t = (int)(n * Math.log(n) / 100) + SchedulerPoolFactory.PURGE_PERIOD_SECONDS * 1000; + int t = (int)(n * Math.log(n) / 100) + 1000; int sleepStep = 100; while (t > 0) { System.out.printf(" >> Waiting for purge: %.2f s remaining%n", t / 1000d); From a9e0a8ab68ef9e385e4a639bd70769ca42e6f21a Mon Sep 17 00:00:00 2001 From: David Karnok Date: Sat, 17 Jul 2021 09:13:09 +0200 Subject: [PATCH 040/348] 3.x: API promotions for 3.1.0 (#7296) --- src/main/java/io/reactivex/rxjava3/core/Flowable.java | 8 ++++---- .../internal/schedulers/SchedulerPoolFactory.java | 2 -- .../java/io/reactivex/rxjava3/plugins/RxJavaPlugins.java | 8 ++++---- .../io/reactivex/rxjava3/schedulers/TestScheduler.java | 9 ++++----- .../internal/schedulers/SchedulerPoolFactoryTest.java | 1 - 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/main/java/io/reactivex/rxjava3/core/Flowable.java b/src/main/java/io/reactivex/rxjava3/core/Flowable.java index a9f7b0a3b6..804a057533 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Flowable.java +++ b/src/main/java/io/reactivex/rxjava3/core/Flowable.java @@ -12725,15 +12725,15 @@ public final Flowable onBackpressureLatest() { *
    Scheduler:
    *
    {@code onBackpressureReduce} does not operate by default on a particular {@link Scheduler}.
    *
    + *

    History: 3.0.9 - experimental * @param reducer the bi-function to call when there is more than one non-emitted value to downstream, * the first argument of the bi-function is previous item and the second one is currently * emitting from upstream * @return the new {@code Flowable} instance * @throws NullPointerException if {@code reducer} is {@code null} - * @since 3.0.9 - experimental + * @since 3.1.0 * @see #onBackpressureReduce(Supplier, BiFunction) */ - @Experimental @CheckReturnValue @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) @@ -12764,6 +12764,7 @@ public final Flowable onBackpressureReduce(@NonNull BiFunction reduc *

    Scheduler:
    *
    {@code onBackpressureReduce} does not operate by default on a particular {@link Scheduler}.
    *
    + *

    History: 3.0.9 - experimental * @param the aggregate type emitted when the downstream requests more items * @param supplier the factory to call to create new item of type R to pass it as the first argument to {@code reducer}. * It is called when previous returned value by {@code reducer} already sent to @@ -12774,9 +12775,8 @@ public final Flowable onBackpressureReduce(@NonNull BiFunction reduc * @return the new {@code Flowable} instance * @throws NullPointerException if {@code supplier} or {@code reducer} is {@code null} * @see #onBackpressureReduce(BiFunction) - * @since 3.0.9 - experimental + * @since 3.1.0 */ - @Experimental @CheckReturnValue @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) diff --git a/src/main/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactory.java b/src/main/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactory.java index 515c2f2061..44a824a168 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactory.java +++ b/src/main/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactory.java @@ -13,9 +13,7 @@ package io.reactivex.rxjava3.internal.schedulers; -import java.util.*; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicReference; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Function; diff --git a/src/main/java/io/reactivex/rxjava3/plugins/RxJavaPlugins.java b/src/main/java/io/reactivex/rxjava3/plugins/RxJavaPlugins.java index c5b0797ba3..58cb730bf6 100644 --- a/src/main/java/io/reactivex/rxjava3/plugins/RxJavaPlugins.java +++ b/src/main/java/io/reactivex/rxjava3/plugins/RxJavaPlugins.java @@ -1153,11 +1153,11 @@ public static void setOnParallelAssembly(@Nullable FunctionHistory: 3.0.11 - experimental * @param handler the hook function to set, null allowed - * @since 3.0.11 - experimental + * @since 3.1.0 */ @SuppressWarnings("rawtypes") - @Experimental public static void setOnParallelSubscribe(@Nullable BiFunction handler) { if (lockdown) { throw new IllegalStateException("Plugins can't be changed anymore"); @@ -1167,11 +1167,11 @@ public static void setOnParallelSubscribe(@Nullable BiFunctionHistory: 3.0.11 - experimental * @return the hook function, may be null - * @since 3.0.11 - experimental + * @since 3.1.0 */ @SuppressWarnings("rawtypes") - @Experimental @Nullable public static BiFunction getOnParallelSubscribe() { return onParallelSubscribe; diff --git a/src/main/java/io/reactivex/rxjava3/schedulers/TestScheduler.java b/src/main/java/io/reactivex/rxjava3/schedulers/TestScheduler.java index a9aa3285f5..33aca58a48 100644 --- a/src/main/java/io/reactivex/rxjava3/schedulers/TestScheduler.java +++ b/src/main/java/io/reactivex/rxjava3/schedulers/TestScheduler.java @@ -52,12 +52,12 @@ public TestScheduler() { /** * Creates a new TestScheduler with the option to use the * {@link RxJavaPlugins#onSchedule(Runnable)} hook when scheduling tasks. + *

    History: 3.0.10 - experimental * @param useOnScheduleHook if {@code true}, the tasks submitted to this * TestScheduler is wrapped via the * {@link RxJavaPlugins#onSchedule(Runnable)} hook - * @since 3.0.10 - experimental + * @since 3.1.0 */ - @Experimental public TestScheduler(boolean useOnScheduleHook) { this.useOnScheduleHook = useOnScheduleHook; } @@ -78,7 +78,7 @@ public TestScheduler(long delayTime, TimeUnit unit) { * Creates a new TestScheduler with the specified initial virtual time * and with the option to use the * {@link RxJavaPlugins#onSchedule(Runnable)} hook when scheduling tasks. - * + *

    History: 3.0.10 - experimental * @param delayTime * the point in time to move the Scheduler's clock to * @param unit @@ -86,9 +86,8 @@ public TestScheduler(long delayTime, TimeUnit unit) { * @param useOnScheduleHook if {@code true}, the tasks submitted to this * TestScheduler is wrapped via the * {@link RxJavaPlugins#onSchedule(Runnable)} hook - * @since 3.0.10 - experimental + * @since 3.1.0 */ - @Experimental public TestScheduler(long delayTime, TimeUnit unit, boolean useOnScheduleHook) { time = unit.toNanos(delayTime); this.useOnScheduleHook = useOnScheduleHook; diff --git a/src/test/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactoryTest.java b/src/test/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactoryTest.java index 5d93dabc09..12afa708c4 100644 --- a/src/test/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactoryTest.java +++ b/src/test/java/io/reactivex/rxjava3/internal/schedulers/SchedulerPoolFactoryTest.java @@ -20,7 +20,6 @@ import io.reactivex.rxjava3.core.RxJavaTest; import io.reactivex.rxjava3.functions.Function; import io.reactivex.rxjava3.internal.functions.Functions; -import io.reactivex.rxjava3.schedulers.Schedulers; import io.reactivex.rxjava3.testsupport.TestHelper; public class SchedulerPoolFactoryTest extends RxJavaTest { From 66fd701417563fd21c24c177447c332191931dc4 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Sat, 17 Jul 2021 12:53:55 +0200 Subject: [PATCH 041/348] 3.x: Add subscribe with disposable container (#7298) --- .../reactivex/rxjava3/core/Completable.java | 45 ++- .../io/reactivex/rxjava3/core/Flowable.java | 53 ++- .../java/io/reactivex/rxjava3/core/Maybe.java | 49 ++- .../io/reactivex/rxjava3/core/Observable.java | 49 ++- .../io/reactivex/rxjava3/core/Single.java | 48 ++- .../AbstractDisposableAutoRelease.java | 125 +++++++ .../DisposableAutoReleaseMultiObserver.java | 78 +++++ .../DisposableAutoReleaseObserver.java | 76 ++++ .../DisposableAutoReleaseSubscriber.java | 151 ++++++++ .../observers/CompletableConsumersTest.java | 221 ++++++++++++ .../observers/MaybeConsumersTest.java | 273 +++++++++++++++ .../observers/ObservableConsumersTest.java | 324 +++++++++++++++++ .../observers/SingleConsumersTest.java | 192 ++++++++++ .../subscribers/FlowableConsumersTest.java | 328 ++++++++++++++++++ .../validators/BaseTypeAnnotations.java | 4 +- .../validators/JavadocForAnnotations.java | 2 +- .../rxjava3/validators/JavadocWording.java | 1 + .../ParamValidationCheckerTest.java | 4 +- 18 files changed, 2009 insertions(+), 14 deletions(-) create mode 100644 src/main/java/io/reactivex/rxjava3/internal/observers/AbstractDisposableAutoRelease.java create mode 100644 src/main/java/io/reactivex/rxjava3/internal/observers/DisposableAutoReleaseMultiObserver.java create mode 100644 src/main/java/io/reactivex/rxjava3/internal/observers/DisposableAutoReleaseObserver.java create mode 100644 src/main/java/io/reactivex/rxjava3/internal/subscribers/DisposableAutoReleaseSubscriber.java create mode 100644 src/test/java/io/reactivex/rxjava3/internal/observers/CompletableConsumersTest.java create mode 100644 src/test/java/io/reactivex/rxjava3/internal/observers/MaybeConsumersTest.java create mode 100644 src/test/java/io/reactivex/rxjava3/internal/observers/ObservableConsumersTest.java create mode 100644 src/test/java/io/reactivex/rxjava3/internal/observers/SingleConsumersTest.java create mode 100644 src/test/java/io/reactivex/rxjava3/internal/subscribers/FlowableConsumersTest.java diff --git a/src/main/java/io/reactivex/rxjava3/core/Completable.java b/src/main/java/io/reactivex/rxjava3/core/Completable.java index 05b3f8b240..96eb10c447 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Completable.java +++ b/src/main/java/io/reactivex/rxjava3/core/Completable.java @@ -19,7 +19,7 @@ import org.reactivestreams.*; import io.reactivex.rxjava3.annotations.*; -import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.disposables.*; import io.reactivex.rxjava3.exceptions.*; import io.reactivex.rxjava3.functions.*; import io.reactivex.rxjava3.internal.functions.*; @@ -29,7 +29,7 @@ import io.reactivex.rxjava3.internal.operators.completable.*; import io.reactivex.rxjava3.internal.operators.maybe.*; import io.reactivex.rxjava3.internal.operators.mixed.*; -import io.reactivex.rxjava3.internal.operators.single.*; +import io.reactivex.rxjava3.internal.operators.single.SingleDelayWithCompletable; import io.reactivex.rxjava3.observers.TestObserver; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import io.reactivex.rxjava3.schedulers.Schedulers; @@ -2836,6 +2836,7 @@ public final Completable hide() { *

    {@code subscribe} does not operate by default on a particular {@link Scheduler}.
    *
    * @return the new {@code Disposable} that can be used for disposing the subscription at any time + * @see #subscribe(Action, Consumer, DisposableContainer) */ @SchedulerSupport(SchedulerSupport.NONE) @NonNull @@ -2921,6 +2922,7 @@ public final void subscribe(@NonNull CompletableObserver observer) { * @param onError the {@link Consumer} that is called if this {@code Completable} emits an error * @return the new {@link Disposable} that can be used for disposing the subscription at any time * @throws NullPointerException if {@code onComplete} or {@code onError} is {@code null} + * @see #subscribe(Action, Consumer, DisposableContainer) */ @CheckReturnValue @NonNull @@ -2934,6 +2936,44 @@ public final Disposable subscribe(@NonNull Action onComplete, @NonNull Consumer< return observer; } + /** + * Wraps the given onXXX callbacks into a {@link Disposable} {@link CompletableObserver}, + * adds it to the given {@link DisposableContainer} and ensures, that if the upstream + * terminates or this particular {@code Disposable} is disposed, the {@code CompletableObserver} is removed + * from the given composite. + *

    + * The {@code CompletableObserver} will be removed after the callback for the terminal event has been invoked. + *

    + *
    Scheduler:
    + *
    {@code subscribe} does not operate by default on a particular {@link Scheduler}.
    + *
    + * @param onError the callback for an upstream error + * @param onComplete the callback for an upstream completion + * @param container the {@code DisposableContainer} (such as {@link CompositeDisposable}) to add and remove the + * created {@code Disposable} {@code CompletableObserver} + * @return the {@code Disposable} that allows disposing the particular subscription. + * @throws NullPointerException + * if {@code onComplete}, {@code onError} + * or {@code container} is {@code null} + * @since 3.1.0 + */ + @SchedulerSupport(SchedulerSupport.NONE) + @NonNull + public final Disposable subscribe( + @NonNull Action onComplete, + @NonNull Consumer onError, + @NonNull DisposableContainer container) { + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(container, "container is null"); + + DisposableAutoReleaseMultiObserver observer = new DisposableAutoReleaseMultiObserver<>( + container, Functions.emptyConsumer(), onError, onComplete); + container.add(observer); + subscribe(observer); + return observer; + } + /** * Subscribes to this {@code Completable} and calls the given {@link Action} when this {@code Completable} * completes normally. @@ -2950,6 +2990,7 @@ public final Disposable subscribe(@NonNull Action onComplete, @NonNull Consumer< * @param onComplete the {@code Action} called when this {@code Completable} completes normally * @return the new {@link Disposable} that can be used for disposing the subscription at any time * @throws NullPointerException if {@code onComplete} is {@code null} + * @see #subscribe(Action, Consumer, DisposableContainer) */ @CheckReturnValue @NonNull diff --git a/src/main/java/io/reactivex/rxjava3/core/Flowable.java b/src/main/java/io/reactivex/rxjava3/core/Flowable.java index 804a057533..d22d8dc4dc 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Flowable.java +++ b/src/main/java/io/reactivex/rxjava3/core/Flowable.java @@ -20,7 +20,7 @@ import org.reactivestreams.*; import io.reactivex.rxjava3.annotations.*; -import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.disposables.*; import io.reactivex.rxjava3.exceptions.*; import io.reactivex.rxjava3.flowables.*; import io.reactivex.rxjava3.functions.*; @@ -15699,6 +15699,7 @@ public final Flowable startWithArray(@NonNull T... items) { * * @return the new {@link Disposable} instance that allows cancelling the flow * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerSupport.NONE) @@ -15727,6 +15728,7 @@ public final Disposable subscribe() { * @throws NullPointerException * if {@code onNext} is {@code null} * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @CheckReturnValue @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @@ -15753,9 +15755,10 @@ public final Disposable subscribe(@NonNull Consumer onNext) { * the {@code Consumer} you have designed to accept any error notification from the * current {@code Flowable} * @return the new {@link Disposable} instance that allows cancelling the flow - * @see ReactiveX operators documentation: Subscribe * @throws NullPointerException * if {@code onNext} or {@code onError} is {@code null} + * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @CheckReturnValue @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @@ -15788,6 +15791,7 @@ public final Disposable subscribe(@NonNull Consumer onNext, @NonNull * @throws NullPointerException * if {@code onNext}, {@code onError} or {@code onComplete} is {@code null} * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @CheckReturnValue @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @@ -15806,6 +15810,51 @@ public final Disposable subscribe(@NonNull Consumer onNext, @NonNull return ls; } + /** + * Wraps the given onXXX callbacks into a {@link Disposable} {@link Subscriber}, + * adds it to the given {@link DisposableContainer} and ensures, that if the upstream + * terminates or this particular {@code Disposable} is disposed, the {@code Subscriber} is removed + * from the given container. + *

    + * The {@coded Subscriber} will be removed after the callback for the terminal event has been invoked. + *

    + *
    Backpressure:
    + *
    The operator consumes the current {@code Flowable} in an unbounded manner (i.e., no + * backpressure is applied to it).
    + *
    Scheduler:
    + *
    {@code subscribe} does not operate by default on a particular {@link Scheduler}.
    + *
    + * @param onNext the callback for upstream items + * @param onError the callback for an upstream error if any + * @param onComplete the callback for the upstream completion if any + * @param container the {@code DisposableContainer} (such as {@link CompositeDisposable}) to add and remove the + * created {@code Disposable} {@code Subscriber} + * @return the {@code Disposable} that allows disposing the particular subscription. + * @throws NullPointerException + * if {@code onNext}, {@code onError}, + * {@code onComplete} or {@code container} is {@code null} + * @since 3.1.0 + */ + @BackpressureSupport(BackpressureKind.SPECIAL) + @SchedulerSupport(SchedulerSupport.NONE) + @NonNull + public final Disposable subscribe( + @NonNull Consumer onNext, + @NonNull Consumer onError, + @NonNull Action onComplete, + @NonNull DisposableContainer container) { + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(container, "container is null"); + + DisposableAutoReleaseSubscriber subscriber = new DisposableAutoReleaseSubscriber<>( + container, onNext, onError, onComplete); + container.add(subscriber); + subscribe(subscriber); + return subscriber; + } + @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerSupport.NONE) @Override diff --git a/src/main/java/io/reactivex/rxjava3/core/Maybe.java b/src/main/java/io/reactivex/rxjava3/core/Maybe.java index c0b8421fb1..917a9838a4 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Maybe.java +++ b/src/main/java/io/reactivex/rxjava3/core/Maybe.java @@ -20,7 +20,7 @@ import org.reactivestreams.*; import io.reactivex.rxjava3.annotations.*; -import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.disposables.*; import io.reactivex.rxjava3.exceptions.*; import io.reactivex.rxjava3.functions.*; import io.reactivex.rxjava3.internal.functions.*; @@ -5226,6 +5226,7 @@ public final Flowable startWith(@NonNull Publisher other) { * * @return the new {@link Disposable} instance that can be used for disposing the subscription at any time * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @SchedulerSupport(SchedulerSupport.NONE) @NonNull @@ -5250,6 +5251,7 @@ public final Disposable subscribe() { * @throws NullPointerException * if {@code onSuccess} is {@code null} * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @CheckReturnValue @SchedulerSupport(SchedulerSupport.NONE) @@ -5272,10 +5274,11 @@ public final Disposable subscribe(@NonNull Consumer onSuccess) { * the {@code Consumer} you have designed to accept any error notification from the * {@code Maybe} * @return the new {@link Disposable} instance that can be used for disposing the subscription at any time - * @see ReactiveX operators documentation: Subscribe * @throws NullPointerException * if {@code onSuccess} is {@code null}, or * if {@code onError} is {@code null} + * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @CheckReturnValue @SchedulerSupport(SchedulerSupport.NONE) @@ -5305,6 +5308,7 @@ public final Disposable subscribe(@NonNull Consumer onSuccess, @NonNu * if {@code onSuccess}, {@code onError} or * {@code onComplete} is {@code null} * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @CheckReturnValue @NonNull @@ -5317,6 +5321,47 @@ public final Disposable subscribe(@NonNull Consumer onSuccess, @NonNu return subscribeWith(new MaybeCallbackObserver<>(onSuccess, onError, onComplete)); } + /** + * Wraps the given onXXX callbacks into a {@link Disposable} {@link MaybeObserver}, + * adds it to the given {@link DisposableContainer} and ensures, that if the upstream + * terminates or this particular {@code Disposable} is disposed, the {@code MaybeObserver} is removed + * from the given composite. + *

    + * The {@code MaybeObserver} will be removed after the callback for the terminal event has been invoked. + *

    + *
    Scheduler:
    + *
    {@code subscribe} does not operate by default on a particular {@link Scheduler}.
    + *
    + * @param onSuccess the callback for upstream items + * @param onError the callback for an upstream error + * @param onComplete the callback for an upstream completion without any value or error + * @param container the {@code DisposableContainer} (such as {@link CompositeDisposable}) to add and remove the + * created {@code Disposable} {@code MaybeObserver} + * @return the {@code Disposable} that allows disposing the particular subscription. + * @throws NullPointerException + * if {@code onSuccess}, {@code onError}, + * {@code onComplete} or {@code container} is {@code null} + * @since 3.1.0 + */ + @SchedulerSupport(SchedulerSupport.NONE) + @NonNull + public final Disposable subscribe( + @NonNull Consumer onSuccess, + @NonNull Consumer onError, + @NonNull Action onComplete, + @NonNull DisposableContainer container) { + Objects.requireNonNull(onSuccess, "onSuccess is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(container, "container is null"); + + DisposableAutoReleaseMultiObserver observer = new DisposableAutoReleaseMultiObserver<>( + container, onSuccess, onError, onComplete); + container.add(observer); + subscribe(observer); + return observer; + } + @SchedulerSupport(SchedulerSupport.NONE) @Override public final void subscribe(@NonNull MaybeObserver observer) { diff --git a/src/main/java/io/reactivex/rxjava3/core/Observable.java b/src/main/java/io/reactivex/rxjava3/core/Observable.java index 27d46ad8c5..18534eecc7 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Observable.java +++ b/src/main/java/io/reactivex/rxjava3/core/Observable.java @@ -20,7 +20,7 @@ import org.reactivestreams.Publisher; import io.reactivex.rxjava3.annotations.*; -import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.disposables.*; import io.reactivex.rxjava3.exceptions.*; import io.reactivex.rxjava3.functions.*; import io.reactivex.rxjava3.internal.functions.*; @@ -13025,6 +13025,7 @@ public final Observable startWithArray(@NonNull T... items) { * * @return the new {@link Disposable} instance that can be used to dispose the subscription at any time * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @SchedulerSupport(SchedulerSupport.NONE) @NonNull @@ -13049,6 +13050,7 @@ public final Disposable subscribe() { * @throws NullPointerException * if {@code onNext} is {@code null} * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @CheckReturnValue @SchedulerSupport(SchedulerSupport.NONE) @@ -13071,9 +13073,10 @@ public final Disposable subscribe(@NonNull Consumer onNext) { * the {@code Consumer} you have designed to accept any error notification from the current * {@code Observable} * @return the new {@link Disposable} instance that can be used to dispose the subscription at any time - * @see ReactiveX operators documentation: Subscribe * @throws NullPointerException * if {@code onNext} or {@code onError} is {@code null} + * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @CheckReturnValue @SchedulerSupport(SchedulerSupport.NONE) @@ -13102,6 +13105,7 @@ public final Disposable subscribe(@NonNull Consumer onNext, @NonNull * @throws NullPointerException * if {@code onNext}, {@code onError} or {@code onComplete} is {@code null} * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, Action, DisposableContainer) */ @CheckReturnValue @SchedulerSupport(SchedulerSupport.NONE) @@ -13119,6 +13123,47 @@ public final Disposable subscribe(@NonNull Consumer onNext, @NonNull return ls; } + /** + * Wraps the given onXXX callbacks into a {@link Disposable} {@link Observer}, + * adds it to the given {@code DisposableContainer} and ensures, that if the upstream + * terminates or this particular {@code Disposable} is disposed, the {@code Observer} is removed + * from the given container. + *

    + * The {@code Observer} will be removed after the callback for the terminal event has been invoked. + *

    + *
    Scheduler:
    + *
    {@code subscribe} does not operate by default on a particular {@link Scheduler}.
    + *
    + * @param onNext the callback for upstream items + * @param onError the callback for an upstream error if any + * @param onComplete the callback for the upstream completion if any + * @param container the {@code DisposableContainer} (such as {@link CompositeDisposable}) to add and remove the + * created {@code Disposable} {@code Observer} + * @return the {@code Disposable} that allows disposing the particular subscription. + * @throws NullPointerException + * if {@code onNext}, {@code onError}, + * {@code onComplete} or {@code container} is {@code null} + * @since 3.1.0 + */ + @SchedulerSupport(SchedulerSupport.NONE) + @NonNull + public final Disposable subscribe( + @NonNull Consumer onNext, + @NonNull Consumer onError, + @NonNull Action onComplete, + @NonNull DisposableContainer container) { + Objects.requireNonNull(onNext, "onNext is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(onComplete, "onComplete is null"); + Objects.requireNonNull(container, "container is null"); + + DisposableAutoReleaseObserver observer = new DisposableAutoReleaseObserver<>( + container, onNext, onError, onComplete); + container.add(observer); + subscribe(observer); + return observer; + } + @SchedulerSupport(SchedulerSupport.NONE) @Override public final void subscribe(@NonNull Observer observer) { diff --git a/src/main/java/io/reactivex/rxjava3/core/Single.java b/src/main/java/io/reactivex/rxjava3/core/Single.java index dbe3694913..66e1ffd3d5 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Single.java +++ b/src/main/java/io/reactivex/rxjava3/core/Single.java @@ -20,7 +20,7 @@ import org.reactivestreams.*; import io.reactivex.rxjava3.annotations.*; -import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.disposables.*; import io.reactivex.rxjava3.exceptions.*; import io.reactivex.rxjava3.functions.*; import io.reactivex.rxjava3.internal.functions.*; @@ -4705,6 +4705,7 @@ public final Flowable startWith(@NonNull Publisher other) { * * @return the new {@link Disposable} instance that can be used for disposing the subscription at any time * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, DisposableContainer) */ @SchedulerSupport(SchedulerSupport.NONE) @NonNull @@ -4726,9 +4727,10 @@ public final Disposable subscribe() { * the callback that receives either the success value or the failure {@link Throwable} * (whichever is not {@code null}) * @return the new {@link Disposable} instance that can be used for disposing the subscription at any time - * @see ReactiveX operators documentation: Subscribe * @throws NullPointerException * if {@code onCallback} is {@code null} + * @see #subscribe(Consumer, Consumer, DisposableContainer) + * @see ReactiveX operators documentation: Subscribe */ @CheckReturnValue @NonNull @@ -4760,6 +4762,7 @@ public final Disposable subscribe(@NonNull BiConsumerReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, DisposableContainer) */ @CheckReturnValue @SchedulerSupport(SchedulerSupport.NONE) @@ -4784,9 +4787,10 @@ public final Disposable subscribe(@NonNull Consumer onSuccess) { * the {@code Consumer} you have designed to accept any error notification from the * {@code Single} * @return the new {@link Disposable} instance that can be used for disposing the subscription at any time - * @see ReactiveX operators documentation: Subscribe * @throws NullPointerException * if {@code onSuccess} or {@code onError} is {@code null} + * @see ReactiveX operators documentation: Subscribe + * @see #subscribe(Consumer, Consumer, DisposableContainer) */ @CheckReturnValue @NonNull @@ -4800,6 +4804,44 @@ public final Disposable subscribe(@NonNull Consumer onSuccess, @NonNu return observer; } + /** + * Wraps the given onXXX callbacks into a {@link Disposable} {@link SingleObserver}, + * adds it to the given {@link DisposableContainer} and ensures, that if the upstream + * terminates or this particular {@code Disposable} is disposed, the {@code SingleObserver} is removed + * from the given container. + *

    + * The {@code SingleObserver} will be removed after the callback for the terminal event has been invoked. + *

    + *
    Scheduler:
    + *
    {@code subscribe} does not operate by default on a particular {@link Scheduler}.
    + *
    + * @param onSuccess the callback for upstream items + * @param onError the callback for an upstream error if any + * @param container the {@code DisposableContainer} (such as {@link CompositeDisposable}) to add and remove the + * created {@code Disposable} {@code SingleObserver} + * @return the {@code Disposable} that allows disposing the particular subscription. + * @throws NullPointerException + * if {@code onSuccess}, {@code onError} + * or {@code container} is {@code null} + * @since 3.1.0 + */ + @SchedulerSupport(SchedulerSupport.NONE) + @NonNull + public final Disposable subscribe( + @NonNull Consumer onSuccess, + @NonNull Consumer onError, + @NonNull DisposableContainer container) { + Objects.requireNonNull(onSuccess, "onSuccess is null"); + Objects.requireNonNull(onError, "onError is null"); + Objects.requireNonNull(container, "container is null"); + + DisposableAutoReleaseMultiObserver observer = new DisposableAutoReleaseMultiObserver<>( + container, onSuccess, onError, Functions.EMPTY_ACTION); + container.add(observer); + subscribe(observer); + return observer; + } + @SchedulerSupport(SchedulerSupport.NONE) @Override public final void subscribe(@NonNull SingleObserver observer) { diff --git a/src/main/java/io/reactivex/rxjava3/internal/observers/AbstractDisposableAutoRelease.java b/src/main/java/io/reactivex/rxjava3/internal/observers/AbstractDisposableAutoRelease.java new file mode 100644 index 0000000000..e5d89a4502 --- /dev/null +++ b/src/main/java/io/reactivex/rxjava3/internal/observers/AbstractDisposableAutoRelease.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016-present, RxJava Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See + * the License for the specific language governing permissions and limitations under the License. + */ + +/* + * Copyright 2016-2019 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.reactivex.rxjava3.internal.observers; + +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.rxjava3.disposables.*; +import io.reactivex.rxjava3.exceptions.*; +import io.reactivex.rxjava3.functions.*; +import io.reactivex.rxjava3.internal.disposables.DisposableHelper; +import io.reactivex.rxjava3.internal.functions.Functions; +import io.reactivex.rxjava3.observers.LambdaConsumerIntrospection; +import io.reactivex.rxjava3.plugins.RxJavaPlugins; + +/** + * Wraps lambda callbacks and when the upstream terminates or the observer gets disposed, + * removes itself from a {@link io.reactivex.rxjava3.disposables.CompositeDisposable}. + *

    History: 0.18.0 @ RxJavaExtensions + * @since 3.1.0 + */ +abstract class AbstractDisposableAutoRelease +extends AtomicReference +implements Disposable, LambdaConsumerIntrospection { + + private static final long serialVersionUID = 8924480688481408726L; + + final AtomicReference composite; + + final Consumer onError; + + final Action onComplete; + + AbstractDisposableAutoRelease( + DisposableContainer composite, + Consumer onError, + Action onComplete + ) { + this.onError = onError; + this.onComplete = onComplete; + this.composite = new AtomicReference<>(composite); + } + + public final void onError(Throwable t) { + if (get() != DisposableHelper.DISPOSED) { + lazySet(DisposableHelper.DISPOSED); + try { + onError.accept(t); + } catch (Throwable e) { + Exceptions.throwIfFatal(e); + RxJavaPlugins.onError(new CompositeException(t, e)); + } + } else { + RxJavaPlugins.onError(t); + } + removeSelf(); + } + + public final void onComplete() { + if (get() != DisposableHelper.DISPOSED) { + lazySet(DisposableHelper.DISPOSED); + try { + onComplete.run(); + } catch (Throwable e) { + Exceptions.throwIfFatal(e); + RxJavaPlugins.onError(e); + } + } + removeSelf(); + } + + @Override + public final void dispose() { + DisposableHelper.dispose(this); + removeSelf(); + } + + final void removeSelf() { + DisposableContainer c = composite.getAndSet(null); + if (c != null) { + c.delete(this); + } + } + + @Override + public final boolean isDisposed() { + return DisposableHelper.isDisposed(get()); + } + + public final void onSubscribe(Disposable d) { + DisposableHelper.setOnce(this, d); + } + + @Override + public final boolean hasCustomOnError() { + return onError != Functions.ON_ERROR_MISSING; + } + +} diff --git a/src/main/java/io/reactivex/rxjava3/internal/observers/DisposableAutoReleaseMultiObserver.java b/src/main/java/io/reactivex/rxjava3/internal/observers/DisposableAutoReleaseMultiObserver.java new file mode 100644 index 0000000000..4779ff5723 --- /dev/null +++ b/src/main/java/io/reactivex/rxjava3/internal/observers/DisposableAutoReleaseMultiObserver.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016-present, RxJava Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See + * the License for the specific language governing permissions and limitations under the License. + */ + +/* + * Copyright 2016-2019 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.reactivex.rxjava3.internal.observers; + +import io.reactivex.rxjava3.core.*; +import io.reactivex.rxjava3.disposables.DisposableContainer; +import io.reactivex.rxjava3.exceptions.Exceptions; +import io.reactivex.rxjava3.functions.*; +import io.reactivex.rxjava3.internal.disposables.DisposableHelper; +import io.reactivex.rxjava3.plugins.RxJavaPlugins; + +/** + * Wraps lambda callbacks and when the upstream terminates or this (Single | Maybe | Completable) + * observer gets disposed, removes itself from a {@link io.reactivex.rxjava3.disposables.CompositeDisposable}. + *

    History: 0.18.0 @ RxJavaExtensions + * @param the element type consumed + * @since 3.1.0 + */ +public final class DisposableAutoReleaseMultiObserver +extends AbstractDisposableAutoRelease +implements SingleObserver, MaybeObserver, CompletableObserver { + + private static final long serialVersionUID = 8924480688481408726L; + + final Consumer onSuccess; + + public DisposableAutoReleaseMultiObserver( + DisposableContainer composite, + Consumer onSuccess, + Consumer onError, + Action onComplete + ) { + super(composite, onError, onComplete); + this.onSuccess = onSuccess; + } + + @Override + public void onSuccess(T t) { + if (get() != DisposableHelper.DISPOSED) { + lazySet(DisposableHelper.DISPOSED); + try { + onSuccess.accept(t); + } catch (Throwable e) { + Exceptions.throwIfFatal(e); + RxJavaPlugins.onError(e); + } + } + removeSelf(); + } + +} diff --git a/src/main/java/io/reactivex/rxjava3/internal/observers/DisposableAutoReleaseObserver.java b/src/main/java/io/reactivex/rxjava3/internal/observers/DisposableAutoReleaseObserver.java new file mode 100644 index 0000000000..89435c96ed --- /dev/null +++ b/src/main/java/io/reactivex/rxjava3/internal/observers/DisposableAutoReleaseObserver.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016-present, RxJava Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See + * the License for the specific language governing permissions and limitations under the License. + */ + +/* + * Copyright 2016-2019 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.reactivex.rxjava3.internal.observers; + +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.DisposableContainer; +import io.reactivex.rxjava3.exceptions.Exceptions; +import io.reactivex.rxjava3.functions.*; +import io.reactivex.rxjava3.internal.disposables.DisposableHelper; + +/** + * Wraps lambda callbacks and when the upstream terminates or this observer gets disposed, + * removes itself from a {@link io.reactivex.rxjava3.disposables.CompositeDisposable}. + *

    History: 0.18.0 @ RxJavaExtensions + * @param the element type consumed + * @since 3.1.0 + */ +public final class DisposableAutoReleaseObserver +extends AbstractDisposableAutoRelease +implements Observer { + + private static final long serialVersionUID = 8924480688481408726L; + + final Consumer onNext; + + public DisposableAutoReleaseObserver( + DisposableContainer composite, + Consumer onNext, + Consumer onError, + Action onComplete + ) { + super(composite, onError, onComplete); + this.onNext = onNext; + } + + @Override + public void onNext(T t) { + if (get() != DisposableHelper.DISPOSED) { + try { + onNext.accept(t); + } catch (Throwable e) { + Exceptions.throwIfFatal(e); + get().dispose(); + onError(e); + } + } + } + +} diff --git a/src/main/java/io/reactivex/rxjava3/internal/subscribers/DisposableAutoReleaseSubscriber.java b/src/main/java/io/reactivex/rxjava3/internal/subscribers/DisposableAutoReleaseSubscriber.java new file mode 100644 index 0000000000..3b9d2d99b3 --- /dev/null +++ b/src/main/java/io/reactivex/rxjava3/internal/subscribers/DisposableAutoReleaseSubscriber.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2016-present, RxJava Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See + * the License for the specific language governing permissions and limitations under the License. + */ + +/* + * Copyright 2016-2019 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.reactivex.rxjava3.internal.subscribers; + +import java.util.concurrent.atomic.AtomicReference; + +import org.reactivestreams.Subscription; + +import io.reactivex.rxjava3.core.FlowableSubscriber; +import io.reactivex.rxjava3.disposables.*; +import io.reactivex.rxjava3.exceptions.*; +import io.reactivex.rxjava3.functions.*; +import io.reactivex.rxjava3.internal.functions.Functions; +import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; +import io.reactivex.rxjava3.observers.LambdaConsumerIntrospection; +import io.reactivex.rxjava3.plugins.RxJavaPlugins; + +/** + * Wraps lambda callbacks and when the upstream terminates or this subscriber gets disposed, + * removes itself from a {@link io.reactivex.rxjava3.disposables.CompositeDisposable}. + *

    History: 0.18.0 @ RxJavaExtensions + * @param the element type consumed + * @since 3.1.0 + */ +public final class DisposableAutoReleaseSubscriber +extends AtomicReference +implements FlowableSubscriber, Disposable, LambdaConsumerIntrospection { + + private static final long serialVersionUID = 8924480688481408726L; + + final AtomicReference composite; + + final Consumer onNext; + + final Consumer onError; + + final Action onComplete; + + public DisposableAutoReleaseSubscriber( + DisposableContainer composite, + Consumer onNext, + Consumer onError, + Action onComplete + ) { + this.onNext = onNext; + this.onError = onError; + this.onComplete = onComplete; + this.composite = new AtomicReference<>(composite); + } + + @Override + public void onNext(T t) { + if (get() != SubscriptionHelper.CANCELLED) { + try { + onNext.accept(t); + } catch (Throwable e) { + Exceptions.throwIfFatal(e); + get().cancel(); + onError(e); + } + } + } + + @Override + public void onError(Throwable t) { + if (get() != SubscriptionHelper.CANCELLED) { + lazySet(SubscriptionHelper.CANCELLED); + try { + onError.accept(t); + } catch (Throwable e) { + Exceptions.throwIfFatal(e); + RxJavaPlugins.onError(new CompositeException(t, e)); + } + } else { + RxJavaPlugins.onError(t); + } + removeSelf(); + } + + @Override + public void onComplete() { + if (get() != SubscriptionHelper.CANCELLED) { + lazySet(SubscriptionHelper.CANCELLED); + try { + onComplete.run(); + } catch (Throwable e) { + Exceptions.throwIfFatal(e); + RxJavaPlugins.onError(e); + } + } + removeSelf(); + } + + @Override + public void dispose() { + SubscriptionHelper.cancel(this); + removeSelf(); + } + + void removeSelf() { + DisposableContainer c = composite.getAndSet(null); + if (c != null) { + c.delete(this); + } + } + + @Override + public boolean isDisposed() { + return SubscriptionHelper.CANCELLED == get(); + } + + @Override + public void onSubscribe(Subscription s) { + if (SubscriptionHelper.setOnce(this, s)) { + s.request(Long.MAX_VALUE); + } + } + + @Override + public boolean hasCustomOnError() { + return onError != Functions.ON_ERROR_MISSING; + } + +} diff --git a/src/test/java/io/reactivex/rxjava3/internal/observers/CompletableConsumersTest.java b/src/test/java/io/reactivex/rxjava3/internal/observers/CompletableConsumersTest.java new file mode 100644 index 0000000000..eb17ead3db --- /dev/null +++ b/src/test/java/io/reactivex/rxjava3/internal/observers/CompletableConsumersTest.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2016-present, RxJava Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See + * the License for the specific language governing permissions and limitations under the License. + */ + +/* + * Copyright 2016-2019 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.reactivex.rxjava3.internal.observers; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.*; + +import org.junit.Test; + +import io.reactivex.rxjava3.core.*; +import io.reactivex.rxjava3.disposables.*; +import io.reactivex.rxjava3.exceptions.CompositeException; +import io.reactivex.rxjava3.functions.*; +import io.reactivex.rxjava3.observers.LambdaConsumerIntrospection; +import io.reactivex.rxjava3.plugins.RxJavaPlugins; +import io.reactivex.rxjava3.subjects.CompletableSubject; +import io.reactivex.rxjava3.testsupport.TestHelper; + +public class CompletableConsumersTest implements Consumer, Action { + + final CompositeDisposable composite = new CompositeDisposable(); + + final CompletableSubject processor = CompletableSubject.create(); + + final List events = new ArrayList<>(); + + @Override + public void run() throws Exception { + events.add("OnComplete"); + } + + @Override + public void accept(Object t) throws Exception { + events.add(t); + } + + @Test + public void onErrorNormal() { + + processor.subscribe(this, this, composite); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onComplete(); + + assertEquals(0, composite.size()); + + assertEquals(Arrays.asList("OnComplete"), events); + + } + + @Test + public void onErrorError() { + + Disposable d = processor.subscribe(this, this, composite); + + assertTrue(d.getClass().toString(), ((LambdaConsumerIntrospection)d).hasCustomOnError()); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onError(new IOException()); + + assertTrue(events.toString(), events.get(0) instanceof IOException); + + assertEquals(0, composite.size()); + } + + @Test + public void onCompleteNormal() { + + processor.subscribe(this, this, composite); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onComplete(); + + assertEquals(0, composite.size()); + + assertEquals(Arrays.asList("OnComplete"), events); + + } + + @Test + public void onCompleteError() { + + processor.subscribe(this, this, composite); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onError(new IOException()); + + assertTrue(events.toString(), events.get(0) instanceof IOException); + + assertEquals(0, composite.size()); + } + + @Test + public void onCompleteDispose() { + + Disposable d = processor.subscribe(this, this, composite); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + assertFalse(d.isDisposed()); + + d.dispose(); + d.dispose(); + + assertTrue(d.isDisposed()); + + assertEquals(0, composite.size()); + + assertFalse(processor.hasObservers()); + } + + @Test + public void onErrorCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + processor.subscribe(this, t -> { + throw new IOException(t); + }, composite); + + processor.onError(new IllegalArgumentException()); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertError(errors, 0, CompositeException.class); + List inners = TestHelper.compositeList(errors.get(0)); + TestHelper.assertError(inners, 0, IllegalArgumentException.class); + TestHelper.assertError(inners, 1, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void onCompleteCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + processor.subscribe(new Action() { + @Override + public void run() throws Exception { + throw new IOException(); + } + }, this, composite); + + processor.onComplete(); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void badSource() { + List errors = TestHelper.trackPluginErrors(); + try { + new Completable() { + @Override + protected void subscribeActual( + CompletableObserver observer) { + observer.onSubscribe(Disposable.empty()); + observer.onComplete(); + + observer.onSubscribe(Disposable.empty()); + observer.onComplete(); + observer.onError(new IOException()); + } + }.subscribe(this, this, composite); + + assertEquals(Arrays.asList("OnComplete"), events); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } +} diff --git a/src/test/java/io/reactivex/rxjava3/internal/observers/MaybeConsumersTest.java b/src/test/java/io/reactivex/rxjava3/internal/observers/MaybeConsumersTest.java new file mode 100644 index 0000000000..92b32c000e --- /dev/null +++ b/src/test/java/io/reactivex/rxjava3/internal/observers/MaybeConsumersTest.java @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2016-present, RxJava Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See + * the License for the specific language governing permissions and limitations under the License. + */ + +/* + * Copyright 2016-2019 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.reactivex.rxjava3.internal.observers; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.*; + +import org.junit.Test; + +import io.reactivex.rxjava3.core.*; +import io.reactivex.rxjava3.disposables.*; +import io.reactivex.rxjava3.exceptions.CompositeException; +import io.reactivex.rxjava3.functions.*; +import io.reactivex.rxjava3.internal.functions.Functions; +import io.reactivex.rxjava3.observers.LambdaConsumerIntrospection; +import io.reactivex.rxjava3.plugins.RxJavaPlugins; +import io.reactivex.rxjava3.subjects.MaybeSubject; +import io.reactivex.rxjava3.testsupport.TestHelper; + +public class MaybeConsumersTest implements Consumer, Action { + + final CompositeDisposable composite = new CompositeDisposable(); + + final MaybeSubject processor = MaybeSubject.create(); + + final List events = new ArrayList<>(); + + @Override + public void run() throws Exception { + events.add("OnComplete"); + } + + @Override + public void accept(Object t) throws Exception { + events.add(t); + } + + static Disposable subscribeAutoDispose(Maybe source, CompositeDisposable composite, + Consumer onSuccess, Consumer onError, Action onComplete) { + return source.subscribe(onSuccess, onError, onComplete, composite); + } + + @Test + public void onSuccessNormal() { + + Disposable d = subscribeAutoDispose(processor, composite, this, Functions.ON_ERROR_MISSING, () -> { }); + + assertFalse(d.getClass().toString(), ((LambdaConsumerIntrospection)d).hasCustomOnError()); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onSuccess(1); + + assertEquals(0, composite.size()); + + assertEquals(Arrays.asList(1), events); + + } + + @Test + public void onErrorNormal() { + + subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onSuccess(1); + + assertEquals(0, composite.size()); + + assertEquals(Arrays.asList(1), events); + + } + + @Test + public void onErrorError() { + + Disposable d = subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(d.getClass().toString(), ((LambdaConsumerIntrospection)d).hasCustomOnError()); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onError(new IOException()); + + assertTrue(events.toString(), events.get(0) instanceof IOException); + + assertEquals(0, composite.size()); + } + + @Test + public void onCompleteNormal() { + + subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onComplete(); + + assertEquals(0, composite.size()); + + assertEquals(Arrays.asList("OnComplete"), events); + + } + + @Test + public void onCompleteError() { + + subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onError(new IOException()); + + assertTrue(events.toString(), events.get(0) instanceof IOException); + + assertEquals(0, composite.size()); + } + + @Test + public void onCompleteDispose() { + + Disposable d = subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + assertFalse(d.isDisposed()); + + d.dispose(); + d.dispose(); + + assertTrue(d.isDisposed()); + + assertEquals(0, composite.size()); + + assertFalse(processor.hasObservers()); + } + + @Test + public void onSuccessCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, new Consumer() { + @Override + public void accept(Object t) throws Exception { + throw new IOException(); + } + }, this, this); + + processor.onSuccess(1); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void onErrorCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, this, new Consumer() { + @Override + public void accept(Throwable t) throws Exception { + throw new IOException(t); + } + }, this); + + processor.onError(new IllegalArgumentException()); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertError(errors, 0, CompositeException.class); + List inners = TestHelper.compositeList(errors.get(0)); + TestHelper.assertError(inners, 0, IllegalArgumentException.class); + TestHelper.assertError(inners, 1, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void onCompleteCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, this, this, new Action() { + @Override + public void run() throws Exception { + throw new IOException(); + } + }); + + processor.onComplete(); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void badSource() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose( + new Maybe() { + @Override + protected void subscribeActual( + MaybeObserver observer) { + observer.onSubscribe(Disposable.empty()); + observer.onComplete(); + + observer.onSubscribe(Disposable.empty()); + observer.onSuccess(2); + observer.onComplete(); + observer.onError(new IOException()); + } + }, composite, this, this, this + ); + + assertEquals(Arrays.asList("OnComplete"), events); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } +} diff --git a/src/test/java/io/reactivex/rxjava3/internal/observers/ObservableConsumersTest.java b/src/test/java/io/reactivex/rxjava3/internal/observers/ObservableConsumersTest.java new file mode 100644 index 0000000000..b5d26340e7 --- /dev/null +++ b/src/test/java/io/reactivex/rxjava3/internal/observers/ObservableConsumersTest.java @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2016-present, RxJava Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See + * the License for the specific language governing permissions and limitations under the License. + */ + +/* + * Copyright 2016-2019 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.reactivex.rxjava3.internal.observers; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.*; + +import org.junit.Test; + +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.*; +import io.reactivex.rxjava3.exceptions.*; +import io.reactivex.rxjava3.functions.*; +import io.reactivex.rxjava3.internal.functions.Functions; +import io.reactivex.rxjava3.observers.LambdaConsumerIntrospection; +import io.reactivex.rxjava3.plugins.RxJavaPlugins; +import io.reactivex.rxjava3.subjects.PublishSubject; +import io.reactivex.rxjava3.testsupport.TestHelper; + +public class ObservableConsumersTest implements Consumer, Action { + + final CompositeDisposable composite = new CompositeDisposable(); + + final PublishSubject processor = PublishSubject.create(); + + final List events = new ArrayList<>(); + + @Override + public void run() throws Exception { + events.add("OnComplete"); + } + + @Override + public void accept(Object t) throws Exception { + events.add(t); + } + + static Disposable subscribeAutoDispose(Observable source, CompositeDisposable composite, + Consumer onNext, Consumer onError, Action onComplete) { + return source.subscribe(onNext, onError, onComplete, composite); + } + + @Test + public void onNextNormal() { + + Disposable d = subscribeAutoDispose(processor, composite, this, Functions.ON_ERROR_MISSING, () -> { }); + + assertFalse(d.getClass().toString(), ((LambdaConsumerIntrospection)d).hasCustomOnError()); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onNext(1); + + assertTrue(composite.size() > 0); + + assertEquals(Arrays.asList(1), events); + + processor.onComplete(); + + assertEquals(Arrays.asList(1), events); + + assertEquals(0, composite.size()); + } + + @Test + public void onErrorNormal() { + + subscribeAutoDispose(processor, composite, this, Functions.ON_ERROR_MISSING, () -> { }); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onNext(1); + + assertTrue(composite.size() > 0); + + assertEquals(Arrays.asList(1), events); + + processor.onComplete(); + + assertEquals(Arrays.asList(1), events); + + assertEquals(0, composite.size()); + } + + @Test + public void onErrorError() { + + Disposable d = subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(d.getClass().toString(), ((LambdaConsumerIntrospection)d).hasCustomOnError()); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onNext(1); + + assertTrue(composite.size() > 0); + + assertEquals(Arrays.asList(1), events); + + processor.onError(new IOException()); + + assertEquals(events.toString(), 1, events.get(0)); + assertTrue(events.toString(), events.get(1) instanceof IOException); + + assertEquals(0, composite.size()); + } + + @Test + public void onCompleteNormal() { + + subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onNext(1); + + assertTrue(composite.size() > 0); + + assertEquals(Arrays.asList(1), events); + + processor.onComplete(); + + assertEquals(Arrays.asList(1, "OnComplete"), events); + + assertEquals(0, composite.size()); + } + + @Test + public void onCompleteError() { + + subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onNext(1); + + assertTrue(composite.size() > 0); + + assertEquals(Arrays.asList(1), events); + + processor.onError(new IOException()); + + assertEquals(events.toString(), 1, events.get(0)); + assertTrue(events.toString(), events.get(1) instanceof IOException); + + assertEquals(0, composite.size()); + } + + @Test + public void onCompleteDispose() { + + Disposable d = subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + assertFalse(d.isDisposed()); + + d.dispose(); + d.dispose(); + + assertTrue(d.isDisposed()); + + assertEquals(0, composite.size()); + + assertFalse(processor.hasObservers()); + } + + @Test + public void onNextCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, new Consumer() { + @Override + public void accept(Object t) throws Exception { + throw new IOException(); + } + }, this, this); + + processor.onNext(1); + + assertTrue(errors.toString(), errors.isEmpty()); + + assertTrue(events.toString(), events.get(0) instanceof IOException); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void onNextCrashOnError() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, this, new Consumer() { + @Override + public void accept(Throwable t) throws Exception { + throw new IOException(t); + } + }, this); + + processor.onError(new IllegalArgumentException()); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertError(errors, 0, CompositeException.class); + List inners = TestHelper.compositeList(errors.get(0)); + TestHelper.assertError(inners, 0, IllegalArgumentException.class); + TestHelper.assertError(inners, 1, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void onNextCrashNoError() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, t -> { + throw new IOException(); + }, Functions.ON_ERROR_MISSING, () -> { }); + + processor.onNext(1); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertError(errors, 0, OnErrorNotImplementedException.class); + assertTrue(errors.get(0).getCause() instanceof IOException); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void onCompleteCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, this, this, new Action() { + @Override + public void run() throws Exception { + throw new IOException(); + } + }); + + processor.onNext(1); + processor.onComplete(); + + assertEquals(Arrays.asList(1), events); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void badSource() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose( + new Observable() { + @Override + protected void subscribeActual( + Observer observer) { + observer.onSubscribe(Disposable.empty()); + observer.onNext(1); + observer.onComplete(); + + observer.onSubscribe(Disposable.empty()); + observer.onNext(2); + observer.onComplete(); + observer.onError(new IOException()); + } + }, composite, this, this, this + ); + + assertEquals(Arrays.asList(1, "OnComplete"), events); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } +} diff --git a/src/test/java/io/reactivex/rxjava3/internal/observers/SingleConsumersTest.java b/src/test/java/io/reactivex/rxjava3/internal/observers/SingleConsumersTest.java new file mode 100644 index 0000000000..a840d8f71a --- /dev/null +++ b/src/test/java/io/reactivex/rxjava3/internal/observers/SingleConsumersTest.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2016-present, RxJava Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See + * the License for the specific language governing permissions and limitations under the License. + */ + +/* + * Copyright 2016-2019 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.reactivex.rxjava3.internal.observers; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.*; + +import org.junit.Test; + +import io.reactivex.rxjava3.core.*; +import io.reactivex.rxjava3.disposables.*; +import io.reactivex.rxjava3.exceptions.CompositeException; +import io.reactivex.rxjava3.functions.Consumer; +import io.reactivex.rxjava3.internal.functions.Functions; +import io.reactivex.rxjava3.observers.LambdaConsumerIntrospection; +import io.reactivex.rxjava3.plugins.RxJavaPlugins; +import io.reactivex.rxjava3.subjects.SingleSubject; +import io.reactivex.rxjava3.testsupport.TestHelper; + +public class SingleConsumersTest implements Consumer { + + final CompositeDisposable composite = new CompositeDisposable(); + + final SingleSubject processor = SingleSubject.create(); + + final List events = new ArrayList<>(); + + @Override + public void accept(Object t) throws Exception { + events.add(t); + } + + static Disposable subscribeAutoDispose(Single source, CompositeDisposable composite, + Consumer onSuccess, Consumer onError) { + return source.subscribe(onSuccess, onError, composite); + } + + @Test + public void onSuccessNormal() { + + Disposable d = subscribeAutoDispose(processor, composite, this, Functions.ON_ERROR_MISSING); + + assertFalse(d.getClass().toString(), ((LambdaConsumerIntrospection)d).hasCustomOnError()); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onSuccess(1); + + assertEquals(0, composite.size()); + + assertEquals(Arrays.asList(1), events); + + } + + @Test + public void onErrorNormal() { + + subscribeAutoDispose(processor, composite, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onSuccess(1); + + assertEquals(0, composite.size()); + + assertEquals(Arrays.asList(1), events); + + } + + @Test + public void onErrorError() { + + Disposable d = subscribeAutoDispose(processor, composite, this, this); + + assertTrue(d.getClass().toString(), ((LambdaConsumerIntrospection)d).hasCustomOnError()); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onError(new IOException()); + + assertTrue(events.toString(), events.get(0) instanceof IOException); + + assertEquals(0, composite.size()); + } + + @Test + public void onSuccessCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, new Consumer() { + @Override + public void accept(Object t) throws Exception { + throw new IOException(); + } + }, this); + + processor.onSuccess(1); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void onErrorCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, this, new Consumer() { + @Override + public void accept(Throwable t) throws Exception { + throw new IOException(t); + } + }); + + processor.onError(new IllegalArgumentException()); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertError(errors, 0, CompositeException.class); + List inners = TestHelper.compositeList(errors.get(0)); + TestHelper.assertError(inners, 0, IllegalArgumentException.class); + TestHelper.assertError(inners, 1, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void badSource() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose( + new Single() { + @Override + protected void subscribeActual( + SingleObserver observer) { + observer.onSubscribe(Disposable.empty()); + observer.onSuccess(1); + + observer.onSubscribe(Disposable.empty()); + observer.onSuccess(2); + observer.onError(new IOException()); + } + }, composite, this, this + ); + + assertEquals(Arrays.asList(1), events); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } +} diff --git a/src/test/java/io/reactivex/rxjava3/internal/subscribers/FlowableConsumersTest.java b/src/test/java/io/reactivex/rxjava3/internal/subscribers/FlowableConsumersTest.java new file mode 100644 index 0000000000..cc7083cde7 --- /dev/null +++ b/src/test/java/io/reactivex/rxjava3/internal/subscribers/FlowableConsumersTest.java @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2016-present, RxJava Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See + * the License for the specific language governing permissions and limitations under the License. + */ + +/* + * Copyright 2016-2019 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.reactivex.rxjava3.internal.subscribers; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.*; + +import org.junit.Test; +import org.reactivestreams.Subscriber; + +import io.reactivex.rxjava3.core.*; +import io.reactivex.rxjava3.disposables.*; +import io.reactivex.rxjava3.exceptions.*; +import io.reactivex.rxjava3.functions.*; +import io.reactivex.rxjava3.internal.functions.Functions; +import io.reactivex.rxjava3.internal.subscriptions.BooleanSubscription; +import io.reactivex.rxjava3.observers.LambdaConsumerIntrospection; +import io.reactivex.rxjava3.plugins.RxJavaPlugins; +import io.reactivex.rxjava3.processors.PublishProcessor; +import io.reactivex.rxjava3.testsupport.TestHelper; + +public class FlowableConsumersTest implements Consumer, Action { + + final CompositeDisposable composite = new CompositeDisposable(); + + final PublishProcessor processor = PublishProcessor.create(); + + final List events = new ArrayList<>(); + + @Override + public void run() throws Exception { + events.add("OnComplete"); + } + + @Override + public void accept(Object t) throws Exception { + events.add(t); + } + + static Disposable subscribeAutoDispose(Flowable source, CompositeDisposable composite, + Consumer onNext, Consumer onError, Action onComplete) { + return source.subscribe(onNext, onError, onComplete, composite); + } + + @Test + public void onNextNormal() { + + Disposable d = subscribeAutoDispose(processor, composite, this, Functions.ON_ERROR_MISSING, () -> { }); + + assertFalse(d.getClass().toString(), ((LambdaConsumerIntrospection)d).hasCustomOnError()); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onNext(1); + + assertTrue(composite.size() > 0); + + assertEquals(Arrays.asList(1), events); + + processor.onComplete(); + + assertEquals(Arrays.asList(1), events); + + assertEquals(0, composite.size()); + } + + @Test + public void onErrorNormal() { + + subscribeAutoDispose(processor, composite, this, this, () -> { }); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onNext(1); + + assertTrue(composite.size() > 0); + + assertEquals(Arrays.asList(1), events); + + processor.onComplete(); + + assertEquals(Arrays.asList(1), events); + + assertEquals(0, composite.size()); + } + + @Test + public void onErrorError() { + + Disposable d = subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(d.getClass().toString(), ((LambdaConsumerIntrospection)d).hasCustomOnError()); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onNext(1); + + assertTrue(composite.size() > 0); + + assertEquals(Arrays.asList(1), events); + + processor.onError(new IOException()); + + assertEquals(events.toString(), 1, events.get(0)); + assertTrue(events.toString(), events.get(1) instanceof IOException); + + assertEquals(0, composite.size()); + } + + @Test + public void onCompleteNormal() { + + subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onNext(1); + + assertTrue(composite.size() > 0); + + assertEquals(Arrays.asList(1), events); + + processor.onComplete(); + + assertEquals(Arrays.asList(1, "OnComplete"), events); + + assertEquals(0, composite.size()); + } + + @Test + public void onCompleteError() { + + subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + processor.onNext(1); + + assertTrue(composite.size() > 0); + + assertEquals(Arrays.asList(1), events); + + processor.onError(new IOException()); + + assertEquals(events.toString(), 1, events.get(0)); + assertTrue(events.toString(), events.get(1) instanceof IOException); + + assertEquals(0, composite.size()); + } + + @Test + public void onCompleteDispose() { + + Disposable d = subscribeAutoDispose(processor, composite, this, this, this); + + assertTrue(composite.size() > 0); + + assertTrue(events.toString(), events.isEmpty()); + + assertFalse(d.isDisposed()); + + d.dispose(); + d.dispose(); + + assertTrue(d.isDisposed()); + + assertEquals(0, composite.size()); + + assertFalse(processor.hasSubscribers()); + } + + @Test + public void onNextCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, new Consumer() { + @Override + public void accept(Object t) throws Exception { + throw new IOException(); + } + }, this, this); + + processor.onNext(1); + + assertTrue(errors.toString(), errors.isEmpty()); + + assertTrue(events.toString(), events.get(0) instanceof IOException); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void onNextCrashOnError() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, this, new Consumer() { + @Override + public void accept(Throwable t) throws Exception { + throw new IOException(t); + } + }, this); + + processor.onError(new IllegalArgumentException()); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertError(errors, 0, CompositeException.class); + List inners = TestHelper.compositeList(errors.get(0)); + TestHelper.assertError(inners, 0, IllegalArgumentException.class); + TestHelper.assertError(inners, 1, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void onNextCrashNoError() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, new Consumer() { + @Override + public void accept(Object t) throws Exception { + throw new IOException(); + } + }, Functions.ON_ERROR_MISSING, () -> { }); + + processor.onNext(1); + + assertTrue(events.toString(), events.isEmpty()); + + TestHelper.assertError(errors, 0, OnErrorNotImplementedException.class); + assertTrue(errors.get(0).getCause() instanceof IOException); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void onCompleteCrash() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose(processor, composite, this, this, new Action() { + @Override + public void run() throws Exception { + throw new IOException(); + } + }); + + processor.onNext(1); + processor.onComplete(); + + assertEquals(Arrays.asList(1), events); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void badSource() { + List errors = TestHelper.trackPluginErrors(); + try { + subscribeAutoDispose( + new Flowable() { + @Override + protected void subscribeActual( + Subscriber s) { + s.onSubscribe(new BooleanSubscription()); + s.onNext(1); + s.onComplete(); + + s.onSubscribe(new BooleanSubscription()); + s.onNext(2); + s.onComplete(); + s.onError(new IOException()); + } + }, composite, this, this, this + ); + + assertEquals(Arrays.asList(1, "OnComplete"), events); + + TestHelper.assertUndeliverable(errors, 0, IOException.class); + } finally { + RxJavaPlugins.reset(); + } + } +} diff --git a/src/test/java/io/reactivex/rxjava3/validators/BaseTypeAnnotations.java b/src/test/java/io/reactivex/rxjava3/validators/BaseTypeAnnotations.java index d03c0dcade..582df0fa71 100644 --- a/src/test/java/io/reactivex/rxjava3/validators/BaseTypeAnnotations.java +++ b/src/test/java/io/reactivex/rxjava3/validators/BaseTypeAnnotations.java @@ -22,6 +22,7 @@ import io.reactivex.rxjava3.annotations.*; import io.reactivex.rxjava3.core.*; +import io.reactivex.rxjava3.disposables.DisposableContainer; import io.reactivex.rxjava3.flowables.ConnectableFlowable; import io.reactivex.rxjava3.observables.ConnectableObservable; import io.reactivex.rxjava3.parallel.ParallelFlowable; @@ -44,7 +45,8 @@ static void checkCheckReturnValueSupport(Class clazz) { for (Method m : clazz.getMethods()) { if (m.getDeclaringClass() == clazz) { - boolean isSubscribeMethod = "subscribe".equals(m.getName()) && m.getParameterTypes().length == 0; + boolean isSubscribeMethod = "subscribe".equals(m.getName()) && + (m.getParameterTypes().length == 0 || m.getParameterTypes()[m.getParameterCount() - 1] == DisposableContainer.class); boolean isConnectMethod = "connect".equals(m.getName()) && m.getParameterTypes().length == 0; boolean isAnnotationPresent = m.isAnnotationPresent(CheckReturnValue.class); diff --git a/src/test/java/io/reactivex/rxjava3/validators/JavadocForAnnotations.java b/src/test/java/io/reactivex/rxjava3/validators/JavadocForAnnotations.java index c3c814f9ff..1c683783d6 100644 --- a/src/test/java/io/reactivex/rxjava3/validators/JavadocForAnnotations.java +++ b/src/test/java/io/reactivex/rxjava3/validators/JavadocForAnnotations.java @@ -95,7 +95,7 @@ static final void scanFor(StringBuilder sourceCode, String annotation, String in ; int lc = lineNumber(sourceCode, idx); - e.append(" at io.reactivex.").append(baseClassName) + e.append(" at io.reactivex.rxjava3.core.").append(baseClassName) .append(" (").append(baseClassName).append(".java:") .append(lc).append(")").append("\r\n\r\n"); } diff --git a/src/test/java/io/reactivex/rxjava3/validators/JavadocWording.java b/src/test/java/io/reactivex/rxjava3/validators/JavadocWording.java index b09303643c..3ab41589a3 100644 --- a/src/test/java/io/reactivex/rxjava3/validators/JavadocWording.java +++ b/src/test/java/io/reactivex/rxjava3/validators/JavadocWording.java @@ -309,6 +309,7 @@ public void flowableDocRefersToFlowableTypes() throws Exception { && !m.signature.contains("Maybe") && !m.signature.contains("MaybeSource") && !m.signature.contains("Disposable") + && !m.signature.contains("void subscribe") ) { CharSequence subSequence = m.javadoc.subSequence(idx - 6, idx + 11); if (idx < 6 || !subSequence.equals("{@link Disposable")) { diff --git a/src/test/java/io/reactivex/rxjava3/validators/ParamValidationCheckerTest.java b/src/test/java/io/reactivex/rxjava3/validators/ParamValidationCheckerTest.java index 84f99707f2..51c7626ed5 100644 --- a/src/test/java/io/reactivex/rxjava3/validators/ParamValidationCheckerTest.java +++ b/src/test/java/io/reactivex/rxjava3/validators/ParamValidationCheckerTest.java @@ -25,7 +25,7 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observer; -import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.disposables.*; import io.reactivex.rxjava3.exceptions.TestException; import io.reactivex.rxjava3.functions.*; import io.reactivex.rxjava3.internal.functions.Functions; @@ -580,6 +580,8 @@ public void checkParallelFlowable() { defaultValues.put(ParallelFailureHandling.class, ParallelFailureHandling.ERROR); + defaultValues.put(DisposableContainer.class, new CompositeDisposable()); + // JDK 8 types defaultValues.put(Optional.class, Optional.of(1)); From a463d248145d55fc0d0833d192ee11b254012855 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jul 2021 08:13:45 +0200 Subject: [PATCH 042/348] Bump codecov/codecov-action from 1.5.2 to 2.0.1 (#7299) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1.5.2 to 2.0.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v1.5.2...v2.0.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/gradle_branch.yml | 2 +- .github/workflows/gradle_pr.yml | 2 +- .github/workflows/gradle_release.yml | 2 +- .github/workflows/gradle_snapshot.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gradle_branch.yml b/.github/workflows/gradle_branch.yml index 27a45e5ccc..2d64e82a80 100644 --- a/.github/workflows/gradle_branch.yml +++ b/.github/workflows/gradle_branch.yml @@ -29,6 +29,6 @@ jobs: - name: Build RxJava run: ./gradlew build --stacktrace - name: Upload to Codecov - uses: codecov/codecov-action@v1.5.2 + uses: codecov/codecov-action@v2.0.1 - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_pr.yml b/.github/workflows/gradle_pr.yml index dbc5418a92..4a5a0c4ba8 100644 --- a/.github/workflows/gradle_pr.yml +++ b/.github/workflows/gradle_pr.yml @@ -29,6 +29,6 @@ jobs: - name: Build RxJava run: ./gradlew build --stacktrace - name: Upload to Codecov - uses: codecov/codecov-action@v1.5.2 + uses: codecov/codecov-action@v2.0.1 - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index 81962b6028..092dd9f659 100644 --- a/.github/workflows/gradle_release.yml +++ b/.github/workflows/gradle_release.yml @@ -38,7 +38,7 @@ jobs: - name: Build RxJava run: ./gradlew build --stacktrace --no-daemon - name: Upload to Codecov - uses: codecov/codecov-action@v1.5.2 + uses: codecov/codecov-action@v2.0.1 - name: Upload release run: ./gradlew -PreleaseMode=full publish --no-daemon --no-parallel --stacktrace env: diff --git a/.github/workflows/gradle_snapshot.yml b/.github/workflows/gradle_snapshot.yml index ed101d8536..391feb08a5 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -41,7 +41,7 @@ jobs: ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USER }} ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} - name: Upload to Codecov - uses: codecov/codecov-action@v1.5.2 + uses: codecov/codecov-action@v2.0.1 - name: Push Javadoc run: ./push_javadoc.sh # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions From bb814d2064e061d27cbdcd1ac64528d96f97feea Mon Sep 17 00:00:00 2001 From: David Karnok Date: Thu, 22 Jul 2021 17:44:45 +0200 Subject: [PATCH 043/348] 3.x: Javadocs fix some wording in Schedulers.java (#7301) --- .../java/io/reactivex/rxjava3/schedulers/Schedulers.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/reactivex/rxjava3/schedulers/Schedulers.java b/src/main/java/io/reactivex/rxjava3/schedulers/Schedulers.java index f5dbe6ce7c..cc7e693b3d 100644 --- a/src/main/java/io/reactivex/rxjava3/schedulers/Schedulers.java +++ b/src/main/java/io/reactivex/rxjava3/schedulers/Schedulers.java @@ -27,6 +27,8 @@ * The initial and runtime values of the various scheduler types can be overridden via the * {@code RxJavaPlugins.setInit(scheduler name)SchedulerHandler()} and * {@code RxJavaPlugins.set(scheduler name)SchedulerHandler()} respectively. + * Note that overriding any initial {@code Scheduler} via the {@link RxJavaPlugins} + * has to happen before the {@code Schedulers} class is accessed. *

    * Supported system properties ({@code System.getProperty()}): *