Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[2.1.15] map method called with null #6059

Closed
boris-petrov opened this issue Jun 22, 2018 · 12 comments · Fixed by #6060
Closed

[2.1.15] map method called with null #6059

boris-petrov opened this issue Jun 22, 2018 · 12 comments · Fixed by #6060

Comments

@boris-petrov
Copy link

I have something like:

observable.concatMapMaybe(...).map(x -> ...);

This x is null sometimes (our tests reproduce it consistently in one case). Didn't happen on 2.1.14. I can't give more information for now, just to let you know there is a problem. If you can't figure it out soon, I'll try to create some reproduction.

@akarnokd
Copy link
Member

Version 2.1.15 did not touch any of the operators you listed and without code demonstrating the problem (you say you have a test reliably failing), we can't do much about it.

@akarnokd akarnokd added 2.x Missing-Details Could be a question or a bug report, but not enough details are provided. labels Jun 22, 2018
@boris-petrov
Copy link
Author

OK, I tried debugging with what I thought the problem might be, no luck so far. Here's a couple of stacktraces in the meantime if you can figure out something from them:

NPE in my code as the value is null
        at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:59)
        at io.reactivex.internal.operators.mixed.ObservableConcatMapMaybe$ConcatMapMaybeMainObserver.drain(ObservableConcatMapMaybe.java:256)
        at io.reactivex.internal.operators.mixed.ObservableConcatMapMaybe$ConcatMapMaybeMainObserver.innerSuccess(ObservableConcatMapMaybe.java:165)
        at io.reactivex.internal.operators.mixed.ObservableConcatMapMaybe$ConcatMapMaybeMainObserver$ConcatMapMaybeObserver.onSuccess(ObservableConcatMapMaybe.java:290)
        at io.reactivex.internal.operators.single.SingleFlatMapMaybe$FlatMapMaybeObserver.onSuccess(SingleFlatMapMaybe.java:117)
        at io.reactivex.internal.operators.maybe.MaybeJust.subscribeActual(MaybeJust.java:36)
        at io.reactivex.Maybe.subscribe(Maybe.java:4096)
        at io.reactivex.internal.operators.single.SingleFlatMapMaybe$FlatMapSingleObserver.onSuccess(SingleFlatMapMaybe.java:89)
        at io.reactivex.internal.operators.single.SingleMap$MapSingleObserver.onSuccess(SingleMap.java:64)
        at io.reactivex.internal.operators.single.SingleMap$MapSingleObserver.onSuccess(SingleMap.java:64)
        at io.reactivex.internal.operators.single.SingleDoOnSuccess$DoOnSuccess.onSuccess(SingleDoOnSuccess.java:59)
        at io.reactivex.internal.operators.single.SingleMap$MapSingleObserver.onSuccess(SingleMap.java:64)
        at io.reactivex.internal.operators.observable.ObservableToListSingle$ToListObserver.onComplete(ObservableToListSingle.java:113)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:378)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:327)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onComplete(ObservableFlatMap.java:304)
        at io.reactivex.internal.observers.BasicFuseableObserver.onComplete(BasicFuseableObserver.java:119)
        at io.reactivex.internal.operators.mixed.SingleFlatMapObservable$FlatMapObserver.onComplete(SingleFlatMapObservable.java:79)
        at io.reactivex.observers.SerializedObserver.onComplete(SerializedObserver.java:181)
        at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver.drain(ObservableConcatMap.java:200)
        at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver.onComplete(ObservableConcatMap.java:146)
        at io.reactivex.internal.operators.observable.ObservableTake$TakeObserver.onComplete(ObservableTake.java:84)
        at io.reactivex.internal.observers.BasicFuseableObserver.onComplete(BasicFuseableObserver.java:119)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:378)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:327)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.onComplete(ObservableFlatMap.java:590)
        at io.reactivex.internal.operators.mixed.SingleFlatMapObservable$FlatMapObserver.onComplete(SingleFlatMapObservable.java:79)
        at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onComplete(ObservableCreate.java:98)
