Skip to content

NoSuchFieldException: unsubscribed #3459

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

Closed
yyfrankyy opened this issue Oct 19, 2015 · 20 comments
Closed

NoSuchFieldException: unsubscribed #3459

yyfrankyy opened this issue Oct 19, 2015 · 20 comments
Labels

Comments

@yyfrankyy
Copy link

java.lang.NoSuchFieldException: unsubscribed
java.lang.Class.getDeclaredField(Class.java:929)
java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl.<init>(AtomicIntegerFieldUpdater.java:251)
java.util.concurrent.atomic.AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdater.java:49)
rx.subscriptions.BooleanSubscription.<clinit>(SourceFile:32)
rx.subscriptions.Subscriptions.create(SourceFile:75)
rx.subjects.SubjectSubscriptionManager.addUnsubscriber(SourceFile:68)
rx.subjects.SubjectSubscriptionManager.call(SourceFile:58)
rx.subjects.SubjectSubscriptionManager.call(SourceFile:35)
rx.Observable.subscribe(SourceFile:7803)
rx.Observable.subscribe(SourceFile:7531)

Happened randomly, I cannot reproduce this.

Machine Info

SM-N900;Android 5.0 LRX21V,level 21
@amitcse
Copy link

amitcse commented Oct 19, 2015

I too have seen this issue occurring randomly. In my case it was happening while using HystrixCollapser inside map/flatMap operator. On debugging I found that onCompleted was being called on the observable before onNext. I was not able to isolate if it was due to rx operator or Hystrix.

@yyfrankyy What is scenario in your use-case? Can you share your flow of composition ?

@akarnokd
Copy link
Member

Hi. Do you use ProGuard by any chance? I'm not an expert on it but you might need to change the field retention policy.

@artem-zinnatullin
Copy link
Contributor

ProGuard detects and keeps fields used by AtomicFieldUpdater since v4.6 (release happened 4 years ago), maybe @yyfrankyy uses another code obfuscator?

@yyfrankyy
Copy link
Author

@akarnokd @artem-zinnatullin we do use proguard, but keep all the staff that rx needs by -keep class rx.** { * ; }

@amitcse It crashed at the very beginning since the Application#onCreate(), code is here:

https://github.com/WeTeX/Watchers/blob/master/src/main/java/com/github/QQMail/Watchers.java#L244

And here are some use cases, it works quite well at most of the time.

https://github.com/WeTeX/Watchers/blob/master/src/test/java/com/github/QQMail/WatchersTest.java

I grep all the crashes related to NoSuchFieldException: unsubscribed, all the crashes came from

  • SM-G900I;Android 5.0,level 21
  • SM-G9006V;Android 5.0,level 21

Some of the crashes look like this, from these two devices. they look so similar..

  • GT-I9507V;Android 5.0.1,level 21
  • GT-I9500;Android 5.0.1,level 21
java.lang.NoSuchFieldException: requested
java.lang.Class.getDeclaredField(Class.java:929)
java.util.concurrent.atomic.AtomicLongFieldUpdater$CASUpdater.<init>(AtomicLongFieldUpdater.java:251)
java.util.concurrent.atomic.AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdater.java:50)
rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.<clinit>(SourceFile:86)
rx.internal.operators.OperatorObserveOn.rx.Subscriber call(rx.Subscriber)(SourceFile:64)
rx.internal.operators.OperatorObserveOn.java.lang.Object call(java.lang.Object)(SourceFile:44)

@artem-zinnatullin
Copy link
Contributor

IDK, but I see 2 possible reasons:

  1. Samsung: probably, they've patched the Runtime (they like to change everything in Android) and it tries to minify fields names for less memory usage (though I don't think that they're really doing such things, but, who knows).
  2. ProGuard rules problem or ProGuard bug or Android Gradle Plugin bug when you're doing non-clean builds (though it'll break app on other devices too).

@yyfrankyy can you please wrap the subscribe() call into try-catch and then collect info about the fields of the BooleanSubscription class, it'll help us detect the problem.

try {
  obs.subscribe(...);
} catch (NoSuchFieldException e) {
  // collect info about fields of the BooleanSubscription class
  BooleanSubscription.class.getDeclaredFields(); // include it into the crash report
}

Also, recently I've shipped ProGuard rules for RxJava as aar https://github.com/artem-zinnatullin/RxJavaProGuardRules, you can try to use them instead of yours.

@ppiech
Copy link

ppiech commented Oct 20, 2015

It's definitely not pro-guard, since the decompiled class code looks correct. I can also try to capture the fields in the class (thank you for the suggestion), but since I haven't reproduced the issue myself it'll take a week before I have that data. In the mean time, I think I'll just replace Atomic_FieldUpdater with Atomic_ objects, since I confirmed that it works.

