realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.45k stars 1.75k forks source link

At times, Realm proxy objects stop providing their data #7840

Closed mannodermaus closed 7 months ago

mannodermaus commented 10 months ago

How frequently does the bug occur?

Sometimes

Description

I apologize for the flaky description, but I haven't been able to get a firm grasp on the situation yet.

Essentially, ever since a few weeks ago, our Android development environment sometimes reaches a state wherein proxy objects returned from Realm queries stop returning their data to the caller, causing weird behaviors to emerge throughout the app that feel like bugs on our end, but aren't. The toString() representation of the proxy objects include all the data, but when reading any of the properties off the proxy, type-dependent empty data (e.g. 0 or "") is returned. Attached is a screenshot of the debugger output – despite the partial obfuscation, the discrepancy between the top line and the properties should be visible.

Screenshot 2023-08-10 at 15 41 32

When this state happens, clearing the build folder of the affected Gradle module and rebuilding from a clean slate resolves the problem for a while. This causes me to think that it is related to incremental builds, but I'm not sure. In the compilation right before the issue happens, we see the transformer's logs like normal, so it doesn't seem like anything is skipped there.

Another note is that the project is also using AGP 8+ and Gradle 8+, so maybe there is some form of missing support here still? 🤔

Any insight is appreciated!

[!NOTE] Since turning off incremental compilation via io.realm.disableIncrementalBuilds = true, I haven't seen the issue creep up again. I will let y'all know if this changes, however.

Stacktrace & log output

No response

Can you reproduce the bug?

No

Reproduction Steps

No response

Version

10.16.1

What Atlas App Services are you using?

Local Database only

Are you using encryption?

No

Platform OS and version(s)

macOS Ventura 13.4

Build environment

Android Studio version: 2023.1.1 Canary 15 (Build #AI-231.9225.16.2311.10572941, built on July 28, 2023) Android Build Tools version: 34.0.0 Android Gradle Plugin version: 8.1.0 Gradle version: 8.2.1

fanwgwg commented 10 months ago

+1 We've encountered the same situation since roughly a few weeks ago, sometimes it would randomly stop providing data, all filed accessors will return a default value like 0 or null even if the data exists. This only happens in development but not in production, it typically happens after several rounds of rebuild of the project.

cmelchior commented 10 months ago

Hmm, this looks odd. So the debugger output is totally expected. You can see this link for more details: https://www.mongodb.com/docs/realm/sdk/java/test-and-debug/debugging/#android-studio-debugging

Sporadic behavior could point to some problems with incremental compilation that might change the accessors. But it is unclear exactly what could be going on.

You are saying this is happening on AGP8+ with Gradle 8+, which would make sense since Googles Transform APIs changed there, but are you using any other plugins that might modify code? Like Compose, Dagger, etc.?

fanwgwg commented 10 months ago

For us this happens only after upgrading to AGP8+. Our setup includes Hilt/Dagger for DI.

I tried debugging too similar to what @mannodermaus does, I understand that the debugger output is expected because realm only accesses the field lazily, the weird thing is that when actually accessing the field itself, it's always 0/null/empty string.

mannodermaus commented 10 months ago

@cmelchior The project does use Compose, but it has done so for a fairly long time without triggering this behavior in the past. Furthermore, we use Moshi code generation via KSP, but that's about it - Dagger is not in use, and neither are there any bytecode manipulation tools (other than Realm, of course).

tekeroth-snapcode commented 10 months ago

Same issue for me, just detected it; the RealmProxy object shows all values as "default", so null, 0, except for List<>, that contains the objects expected, but also the objects in the lists as "defaulted" everywhere.

rafiqlightwala commented 10 months ago

Can confirm I faced this exact issue today. Same as all the participants described. gradle 8. and not just debugging, the received properties are null. not using compose.

mannodermaus commented 10 months ago

Here are some new observations from my side. When this state is reached, the odd behavior of Realm proxies is not limited to read operations. I have seen that if a new element is inserted into a Realm, a new record is inserted into its table, but all the properties are empty.

~Furthermore, I have played around with the build settings of our project and found that we are using the Android Cache Fix plugin for Gradle. I've turned that off and haven't seen the issue reappear in a few days. It might be coincidence, but do other commenters here use that same plugin? I'm wondering if it interferes with Realm's incremental bytecode manipulation when using AGP 8 or Gradle 8, so if you do use it, try turning it off for a while and give it another go.~ Never mind, it happened again. ☹️

chk2902 commented 8 months ago

Same here. Cleaning or Rebuilding the project helps for a while, but the problem reappears here after a couple of compilations. Objects not added to the database, default values read from RealmObjects... took me hours to make sure my code was not wrong.

I see it was fixed, but the realm grade plugin I use is still the 10.16.1?

clementetb commented 8 months ago

@chk2902 The issue was fixed in version 10.16.2. Please update the Realm Gradle plugin to apply the fix.