my code that calls ObservableEmitter.onComplete
NPE in my code as the value is null
        at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:59)
        at io.reactivex.internal.operators.mixed.ObservableConcatMapMaybe$ConcatMapMaybeMainObserver.drain(ObservableConcatMapMaybe.java:256)
        at io.reactivex.internal.operators.mixed.ObservableConcatMapMaybe$ConcatMapMaybeMainObserver.onNext(ObservableConcatMapMaybe.java:124)
        at io.reactivex.observers.SerializedObserver.onNext(SerializedObserver.java:113)
        at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver$InnerObserver.onNext(ObservableConcatMap.java:247)
        at io.reactivex.internal.observers.DeferredScalarDisposable.complete(DeferredScalarDisposable.java:82)
        at io.reactivex.internal.operators.single.SingleToObservable$SingleToObservableObserver.onSuccess(SingleToObservable.java:73)
        at io.reactivex.internal.operators.single.SingleMap$MapSingleObserver.onSuccess(SingleMap.java:64)
        at io.reactivex.internal.operators.single.SingleJust.subscribeActual(SingleJust.java:30)
        at io.reactivex.Single.subscribe(Single.java:3313)
        at io.reactivex.internal.operators.single.SingleMap.subscribeActual(SingleMap.java:34)
        at io.reactivex.Single.subscribe(Single.java:3313)
        at io.reactivex.internal.operators.single.SingleToObservable.subscribeActual(SingleToObservable.java:36)
        at io.reactivex.Observable.subscribe(Observable.java:12036)
        at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver.drain(ObservableConcatMap.java:218)
        at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver.onNext(ObservableConcatMap.java:128)
        at io.reactivex.internal.operators.mixed.SingleFlatMapObservable$FlatMapObserver.onNext(SingleFlatMapObservable.java:69)
        at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onNext(ObservableCreate.java:67)
my code that calls ObservableEmitter.onNext

@akarnokd
Copy link
Member

Is dispose/cancel involved in your flows?

@boris-petrov
Copy link
Author

Well, we do have dispose here and there but they're in completely different places in the code. It IS possible that a dispose could reach this piece of code but... not sure, it is quite complex. I could try removing all dispose calls and checking if that fixes it?

@akarnokd
Copy link
Member

I've identified a race condition which can happen when the flow is getting disposed the same time the Maybe succeeds, resulting in a null item being emitted. It would be great if you could check if there is a dispose/cancel happening in your test as well.

@akarnokd akarnokd added Investigating and removed Missing-Details Could be a question or a bug report, but not enough details are provided. labels Jun 22, 2018
@akarnokd
Copy link
Member

Can you verify the crash is resolved with the latest snapshot (give it an hour and check https://oss.jfrog.org/libs-snapshot/io/reactivex/rxjava2/rxjava/2.2.0-SNAPSHOT/ for binaries for today)?

repositories {
    maven { url 'https://oss.jfrog.org/libs-snapshot' }
}

dependencies {
    compile 'io.reactivex.rxjava2:rxjava:2.2.0-SNAPSHOT'
}

@boris-petrov
Copy link
Author

boris-petrov commented Jun 22, 2018

Sure, I'll try it out, thanks for the quick response, as always! Its funny how I seem to always be catching some horrible edge-case race conditions like this one and the one before it that you've mentioned in the PR. :D

@boris-petrov
Copy link
Author

@akarnokd - I can confirm that 2.2.0-SNAPSHOT of today seemingly fixes the issue (I don't get the exception running our tests).

@akarnokd
Copy link
Member

Great. How urgent is for you to have this fix in a release version (next would be in a month)?

@boris-petrov
Copy link
Author

boris-petrov commented Jun 22, 2018 via email

@akarnokd
Copy link
Member

I'd wait a couple of days as most bugs are reported next to a release.

@vanniktech @artem-zinnatullin @davidmoten would you be fine with 2.1.16 as a patch release next Tuesday?

@vanniktech
Copy link
Collaborator

Sure. Releases are free.

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

Successfully merging a pull request may close this issue.

3 participants