@yyfrankyy
Copy link
Author

@artem-zinnatullin Sure, we can do this on our next release next month, will come back later.

@plastec
Copy link

plastec commented Oct 27, 2015

Hi,
I have the same issues. All only on Samsung devices with Android 5

1:
....
Caused by java.lang.NoSuchFieldException: producerIndex
at java.lang.Class.getDeclaredField(Class.java)
at rx.internal.util.unsafe.UnsafeAccess.addressOf(SourceFile)
at rx.internal.util.unsafe.SpmcArrayQueueProducerField.(SourceFile)
at rx.internal.util.RxRingBuffer$2.createObject(SourceFile)
at rx.internal.util.ObjectPool.borrowObject(SourceFile)
at rx.internal.util.RxRingBuffer.(SourceFile)
at rx.internal.util.RxRingBuffer.getSpmcInstance(SourceFile)
at rx.internal.operators.OnSubscribeCombineLatest$MultiSourceProducer.(SourceFile)
at rx.internal.operators.OnSubscribeCombineLatest.call(SourceFile)
at rx.Observable.unsafeSubscribe(SourceFile)
at rx.internal.operators.OperatorSubscribeOn$1$1.call(SourceFile)
at rx.internal.schedulers.ScheduledAction.run(SourceFile)
at rx.schedulers.ExecutorScheduler$ExecutorSchedulerWorker.run(SourceFile)
...

2:
...
Caused by java.lang.NoSuchFieldException: do
at java.lang.Class.getDeclaredField(Class.java)
at java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl.(AtomicIntegerFieldUpdater.java)
at java.util.concurrent.atomic.AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdater.java)
at rx.subscriptions.BooleanSubscription.(SourceFile)
at rx.subscriptions.Subscriptions.create(SourceFile)
at rx.subjects.SubjectSubscriptionManager.addUnsubscriber(SourceFile)
at rx.Observable.subscribe(SourceFile)
at rx.Observable.subscribe(SourceFile)
...

3:
...
Caused by java.lang.NoSuchFieldException: this
at java.lang.Class.getDeclaredField(Class.java)
at java.util.concurrent.atomic.AtomicLongFieldUpdater$CASUpdater.(AtomicLongFieldUpdater.java)
at java.util.concurrent.atomic.AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdater.java)
at rx.internal.operators.OnSubscribeCombineLatest$MultiSourceProducer.(SourceFile)
at rx.internal.operators.OnSubscribeCombineLatest.call(SourceFile)
at rx.Observable.unsafeSubscribe(SourceFile)
at rx.internal.operators.OperatorSubscribeOn$1$1.call(SourceFile)
at rx.internal.schedulers.ScheduledAction.run(SourceFile)
at rx.schedulers.ExecutorScheduler$ExecutorSchedulerWorker.run(SourceFile)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java)
at java.lang.Thread.run(Thread.java)

4:
...
Caused by java.lang.NoSuchFieldException: do
at java.lang.Class.getDeclaredField(Class.java)
at java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl.(AtomicIntegerFieldUpdater.java)
at java.util.concurrent.atomic.AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdater.java)
at rx.schedulers.CachedThreadScheduler$EventLoopWorker.(SourceFile)
at rx.schedulers.CachedThreadScheduler.createWorker(SourceFile)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.(SourceFile)
at rx.internal.operators.OperatorObserveOn.call(SourceFile)
at rx.Observable$2.call(SourceFile)
at rx.Observable.subscribe(SourceFile)
at rx.Observable.subscribe(SourceFile)
...

5:
...
Caused by java.lang.NoSuchFieldException: case
at java.lang.Class.getDeclaredField(Class.java)
at java.util.concurrent.atomic.AtomicLongFieldUpdater$CASUpdater.(AtomicLongFieldUpdater.java)
at java.util.concurrent.atomic.AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdater.java)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.(SourceFile)
at rx.internal.operators.OperatorObserveOn.call(SourceFile)
at rx.Observable$2.call(SourceFile)
at rx.Observable.subscribe(SourceFile)
at rx.Observable.subscribe(SourceFile)
....

Looks like Samsung introduce some specific problem on Android 5.

Do you plan to apply a workaround for that?

