diff --git a/.github/workflows/gradle_branch.yml b/.github/workflows/gradle_branch.yml index 5d58c3d508..875051e2c9 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@v2.0.3 + uses: codecov/codecov-action@v2.1.0 - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_jdk11.yml b/.github/workflows/gradle_jdk11.yml index 9b30f8da56..1c49e9ea3c 100644 --- a/.github/workflows/gradle_jdk11.yml +++ b/.github/workflows/gradle_jdk11.yml @@ -28,6 +28,8 @@ jobs: restore-keys: ${{ runner.os }}-gradle-1- - name: Grant execute permission for gradlew run: chmod +x gradlew + - name: Verify generated module-info + run: ./gradlew -PjavaCompatibility=9 jar - name: Build RxJava run: ./gradlew build --stacktrace - name: Generate Javadoc diff --git a/.github/workflows/gradle_pr.yml b/.github/workflows/gradle_pr.yml index 8c1c961ad7..cba63a5dd5 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@v2.0.3 + uses: codecov/codecov-action@v2.1.0 - name: Generate Javadoc run: ./gradlew javadoc --stacktrace diff --git a/.github/workflows/gradle_release.yml b/.github/workflows/gradle_release.yml index 55ae0858c0..4f49eb210e 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@v2.0.3 + uses: codecov/codecov-action@v2.1.0 - 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 f13777798a..963e481866 100644 --- a/.github/workflows/gradle_snapshot.yml +++ b/.github/workflows/gradle_snapshot.yml @@ -42,7 +42,7 @@ jobs: ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USER }} ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} - name: Upload to Codecov - uses: codecov/codecov-action@v2.0.3 + uses: codecov/codecov-action@v2.1.0 - name: Push Javadoc run: ./push_javadoc.sh # Define secrets at https://github.com/ReactiveX/RxJava/settings/secrets/actions diff --git a/README.md b/README.md index aaec7ece62..7449fa7f8b 100644 --- a/README.md +++ b/README.md @@ -526,7 +526,7 @@ APIs marked with the [`@Experimental`][experimental source link] annotation at t #### @Deprecated -APIs marked with the `@Deprecated` annotation at the class or method level will remain supported until the next major release but it is recommended to stop using them. +APIs marked with the `@Deprecated` annotation at the class or method level will remain supported until the next major release, but it is recommended to stop using them. #### io.reactivex.rxjava3.internal.* diff --git a/build.gradle b/build.gradle index 3a87a423e1..779328eb66 100644 --- a/build.gradle +++ b/build.gradle @@ -7,17 +7,18 @@ 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.16.1" - id("biz.aQute.bnd.builder") version "5.3.0" - id("com.vanniktech.maven.publish") version "0.17.0" + id("biz.aQute.bnd.builder") version "6.0.0" + id("com.vanniktech.maven.publish") version "0.18.0" + id("org.beryx.jar") version "1.2.0" } ext { reactiveStreamsVersion = "1.0.3" junitVersion = "4.13.2" testNgVersion = "7.4.0" - mockitoVersion = "3.12.4" + mockitoVersion = "4.0.0" jmhLibVersion = "1.21" - guavaVersion = "30.1.1-jre" + guavaVersion = "31.0.1-jre" } def releaseTag = System.getenv("BUILD_TAG") @@ -86,6 +87,8 @@ animalsniffer { } jar { + // Cover for bnd still not supporting MR Jars: https://github.com/bndtools/bnd/issues/2227 + bnd('-fixupmessages': '^Classes found in the wrong directory: \\\\{META-INF/versions/9/module-info\\\\.class=module-info}$') bnd( "Bundle-Name": "rxjava", "Bundle-Vendor": "RxJava Contributors", @@ -93,10 +96,12 @@ jar { "Import-Package": "!org.junit,!junit.framework,!org.mockito.*,!org.testng.*,*", "Bundle-DocURL": "https://github.com/ReactiveX/RxJava", "Eclipse-ExtensibleAPI": "true", - "Automatic-Module-Name": "io.reactivex.rxjava3", "Export-Package": "!io.reactivex.rxjava3.internal.*, io.reactivex.rxjava3.*", - "Bundle-SymbolicName": "io.reactivex.rxjava3.rxjava" + "Bundle-SymbolicName": "io.reactivex.rxjava3.rxjava", + "Multi-Release": "true" ) + + moduleInfoPath = 'src/main/module/module-info.java' } license { diff --git a/gradle/javadoc_cleanup.gradle b/gradle/javadoc_cleanup.gradle index a391375af4..5f120656e0 100644 --- a/gradle/javadoc_cleanup.gradle +++ b/gradle/javadoc_cleanup.gradle @@ -11,6 +11,16 @@ task javadocCleanup(dependsOn: "javadoc") doLast { 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/subjects/PublishSubject.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/processors/PublishProcessor.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/subjects/AsyncSubject.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/processors/AsyncProcessor.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/subjects/BehaviorSubject.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/processors/BehaviorProcessor.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/processors/MulticastProcessor.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/subjects/UnicastSubject.html')) + fixJavadocFile(rootProject.file('build/docs/javadoc/io/reactivex/rxjava3/processors/UnicastProcessor.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')) diff --git a/src/main/java/io/reactivex/rxjava3/core/Flowable.java b/src/main/java/io/reactivex/rxjava3/core/Flowable.java index 096486bd7b..6cbdf0a412 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Flowable.java +++ b/src/main/java/io/reactivex/rxjava3/core/Flowable.java @@ -16972,9 +16972,9 @@ public final Flowable takeUntil(@NonNull Predicate stopPredicate) /** * Returns a {@code Flowable} that emits the items emitted by the current {@code Flowable} until a second {@link Publisher} - * emits an item. + * emits an item or completes. *

