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

ArrayIndexOutOfBoundsException: rowIndex is less than 0 #2408

Closed
Sutirth opened this issue Mar 10, 2016 · 26 comments
Closed

ArrayIndexOutOfBoundsException: rowIndex is less than 0 #2408

Sutirth opened this issue Mar 10, 2016 · 26 comments
Assignees

Comments

@Sutirth
Copy link

Sutirth commented Mar 10, 2016

Goal (what do you want to achieve?)

I am changing status of a field in realm table continuously

Expected Results

The status should change in the database

Actual Results (e.g. full stack trace with exception)

03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime: FATAL EXCEPTION: main
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime: Process: com.workoutguru.workoutcash, PID: 28586
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime: java.lang.ArrayIndexOutOfBoundsException: rowIndex is less than 0.
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at io.realm.internal.TableView.nativeGetSourceRowIndex(Native Method)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at io.realm.internal.TableView.getSourceRowIndex(TableView.java:158)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at io.realm.RealmResults.get(RealmResults.java:174)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at com.workoutguru.workoutcash.CompanyGoals_AllGoals_Fragment$CompanyAllGoalsAdapter$CompanyAllGoalsAdapterViewHolder$1$1.onResponse(CompanyGoals_AllGoals_Fragment.java:668)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at retrofit.ExecutorCallAdapterFactory$ExecutorCallback$1.run(ExecutorCallAdapterFactory.java:86)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5343)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
03-10 17:27:50.122 28586-28586/com.workoutguru.workoutcash E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

Version of Realm and tooling

Realm version(s): compile 'io.realm:realm-android:0.87.5'

Android Studio version: android 1.4

Android version(s) on device/simulator: Device version 5.1,API:22

@kneth
Copy link
Contributor

kneth commented Mar 10, 2016

It looks like you are trying to change the value of a non-existing object. The object you are changing is found in a RealmResults, right? Do you execute the query (findAll()) outside the transaction? Is your Realm updated in another thread?

@Sutirth
Copy link
Author

Sutirth commented Mar 10, 2016

I am executing query findfirst() in async transaction and calling notifyDataSetChanged in recyclerView

@jjhesk
Copy link

jjhesk commented Mar 15, 2016

+1

@beeender
Copy link
Contributor

@Sutirth Can you set a breakpoint at CompanyGoals_AllGoals_Fragment.java:668 to see what is the index when crash happens?

@Sutirth
Copy link
Author

Sutirth commented Mar 15, 2016

@beeender It happens sometime or the other not a frequent breakdown. Though I have debugged this issue for long hours and after doing everything it crashes here

AllGoalsDB unsubscribeGoalResult = realm.where(AllGoalsDB.class)
                                            .equalTo(WorkoutCashConstants.COLUMN_GOALID, allGoalsResults.get(getAdapterPosition()).getGoalID())
                                            .findFirst();

So I have made few observation and this would be according to my theory please correct me if I am wrong. Suppose I say a user is on 2g network and for example he click subscribe(This is the time when I hit my api call and onSuccess I change the status in my realm database). And suppose there is a brief lag period and I click on subscribe again it crashes because its status is already changed in the database and hence I get row Index as 0.

Would request you to keep this issue open Because I am debugging this issue continuously

P.S I live in India and hence we do a rigorous testing on spectrum.

@beeender
Copy link
Contributor

The changes in another thread will reflect to the current thread's Realm instance in the "next" event loop. So if you are tracking some Realm data status, like the RealmResults's size by your own var, it is very important to refresh them when Realm changes. The suggestion is make your data in each thread's stateless, whatever the data changes, just read the Realm, get the latest data.

@Sutirth
Copy link
Author

Sutirth commented Mar 15, 2016

@beeender Exactly I am doing the same thing say for e.g if I am doing some changes in Recycler view I notify the adapter when its successful but this still I am end getting error.

@bmunkholm bmunkholm changed the title Realm Crashes Unexpectedly ArrayIndexOutOfBoundsException: rowIndex is less than 0 Mar 15, 2016
@dalinaum
Copy link
Contributor

This issue is reported by VCNC too. See its CrashLytics too: http://crashes.to/s/957c6014d94

@Sutirth
Copy link
Author

Sutirth commented Mar 22, 2016