markrietveld added a commit to markrietveld/RxJava that referenced this issue Nov 3, 2015
Replace them all with their respective Atomic* counterparts
For example AtomicLongFieldUpdater -> AtomicLong
Addresses ReactiveX#3459
markrietveld added a commit to markrietveld/RxJava that referenced this issue Nov 3, 2015
Replace them all with their respective Atomic* counterparts
For example AtomicLongFieldUpdater -> AtomicLong
Addresses ReactiveX#3459
markrietveld added a commit to markrietveld/RxJava that referenced this issue Nov 3, 2015
Replace them all with their respective Atomic* counterparts
For example AtomicLongFieldUpdater -> AtomicLong
Addresses ReactiveX#3459
@digitalbuddha
Copy link

1000+ crashes past few days in New York Times app. Hoping for @markrietveld fix to be merged soon. We are reaching out to Samsung as well to find out exactly what happened on their end.

Package: com.nytimes.android
Version Code: 9486
Version Name: 5.9.2
Android: 5.0.2
Manufacturer: samsung
Model: SM-T805Y
Date: Mon Oct 26 06:31:34 AEDT 2015

java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
    at rx.internal.schedulers.ScheduledAction.run(SourceFile:62)
    at rx.schedulers.ExecutorScheduler$ExecutorSchedulerWorker.run(SourceFile:98)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.ExceptionInInitializerError
    at rx.internal.operators.OperatorZip.call(SourceFile:113)
    at rx.internal.operators.OperatorZip.call(SourceFile:58)
    at rx.Observable$2.call(SourceFile:158)
    at rx.Observable$2.call(SourceFile:154)
    at rx.Observable.subscribe(SourceFile:7804)
    at rx.Observable.subscribe(SourceFile:7772)
    at com.nytimes.android.notification.DailyRichNotificationHelper.displayDailyRichNotification(SourceFile:108)
    at com.nytimes.android.notification.DailyRichNotificationHelper.displayDailyRichNotification(SourceFile:99)
    at com.nytimes.android.notification.DailyRichNotificationHelper$1.call(SourceFile:86)
    at com.nytimes.android.notification.DailyRichNotificationHelper$1.call(SourceFile:83)
    at rx.Observable$28.onNext(SourceFile:7588)
    at rx.observers.SafeSubscriber.onNext(SourceFile:130)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.emitScalar(SourceFile:364)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.tryEmit(SourceFile:326)
    at rx.internal.operators.OperatorMerge$InnerSubscriber.onNext(SourceFile:802)
    at rx.internal.operators.OperatorDoOnEach$1.onNext(SourceFile:84)
    at rx.subjects.SubjectSubscriptionManager$SubjectObserver.onNext(SourceFile:224)
    at rx.internal.operators.NotificationLite.accept(SourceFile:150)
    at rx.subjects.ReplaySubject$UnboundedReplayState.accept(SourceFile:466)
    at rx.subjects.ReplaySubject$UnboundedReplayState.replayObserverFromIndex(SourceFile:515)
    at rx.subjects.ReplaySubject$UnboundedReplayState.replayObserver(SourceFile:503)
    at rx.subjects.ReplaySubject.caughtUp(SourceFile:423)
    at rx.subjects.ReplaySubject.onNext(SourceFile:369)
    at rx.Observable$30.onNext(SourceFile:7681)
    at rx.observers.SafeSubscriber.onNext(SourceFile:130)
    at rx.internal.operators.OperatorDoOnEach$1.onNext(SourceFile:84)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.emitScalar(SourceFile:364)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.tryEmit(SourceFile:326)
    at rx.internal.operators.OperatorMerge$InnerSubscriber.onNext(SourceFile:802)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.emitScalar(SourceFile:364)
    at rx.internal.operators.OperatorMerge$MergeSubscriber.tryEmit(SourceFile:326)
    at rx.internal.operators.OperatorMerge$InnerSubscriber.onNext(SourceFile:802)
    at rx.subjects.SubjectSubscriptionManager$SubjectObserver.onNext(SourceFile:224)
    at rx.subjects.AsyncSubject.onCompleted(SourceFile:101)
    at rx.util.async.Async$1$1.call(SourceFile:533)
    at rx.internal.schedulers.ScheduledAction.run(SourceFile:55)
    ... 4 more
Caused by: java.lang.RuntimeException: java.lang.NoSuchFieldException: counter
    at java.util.concurrent.atomic.AtomicLongFieldUpdater$CASUpdater.<init>(AtomicLongFieldUpdater.java:269)
    at java.util.concurrent.atomic.AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdater.java:50)
    at rx.internal.operators.OperatorZip$Zip.<clinit>(SourceFile:187)
    ... 40 more
Caused by: java.lang.NoSuchFieldException: counter
    at java.lang.Class.getDeclaredField(Class.java:929)
    at java.util.concurrent.atomic.AtomicLongFieldUpdater$CASUpdater.<init>(AtomicLongFieldUpdater.java:251)
    ... 42 more