- * + * *

*
Backpressure:
*
The operator doesn't interfere with backpressure which is determined by the current {@code Flowable}'s backpressure @@ -16984,7 +16984,7 @@ public final Flowable takeUntil(@NonNull Predicate stopPredicate) *
* * @param other - * the {@code Publisher} whose first emitted item will cause {@code takeUntil} to stop emitting items + * the {@code Publisher} whose first emitted item or completion will cause {@code takeUntil} to stop emitting items * from the current {@code Flowable} * @param * the type of items emitted by {@code other} diff --git a/src/main/java/io/reactivex/rxjava3/core/Observable.java b/src/main/java/io/reactivex/rxjava3/core/Observable.java index 37641d438e..2206319b18 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Observable.java +++ b/src/main/java/io/reactivex/rxjava3/core/Observable.java @@ -14028,16 +14028,16 @@ public final Observable takeLast(long time, @NonNull TimeUnit unit, @NonNull /** * Returns an {@code Observable} that emits the items emitted by the current {@code Observable} until a second {@link ObservableSource} - * emits an item. + * emits an item or completes. *

- * + * *

*
Scheduler:
*
{@code takeUntil} does not operate by default on a particular {@link Scheduler}.
*
* * @param other - * the {@code ObservableSource} whose first emitted item will cause {@code takeUntil} to stop emitting items + * the {@code ObservableSource} whose first emitted item or completion will cause {@code takeUntil} to stop emitting items * from the current {@code Observable} * @param * the type of items emitted by {@code other} diff --git a/src/main/java/io/reactivex/rxjava3/core/Single.java b/src/main/java/io/reactivex/rxjava3/core/Single.java index eb590aa428..ea6a610feb 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Single.java +++ b/src/main/java/io/reactivex/rxjava3/core/Single.java @@ -4735,7 +4735,7 @@ public final Disposable subscribe() { @CheckReturnValue @NonNull @SchedulerSupport(SchedulerSupport.NONE) - public final Disposable subscribe(@NonNull BiConsumer onCallback) { + public final Disposable subscribe(@NonNull BiConsumer<@Nullable ? super T, @Nullable ? super Throwable> onCallback) { Objects.requireNonNull(onCallback, "onCallback is null"); BiConsumerSingleObserver observer = new BiConsumerSingleObserver<>(onCallback); diff --git a/src/main/java/io/reactivex/rxjava3/observers/BaseTestConsumer.java b/src/main/java/io/reactivex/rxjava3/observers/BaseTestConsumer.java index 265ea894a5..5807e598ff 100644 --- a/src/main/java/io/reactivex/rxjava3/observers/BaseTestConsumer.java +++ b/src/main/java/io/reactivex/rxjava3/observers/BaseTestConsumer.java @@ -307,11 +307,11 @@ private U assertError(@NonNull Predicate errorPredicate, boolean exac public final U assertValue(@NonNull T value) { int s = values.size(); if (s != 1) { - throw fail("expected: " + valueAndClass(value) + " but was: " + values); + throw fail("\nexpected: " + valueAndClass(value) + "\ngot: " + values); } T v = values.get(0); if (!Objects.equals(value, v)) { - throw fail("expected: " + valueAndClass(value) + " but was: " + valueAndClass(v)); + throw fail("\nexpected: " + valueAndClass(value) + "\ngot: " + valueAndClass(v)); } return (U)this; } @@ -359,7 +359,7 @@ public final U assertValueAt(int index, @NonNull T value) { T v = values.get(index); if (!Objects.equals(value, v)) { - throw fail("expected: " + valueAndClass(value) + " but was: " + valueAndClass(v) + " at position " + index); + throw fail("Values at position " + index + " differ;\nexpected: " + valueAndClass(value) + "\ngot: " + valueAndClass(v)); } return (U)this; } @@ -425,7 +425,7 @@ public static String valueAndClass(@Nullable Object o) { public final U assertValueCount(int count) { int s = values.size(); if (s != count) { - throw fail("Value counts differ; expected: " + count + " but was: " + s); + throw fail("Value counts differ;\nexpected: " + count + "\ngot: " + s); } return (U)this; } @@ -450,14 +450,14 @@ public final U assertNoValues() { public final U assertValues(@NonNull T... values) { int s = this.values.size(); if (s != values.length) { - throw fail("Value count differs; expected: " + values.length + " " + Arrays.toString(values) - + " but was: " + s + " " + this.values); + throw fail("Value count differs;\nexpected: " + values.length + " " + Arrays.toString(values) + + "\ngot: " + s + " " + this.values); } for (int i = 0; i < s; i++) { T v = this.values.get(i); T u = values[i]; if (!Objects.equals(u, v)) { - throw fail("Values at position " + i + " differ; expected: " + valueAndClass(u) + " but was: " + valueAndClass(v)); + throw fail("Values at position " + i + " differ;\nexpected: " + valueAndClass(u) + "\ngot: " + valueAndClass(v)); } } return (U)this; @@ -504,7 +504,7 @@ public final U assertValueSequence(@NonNull Iterable sequence) { T v = actualIterator.next(); if (!Objects.equals(u, v)) { - throw fail("Values at position " + i + " differ; expected: " + valueAndClass(u) + " but was: " + valueAndClass(v)); + throw fail("Values at position " + i + " differ;\nexpected: " + valueAndClass(u) + "\ngot: " + valueAndClass(v)); } i++; } diff --git a/src/main/java/io/reactivex/rxjava3/operators/QueueDisposable.java b/src/main/java/io/reactivex/rxjava3/operators/QueueDisposable.java index f293e6e9e7..97096064d9 100644 --- a/src/main/java/io/reactivex/rxjava3/operators/QueueDisposable.java +++ b/src/main/java/io/reactivex/rxjava3/operators/QueueDisposable.java @@ -18,7 +18,7 @@ /** * An interface extending {@link SimpleQueue} and {@link Disposable} and allows negotiating - * the fusion mode between subsequent operators of the {@link Observable} base reactive type. + * the fusion mode between subsequent operators of the {@link io.reactivex.rxjava3.core.Observable Observable} base reactive type. *

* The negotiation happens in subscription time when the upstream * calls the {@code onSubscribe} with an instance of this interface. The diff --git a/src/main/java/io/reactivex/rxjava3/operators/QueueSubscription.java b/src/main/java/io/reactivex/rxjava3/operators/QueueSubscription.java index f799dcd014..eae8922992 100644 --- a/src/main/java/io/reactivex/rxjava3/operators/QueueSubscription.java +++ b/src/main/java/io/reactivex/rxjava3/operators/QueueSubscription.java @@ -19,7 +19,7 @@ /** * An interface extending {@link SimpleQueue} and {@link Subscription} and allows negotiating - * the fusion mode between subsequent operators of the {@link Flowable} base reactive type. + * the fusion mode between subsequent operators of the {@link io.reactivex.rxjava3.core.Flowable Flowable} base reactive type. *

* The negotiation happens in subscription time when the upstream * calls the {@code onSubscribe} with an instance of this interface. The diff --git a/src/main/java/io/reactivex/rxjava3/processors/BehaviorProcessor.java b/src/main/java/io/reactivex/rxjava3/processors/BehaviorProcessor.java index 56c9d881f0..eac40a8a75 100644 --- a/src/main/java/io/reactivex/rxjava3/processors/BehaviorProcessor.java +++ b/src/main/java/io/reactivex/rxjava3/processors/BehaviorProcessor.java @@ -306,17 +306,14 @@ public void onComplete() { } /** - * Tries to emit the item to all currently subscribed Subscribers if all of them - * has requested some value, returns false otherwise. + * Tries to emit the item to all currently subscribed {@link Subscriber}s if all of them + * has requested some value, returns {@code false} otherwise. *

- * This method should be called in a sequential manner just like the onXXX methods - * of the PublishProcessor. - *

- * Calling with a null value will terminate the PublishProcessor and a NullPointerException - * is signaled to the Subscribers. + * This method should be called in a sequential manner just like the {@code onXXX} methods + * of this {@code BehaviorProcessor}. *

History: 2.0.8 - experimental - * @param t the item to emit, not null - * @return true if the item was emitted to all Subscribers + * @param t the item to emit, not {@code null} + * @return {@code true} if the item was emitted to all {@code Subscriber}s * @throws NullPointerException if {@code t} is {@code null} * @since 2.2 */ diff --git a/src/main/java/io/reactivex/rxjava3/processors/PublishProcessor.java b/src/main/java/io/reactivex/rxjava3/processors/PublishProcessor.java index 79f38a06ec..db6787880f 100644 --- a/src/main/java/io/reactivex/rxjava3/processors/PublishProcessor.java +++ b/src/main/java/io/reactivex/rxjava3/processors/PublishProcessor.java @@ -271,17 +271,14 @@ public void onComplete() { } /** - * Tries to emit the item to all currently subscribed Subscribers if all of them - * has requested some value, returns false otherwise. + * Tries to emit the item to all currently subscribed {@link Subscriber}s if all of them + * has requested some value, returns {@code false} otherwise. *

- * This method should be called in a sequential manner just like the onXXX methods - * of the PublishProcessor. - *

- * Calling with a null value will terminate the PublishProcessor and a NullPointerException - * is signaled to the Subscribers. + * This method should be called in a sequential manner just like the {@code onXXX} methods + * of this {@code PublishProcessor}. *

History: 2.0.8 - experimental - * @param t the item to emit, not null - * @return true if the item was emitted to all Subscribers + * @param t the item to emit, not {@code null} + * @return {@code true} if the item was emitted to all {@code Subscriber}s * @throws NullPointerException if {@code t} is {@code null} * @since 2.2 */ diff --git a/src/main/module/module-info.java b/src/main/module/module-info.java new file mode 100644 index 0000000000..4bed327f1a --- /dev/null +++ b/src/main/module/module-info.java @@ -0,0 +1,32 @@ +/* + * 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. + */ + +module io.reactivex.rxjava3 { + exports io.reactivex.rxjava3.annotations; + exports io.reactivex.rxjava3.core; + exports io.reactivex.rxjava3.disposables; + exports io.reactivex.rxjava3.exceptions; + exports io.reactivex.rxjava3.flowables; + exports io.reactivex.rxjava3.functions; + exports io.reactivex.rxjava3.observables; + exports io.reactivex.rxjava3.observers; + exports io.reactivex.rxjava3.operators; + exports io.reactivex.rxjava3.parallel; + exports io.reactivex.rxjava3.plugins; + exports io.reactivex.rxjava3.processors; + exports io.reactivex.rxjava3.schedulers; + exports io.reactivex.rxjava3.subjects; + exports io.reactivex.rxjava3.subscribers; + + requires transitive org.reactivestreams; +} \ No newline at end of file diff --git a/src/test/java/io/reactivex/rxjava3/observers/TestObserverTest.java b/src/test/java/io/reactivex/rxjava3/observers/TestObserverTest.java index 576dd4bfb1..cd83664014 100644 --- a/src/test/java/io/reactivex/rxjava3/observers/TestObserverTest.java +++ b/src/test/java/io/reactivex/rxjava3/observers/TestObserverTest.java @@ -999,7 +999,7 @@ public void assertValueAtIndexMatch() { @Test public void assertValueAtIndexNoMatch() { - assertThrowsWithMessage("expected: b (class: String) but was: c (class: String) at position 2 (latch = 0, values = 3, errors = 0, completions = 1)", AssertionError.class, () -> { + assertThrowsWithMessage("Values at position 2 differ;\nexpected: b (class: String)\ngot: c (class: String) (latch = 0, values = 3, errors = 0, completions = 1)", AssertionError.class, () -> { TestObserver to = new TestObserver<>(); Observable.just("a", "b", "c").subscribe(to); diff --git a/src/test/java/io/reactivex/rxjava3/testsupport/BaseTestConsumerEx.java b/src/test/java/io/reactivex/rxjava3/testsupport/BaseTestConsumerEx.java index 05004dae2e..c06c1afcad 100644 --- a/src/test/java/io/reactivex/rxjava3/testsupport/BaseTestConsumerEx.java +++ b/src/test/java/io/reactivex/rxjava3/testsupport/BaseTestConsumerEx.java @@ -160,7 +160,7 @@ public final U assertErrorMessage(String message) { Throwable e = errors.get(0); String errorMessage = e.getMessage(); if (!Objects.equals(message, errorMessage)) { - throw fail("Error message differs; exptected: " + message + " but was: " + errorMessage); + throw fail("Error message differs;\nexpected: " + message + "\ngot: " + errorMessage); } } else { throw fail("Multiple errors"); diff --git a/src/test/java/io/reactivex/rxjava3/testsupport/TestObserverEx.java b/src/test/java/io/reactivex/rxjava3/testsupport/TestObserverEx.java index 8b09c4e588..b7812c21a8 100644 --- a/src/test/java/io/reactivex/rxjava3/testsupport/TestObserverEx.java +++ b/src/test/java/io/reactivex/rxjava3/testsupport/TestObserverEx.java @@ -254,8 +254,8 @@ public final TestObserverEx assertFusionMode(int mode) { int m = establishedFusionMode; if (m != mode) { if (qd != null) { - throw new AssertionError("Fusion mode different. Expected: " + fusionModeToString(mode) - + ", actual: " + fusionModeToString(m)); + throw new AssertionError("Fusion mode different.\nexpected: " + fusionModeToString(mode) + + "\ngot: " + fusionModeToString(m)); } else { throw fail("Upstream is not fuseable"); } diff --git a/src/test/java/io/reactivex/rxjava3/testsupport/TestObserverExTest.java b/src/test/java/io/reactivex/rxjava3/testsupport/TestObserverExTest.java index 127435b515..2296ceb757 100644 --- a/src/test/java/io/reactivex/rxjava3/testsupport/TestObserverExTest.java +++ b/src/test/java/io/reactivex/rxjava3/testsupport/TestObserverExTest.java @@ -1274,7 +1274,7 @@ public void assertValueAtIndexMatch() { @Test public void assertValueAtIndexNoMatch() { - assertThrows("expected: b (class: String) but was: c (class: String) (latch = 0, values = 3, errors = 0, completions = 1)", AssertionError.class, () -> { + assertThrows("\nexpected: b (class: String)\ngot: c (class: String) (latch = 0, values = 3, errors = 0, completions = 1)", AssertionError.class, () -> { TestObserverEx to = new TestObserverEx<>(); Observable.just("a", "b", "c").subscribe(to);