objectbox / objectbox/objectbox-java

io.objectbox.exception.FileCorruptException: Could not get from cursor (corrupted) (error code -30796)

Open
#926 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Java
Stars
4.6k
Forks
311
PR merge metrics
No merged PRs in 30d

Description

In my Pre-launch report details I see continuously crashes on Android 8.1 phones. I cannot reproduce it on a Emulator with SDK 27. Stacktrace error (see for log details below): io.objectbox.exception.FileCorruptException: Could not get from cursor (corrupted) (error code -30796)

Is this a issue with pre-launch testing or might this occur on real devices as well? After searching I found multiple issues with Android 8.1. Any clue?

I'm using a read-only box from a fragment (write box is in a remote service).

  • ObjectBox version 2.8.0 (but also on 2.7.1)
  • Reproducibility: always on Android 8.1 devices for pre-launch report
  • Device: e.g. Motorola moto e5 play and Nokia Nokia 1
  • OS: Android 8.1

Code
Initialization done in MainActivity class after being connected to Service (remote process). The method initMainActivity is called.

protected void initMainActivity() {
        if (!mInitMainActivity) {
            JepsterManager jepsterManager = (JepsterManager) getApplication();
            jepsterManager.initReadOnlyBox();
            //Check if version is updated and update information has to be shown
            JepsterVersionUtilities.checkVersion(this, mService, mPreferences);
            //Check version to verify if preference migration is needed
            PrefsMigrationUtilities.checkVersion(this, mPreferences);

            setNavigationHeader();

            mInitMainActivity = true;

            //ObjectBox need to be available, JepsterService has to be started first to be able to update schema of Box.
            if (mOnPostResume){
                selectDrawerItem(mMenuItemId);
            }
        }
    }
public class ObjectBox {
    private static BoxStore boxStore;
    private static int messageId = 0;

    public static void init(Context context) {
        if (boxStore == null) {
            boxStore = MyObjectBox.builder()
                    .androidContext(context.getApplicationContext())
                    .androidReLinker(ReLinker.log(new ReLinker.Logger() {
                        @Override
                        public void log(String message) {
                            Log.d(Constants.TAG, message);
                        }
                    }))
                    .build();

            if (BuildConfig.DEBUG) {
                boolean started = new AndroidObjectBrowser(boxStore).start(context);
            }
        }
    }

    public static void initReadOnly(Context context) {
        if (boxStore == null) {
            boxStore = MyObjectBox.builder()
                    .androidContext(context.getApplicationContext())
                    .androidReLinker(ReLinker.log(new ReLinker.Logger() {
                        @Override
                        public void log(String message) {
                            Log.d(Constants.TAG, message);
                        }
                    }))
                    .readOnly()
                    .build();

            if (BuildConfig.DEBUG) {
                boolean started = new AndroidObjectBrowser(boxStore).start(context);
            }
        }
    }

    public static BoxStore get() {
        return boxStore;
    }


    public static int getMessageId(){
        messageId ++;
        return messageId;
    }
}
public int getDataFieldValue(int bike, int page, int dataField){
        Box<BikeDataFieldEntity> bikeDataFieldBox = getBikeDataFieldBox();

        //Search data field ID
        QueryBuilder<BikeDataFieldEntity> builder = bikeDataFieldBox.query();
        builder.equal(BikeDataFieldEntity_.bike, bike)
                .equal(BikeDataFieldEntity_.page, page)
                .equal(BikeDataFieldEntity_.dataField, dataField);
        Query<BikeDataFieldEntity> query = builder.build();
        BikeDataFieldEntity bikeDataField = query.findFirst(); (**Line 321**)

        return bikeDataField.getDataFieldValue();
    }
public Box<BikeDataFieldEntity> getBikeDataFieldBox(){
        if (mBikeDataFieldBox == null){
            mBikeDataFieldBox = ObjectBox.get().boxFor(BikeDataFieldEntity.class);
        }
        return mBikeDataFieldBox;
    }

Logs, stack traces

io.objectbox.exception.FileCorruptException: Could not get from cursor (corrupted) (error code -30796)
	at io.objectbox.query.Query.nativeFindFirst(Native Method)
	at io.objectbox.query.Query.lambda$findFirst$0$Query(Query.java:153)
	at io.objectbox.query.-$$Lambda$Query$U3Pw2NlOHcqDE3imeFDwfgwkeJw.call(Unknown Source:2)
	at io.objectbox.BoxStore.callInReadTx(BoxStore.java:813)
	at io.objectbox.BoxStore.callInReadTxWithRetry(BoxStore.java:759)
	at io.objectbox.query.Query.callInReadTx(Query.java:275)
	at io.objectbox.query.Query.findFirst(Query.java:151)
	at com.twom.bico.pages.FragmentPageDataFields.getDataFieldValue(FragmentPageDataFields.java:321)
	at com.twom.bico.pages.FragmentPageDataFields.initViews(FragmentPageDataFields.java:111)
	at com.twom.bico.pages.FragmentPage9DataFields.onCreateView(FragmentPage9DataFields.java:31)
	at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
	at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
	at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
	at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
	at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
	at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
	at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2169)
	at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1992)
	at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
	at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1818)
	at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:303)
	at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:270)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the stack trace at FragmentPageDataFields.java line 321 and compare the read-only initialization in ObjectBox.initReadOnly with the remote service setup. Reproduce the query on Android 8.1 devices or the pre-launch environment using the provided device details and logs. Done means establishing whether the corruption is limited to pre-launch testing or can occur on real devices, with a documented cause or next diagnostic step.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java
Domain
database, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.