markrietveld added a commit to markrietveld/RxJava that referenced this issue Nov 11, 2015
Replace them all with their respective Atomic* counterparts
For example AtomicLongFieldUpdater -> AtomicLong
Addresses ReactiveX#3459
@akarnokd
Copy link
Member

akarnokd commented Feb 9, 2016

Fix delivered, all AtomicXFieldUpdater changed to AtomicX classes.

@akarnokd akarnokd closed this as completed Feb 9, 2016
@roccozanni
Copy link

Hi,
there is still a reference to AtomicIntegerFieldUpdater here:

https://github.com/ReactiveX/RxJava/blob/1.x/src/main/java/rx/schedulers/CachedThreadScheduler.java#L180

Any chance to have it fixed in the 1.x branch?

Thanks,
Rocco

@akarnokd
Copy link
Member

akarnokd commented Mar 7, 2016

@roccozanni Would you be interested in fixing it?

@roccozanni
Copy link

@akarnokd I can definitely give it a try.

I forked the project and imported into Eclipse, but I have some troubles with the unit tests, because there are some failures and I'm not so confident in doing changes without the help of a robust existing test suites. I use RxJava since a while but I'm definitely not into the internals.

Not sure if it's something misconfigured on my side (I followed the instructions in the "How to contribute" wiki page), but I can send you the JUnit xml output if needed. Can you please verify if the 1.x branch tests are working on your side?

@akarnokd
Copy link
Member

akarnokd commented Mar 7, 2016

We have CI associated with the project and all the current tests pass both locally and on Travis. After you imported the project, go to the Eclipse preferences, look for Compiler warnings and set the restricted access to ignore. You should also install the Gradle IDE plugin to make sure all test dependencies are wired up properly.

@mateherber
Copy link

Same android samsung 5.0.X appeared for us with the latest 1.1.2

Caused by java.lang.NoSuchFieldException: producerIndex
at java.lang.Class.getDeclaredField(Class.java:929)
at rx.internal.util.unsafe.UnsafeAccess.addressOf(UnsafeAccess.java:100)
at rx.internal.util.unsafe.SpmcArrayQueueProducerField.(SpmcArrayQueue.java:31)
at rx.internal.util.RxRingBuffer$2.createObject(RxRingBuffer.java:294)
at rx.internal.util.RxRingBuffer$2.createObject(RxRingBuffer.java:290)
at rx.internal.util.ObjectPool.borrowObject(ObjectPool.java:74)
at rx.internal.util.RxRingBuffer.(RxRingBuffer.java:307)
at rx.internal.util.RxRingBuffer.getSpmcInstance(RxRingBuffer.java:45)
at rx.internal.operators.OperatorZip$Zip$InnerSubscriber.(OperatorZip.java:305)
at rx.internal.operators.OperatorZip$Zip.start(OperatorZip.java:205)
at rx.internal.operators.OperatorZip$ZipSubscriber.onNext(OperatorZip.java:156)
at rx.internal.operators.OperatorZip$ZipSubscriber.onNext(OperatorZip.java:122)
...

@akarnokd
Copy link
Member

akarnokd commented Apr 4, 2016

So those Android devices have Unsafe?

I wonder if the addressOf might be triggering the bug in the runtime by hiding the getDeclaredField call.

@mateherber
Copy link

I was thinking that too but I've checked and the implementation has not changed recently and we started seeing the errors just with the latest version. Pretty weird stuff...

@akarnokd
Copy link
Member

akarnokd commented Apr 4, 2016

If you could play with a manual build, inlining the addressOf in rx.internal.util.unsafe.SpmcArrayQueueProducerField and rx.internal.util.unsafe.SpmcArrayQueueConsumerField could rule out that sort of bug.

In the meantime, I'll try to have a System property driven way of disabling Unsafe use in a PR.

tejasgarde pushed a commit to tejasgarde/RxJava that referenced this issue Apr 4, 2016
Replace them all with their respective Atomic* counterparts
For example AtomicLongFieldUpdater -> AtomicLong
Addresses ReactiveX#3459
@lucas34
Copy link

lucas34 commented Jun 1, 2016

I'm still having this following issue

java.lang.IllegalArgumentException: Must be integer type

at java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl.<init>(AtomicIntegerFieldUpdater.java:275)
at java.util.concurrent.atomic.AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdater.java:49)
at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker

Should we replace the AtomicIntegerFieldUpdater on the class CachedThreadScheduler as well ?

@akarnokd
Copy link
Member

akarnokd commented Jun 1, 2016

See #3979.

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

No branches or pull requests

10 participants