@beeender Closed Already without solution?? :(

@beeender
Copy link
Contributor

Oppos, I thought this is solved. Since we cannot reproduce this from our side can you please reproduce this issue will a minimal Android Studio project and share with us so we can do some investigation on it? to help@realm.io
Thanks!

@atouchsh
Copy link

has the same issue occurred some times, when the the adapter being updated and the user click before or while the adapter is being updated,
i use the following solution when the user clicks on an item

try {
     list.get(getAdapterPosition());
} catch (Exception ignored) {
     return;
}

@KynoYang
Copy link

I have the same issue, but it may be because I remove data from Realm in another thread. Do all the transactions in the same thread is not possible for me. Any suggestion?

@beeender
Copy link
Contributor

@KynoYang Can you share some related code with us? to help@realm.io if you want to share it privately.

@KynoYang
Copy link

Sure. I'll try to make a demo to reproduce it.

@beeender
Copy link
Contributor

@KynoYang A demo project to reproduce it would be the best!!! Thanks a lot!

@KynoYang
Copy link

@beeender Unfortunately, I failed to reproduce it in the demo. It seems no relation with multiple threads. But I indeed received several crash reports from users. I'll add some log in my app to figure out what's the problem. BTW, one of my users sent me a video about this bug. I guess it's because the change listener in RealmExpandableListAdapter (not sure RealmBaseAdapter has the same problem) doesn't work at that time in some unknown reason.

@beeender
Copy link
Contributor

Reopen this issue. I am checking with @KynoYang about this.

@cmelchior
Copy link
Contributor

@beeender Did you have a chance to look into this?

@beeender
Copy link
Contributor

beeender commented May 4, 2016

Yes, but we have no luck to reproduce it :(

@beeender
Copy link
Contributor

beeender commented May 9, 2016

#2753 is reporting the similar issue, i will try to reproduce it with clues from there.

beeender added a commit that referenced this issue Jun 2, 2016
Close #2408

RealmResults are synced when calling its listener, since we need to
check the table version before calling the listener. So sync it just
after advance read won't be an option - in that way, the result's
listener won't be triggered.

So we notify the global listeners as the last thing to do, at that
point, result will be synced already.

Also a test case is added to ensure the calling sequence of synced
listeners.
@beeender beeender self-assigned this Jun 2, 2016
beeender added a commit that referenced this issue Jun 2, 2016
Close #2408

RealmResults are synced when calling its listener, since we need to
check the table version before calling the listener. So sync it just
after advance read won't be an option - in that way, the result's
listener won't be triggered.

So we notify the global listeners as the last thing to do, at that
point, result will be synced already.

Also a test case is added to ensure the calling sequence of synced
listeners.
beeender added a commit that referenced this issue Jun 3, 2016
Close #2408

RealmResults are synced when calling its listener, since we need to
check the table version before calling the listener. So sync it just
after advance read won't be an option - in that way, the result's
listener won't be triggered.

So we notify the global listeners as the last thing to do, at that
point, result will be synced already.

Also a test case is added to ensure the calling sequence of synced
listeners.
@beeender beeender closed this as completed Jun 3, 2016
@Mohsin92
Copy link

java.lang.ArrayIndexOutOfBoundsException: rowIndex > available rows: 1 > 1 at io.realm.internal.TableView.nativeGetSourceRowIndex(Native Method) at io.realm.internal.TableView.getSourceRowIndex(TableView.java:119) at io.realm.RealmResults.get(RealmResults.java:215) at com.varshaaweblabs.estateblock.HomeScreen.HomeScreenactivity$4$1.execute(HomeScreenactivity.java:532) at io.realm.Realm.executeTransaction(Realm.java:1301) at com.varshaaweblabs.estateblock.HomeScreen.HomeScreenactivity$4.onResponse(HomeScreenactivity.java:484) at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68) at android.os.Handler.handleCallback(Handler.java:725) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:153) at android.app.ActivityThread.main(ActivityThread.java:5299) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) at dalvik.system.NativeStart.main(Native Method)

@kneth
Copy link
Contributor

kneth commented Mar 16, 2017

@Mohsin92 can you provide a bit of background info (Realm version, etc.) and context (when do you see exception, Realm configuration, etc.).

@Zhuinden
Copy link
Contributor

@Mohsin92 execute your query inside the Realm transaction

@Mohsin92
Copy link

@kneth : Realm 2.3.0
Context:
When I tried to update in database its shows me errors.

` try { // I could use try-with-resources here
realm = Realm.getDefaultInstance();
realm.executeTransaction(new Realm.Transaction() {
@OverRide
public void execute(Realm realm) {

                            RealmResults<Favourite_List_DB> favourite_list_dbs = realm.where(Favourite_List_DB.class).findAll();
                            if (favourite_list_dbs.size() < 1) {
                                Log.e("Databae is empty: ", "Empty DB");
                            } else {
                                Log.e("DB List Before size: ", String.valueOf(favourite_list_dbs.size()));
                                for (int i = 0; i < favourite_listing_subs.size(); i++) {
                                    for (int j = 0; j < favourite_listing_subs.get(i).getResult().getListing().size(); j++) {
                                        if (favourite_listing_subs.get(i).getResult().getListing().get(j).getListingKey().equalsIgnoreCase(favourite_list_dbs.get(i).getListing_key())) {
                                            if (!favourite_listing_subs.get(i).getResult().getListing().isManaged()) {
                                                for (Favourite_listing_sub favourite_list_db : favourite_listing_subs) {
                                                    if (favourite_list_db.getResult().getListing().isManaged()) {
                                                        managedImageList.add(favourite_list_db);
                                                        Log.e("Favourite: ", "Now it manage.");
                                                    } else {
                                                        managedImageList.add(realm.copyToRealm(favourite_list_db));
                                                    }
                                                }
                                                //  favourite_listing_subs.addAll(managedImageList);
                                                favourite_list_dbs.get(j).setListing(managedImageList.get(i).getResult().getListing().get(j));
                                                favourite_list_dbs.get(j).setListing_key(managedImageList.get(i).getResult().getListing().get(j).getListingKey());
                                                favourite_list_dbs.get(j).setUpdate_date(retdate());
                                                favourite_list_dbs.get(j).setCreate_date(retdate());
                                                realm.copyToRealmOrUpdate(favourite_list_dbs);
                                                Log.e("DB List after size: ", String.valueOf(favourite_list_dbs.size()));
                                            } else {
                                                favourite_list_dbs.get(j).setListing(managedImageList.get(i).getResult().getListing().get(j));
                                                favourite_list_dbs.get(j).setListing_key(managedImageList.get(i).getResult().getListing().get(j).getListingKey());
                                                favourite_list_dbs.get(j).setUpdate_date(retdate());
                                                favourite_list_dbs.get(j).setCreate_date(retdate());
                                                realm.copyToRealmOrUpdate(favourite_list_dbs);
                                            }
                                        } else {
                                            if (!favourite_listing_subs.get(i).getResult().getListing().isManaged()) {
                                                for (Favourite_listing_sub favourite_list_db : favourite_listing_subs) {
                                                    if (favourite_list_db.getResult().getListing().isManaged()) {
                                                        managedImageList.add(favourite_list_db);
                                                        Log.e("Favourite: ", "Now it manage.");
                                                    } else {
                                                        managedImageList.add(realm.copyToRealm(favourite_list_db));
                                                    }
                                                }
                                                //   favourite_listing_subs.addAll(managedImageList);
                                                //  favourite_listing_subs.addAll(managedImageList);

                                                favourite_list_dbs.get(j).setListing(managedImageList.get(j).getResult().getListing().get(j));
                                                // favourite_list_dbs.get(i).setListing_key(managedImageList.get(j).getResult().getListing().get(j).getListingKey());
                                                favourite_list_dbs.get(j).setUpdate_date(retdate());
                                                favourite_list_dbs.get(j).setCreate_date(retdate());
                                                realm.insert(favourite_list_dbs);
                                                Log.e("DB List after size: ", String.valueOf(favourite_list_dbs.size()));
                                            } else {
                                                favourite_list_dbs.get(j).setListing(managedImageList.get(j).getResult().getListing().get(j));
                                                //  favourite_list_dbs.get(j).setListing_key(managedImageList.get(j).getResult().getListing().get(j).getListingKey());
                                                favourite_list_dbs.get(j).setUpdate_date(retdate());
                                                favourite_list_dbs.get(j).setCreate_date(retdate());
                                                realm.insert(favourite_list_dbs);
                                            }
                                        }
                                    }
                                }
                                realm.insertOrUpdate(favourite_listing_subs);
                            }
                        }
                    });
                } finally {
                    if (realm != null) {
                        realm.close();
                    }
                }`

@Mohsin92
Copy link

@Zhuinden : yes I tried same you can find in above code.

@Zhuinden
Copy link
Contributor

Zhuinden commented Mar 16, 2017

@Mohsin92

for (int j = 0; j < favourite_listing_subs.get(i).getResult().getListing().size(); j++) {


apparently favourite_listing_subs.get(i).getResult().getListing().size() != favourite_list_dbs.size()

so the error is in your code, in that line

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests