realm-java icon indicating copy to clipboard operation
realm-java copied to clipboard

Encrypted interprocess sharing is currently unsupported.DB has been opened by pid: 24356. Current pid is 24516.

Open Ndrocchietto opened this issue 3 years ago • 9 comments

How frequently does the bug occur?

All the time

Description

When try to open the app the initial splash screen crashes, when the db is initialised

Stacktrace & log output

Fatal Exception: java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.myapp.android.app/com.ex.myapp.android.activity.SplashScreenActivity}: java.lang.RuntimeException: /data/user/0/com.myapp.android.app/files/myappDb: Encrypted interprocess sharing is currently unsupported.DB has been opened by pid: 24356. Current pid is 24516. in /tmp/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 107
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3914)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4201)
       at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2438)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:226)
       at android.os.Looper.loop(Looper.java:313)
       at android.app.ActivityThread.main(ActivityThread.java:8663)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

and Caused by java.lang.RuntimeException: /data/user/0/com.myapp.android.app/files/myappDb: Encrypted interprocess sharing is currently unsupported.DB has been opened by pid: 24356. Current pid is 24516. in /tmp/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 107
       at io.realm.internal.OsSharedRealm.nativeGetSharedRealm(OsSharedRealm.java)
       at io.realm.internal.OsSharedRealm.<init>(OsSharedRealm.java:176)
       at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:261)
       at io.realm.BaseRealm.<init>(BaseRealm.java:143)
       at io.realm.BaseRealm.<init>(BaseRealm.java:110)
       at io.realm.Realm.<init>(Realm.java:159)
       at io.realm.Realm.createInstance(Realm.java:506)
       at io.realm.RealmCache.createInstance(RealmCache.java:508)
       at io.realm.RealmCache.doCreateRealmOrGetFromCache(RealmCache.java:461)
       at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:422)
       at io.realm.Realm.getInstance(Realm.java:435)
       at com.ex.myapp.android.App.newRealm(App.java:143)
       at com.ex.myapp.android.App.initDb(App.java:408)
       at com.ex.myapp.android.App.init(App.java:329)
       at com.ex.myapp..android.App.instance(App.java:79)
       at com.ex.myapp.android.network.NetworkContext$class.$init$(NetworkContext.scala:6)
       at com.ex.myappandroid.activity.SplashScreenActivity.<init>(SplashScreenActivity.scala:34)
       at java.lang.Class.newInstance(Class.java)
       at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
       at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
       at android.app.Instrumentation.newActivity(Instrumentation.java:1273)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3901)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4201)
       at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2438)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:226)
       at android.os.Looper.loop(Looper.java:313)
       at android.app.ActivityThread.main(ActivityThread.java:8663)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

Can you reproduce the bug?

Yes, always

Reproduction Steps

Realm is instantiated in App.java , most of the code is inherited the issue : at com.ex.myapp.android.App.newRealm(App.java:143) happens in these lines into the try block ,

try{
 Realm.setDefaultConfiguration(realmConfiguration);
            return Realm.getInstance(realmConfiguration);

more detail below in the method newRealm

here is initialised Realm:

   private void initDb() {
           Realm.init(this);
            db = newRealm();
            Log.i("HVDB", "Initialized DB");

            Realm realm = Realm.getDefaultInstance();

            realm.beginTransaction();
            realm.delete(AppLog.class);
            realm.commitTransaction();
            realm.close();
            NamedValue.unset(K.basketsWithSelectedTimeslot);
            Log.i("HVDB", "Cleared cached data");
            //set to true after doing a migration so that the tutorial
            if (state().resetTutorial) {
                NamedValue.unset(K.tutorial.shown);
                state().resetTutorial = false;
            }

            //TODO: debug only
            //NamedValue.unset(K.lastShownRecallId);
    }

NamedValue extends a Realm object for :


@RealmClass
public class NamedValue extends RealmObject{

    /**
     * Gets the value for the given key
     *
     * @param key
     * @return value for the given key (defaults to empty string)
     */
    public static String get(String key){
        final Realm db = App.instance().db();
        try {
            return getValue(db.where(NamedValue.class).equalTo("key", key).findFirst());
        }
        finally {
            App.instance().closeDb(db);
        }
    }

    public static <T> T getObject(String key, Class<? extends T> clazz) {
        final T object;
        try{
            object = App.instance().gson().fromJson(NamedValue.get(key), clazz);
            return object;
        }
        catch (Exception e){
            return null;
        }
    }

    /**
     * Removed a stored key-value pair
     *
     * @param key
     * @return the old value for the given object key (defaults to empty string)
     */
    public static String unset(String key){
        final Realm db = App.instance().db();
        try {
            final NamedValue storedValue = db.where(NamedValue.class).equalTo("key", key).findFirst();
            final String oldValue = getValue(storedValue);
            if(storedValue != null){
                db.beginTransaction();
                try {
                    storedValue.deleteFromRealm();
                } catch (IllegalStateException iae) {
                    //cannot delete key, skip this
                }
                db.commitTransaction();
            }
            return oldValue;
        }
        finally {
            App.instance().closeDb(db);
        }
    }

    /**
     * Sets the provided value for the given key
     *
     * @param key
     * @param value
     * @return the old value for the given key (defaults to empty string)
     */
    public static String set(String key, String value){
        final Realm db = App.instance().db();
        try {
            db.beginTransaction();
            NamedValue updatedValue = db.where(NamedValue.class).equalTo("key", key).findFirst();
            final String oldValue = getValue(updatedValue);
            if(updatedValue == null)
                updatedValue = new NamedValue(key, value);
            else
                updatedValue.setValue(value);
            db.copyToRealmOrUpdate(updatedValue);
            db.commitTransaction();
            return oldValue;
        }
        finally {
            App.instance().closeDb(db);
        }
    }

    public static <T> T setObject(String key, T object) {
        if(object == null) {
            final String oldValue = unset(key);
            //TODO: since the object passed in is null and java does not retain generic class information, there is no way to know the class of the stored object
            //a possible solution for this would be to save the class alongside the value when storing objects
            return null;
        }
        else
            return App.instance().gson().fromJson(NamedValue.set(key, App.instance().gson().toJson(object)), (Class<T>)object.getClass());
    }

    public static void clear() {
        final Realm db = App.instance().db();
        try {
            db.beginTransaction();
            db.delete(NamedValue.class);
            db.commitTransaction();
        } finally {
            App.instance().closeDb(db);
        }
    }

    private static String getValue(NamedValue storedValue){
        if((storedValue == null) || (storedValue.getValue() == null))
            return "";
        return storedValue.getValue();
    }

    @PrimaryKey
    private String key;
    private String value;

    public NamedValue(final String key, final String value){
        this.key = key;
        this.value = value;
    }

    public NamedValue(final String key){
        this.key = key;
        this.value = "";
    }

    public NamedValue(){
        this.value = "";
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}


    public synchronized Realm db(){

            return newRealm();
    }

here the method newRealm() I mentioned where happens the issue
private Realm newRealm(){
    if(realmConfiguration == null) {
        RealmConfiguration.Builder builder = new RealmConfiguration.Builder()
                .name(LocalConfig.realm.name)
                .directory(getFilesDir())
                .schemaVersion(LocalConfig.realm.schemaVersion)
                //.modules(new DataModule())
                .encryptionKey(SecurityUtils.getStoragePassword(this));
        Log.i("HVDB", String.format("Requring DB version %d", LocalConfig.realm.schemaVersion));
        if (LocalConfig.realm.schemaVersion == 1) {
            Log.w("HVDB", "DEBUG MODE - THIS WILL CLEAR DATA");
            builder = builder.deleteRealmIfMigrationNeeded();
        } else {
            builder = builder.migration(new HVRealmMigration());
        }
        realmConfiguration = builder.build();
    }
    try {//here should happen the issue
        Realm.setDefaultConfiguration(realmConfiguration);
        return Realm.getInstance(realmConfiguration);
    } catch (IllegalArgumentException iae) {
        Log.e("HVDB", "Invalid DB file", iae);
        if((iae.getMessage() != null) && (iae.getMessage().contains("format"))){
            Log.e("HVDB", "Invalid DB format", iae);
            //if the realm format is invalid we try to delete it as the database is not recoverable
            try {
                Realm.deleteRealm(realmConfiguration);
            } catch (Exception e) {
                Log.e("HVDB", "Error while removing corrupt DB", e);
            }
        }
    } catch (RealmFileException rfe) {
        Log.e("HVDB", "Error while initializing DB", rfe);
      try {
         Realm.deleteRealm(realmConfiguration);
      } catch (Exception e) {
          Log.e("HVDB", "Error while removing corrupt/incompatible DB", e);
          e.printStackTrace();
        new File(realmConfiguration.getRealmFileName()).delete();
      }
    }
    return Realm.getInstance(realmConfiguration);
}

public class HVRealmMigration implements RealmMigration { private static final List<Pair<Long, RealmMigration>> migrations = new LinkedList<>(); static { //migrations are not used for development }

@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
    Log.i("HVDBMigration", String.format("Migrating from DB v %d to DB v %d", oldVersion, newVersion));
    for(Pair<Long, RealmMigration> migration: migrations){
        if(migration.first.longValue() >= oldVersion) {
            migration.second.migrate(realm, oldVersion, newVersion);
        }
    }
    final DynamicRealmObject nv = realm.where(NamedValue.class.getSimpleName()).equalTo("key", K.tutorial.shown).findFirst();
    if(nv != null){
        nv.deleteFromRealm();
    }
    App.instance().state().resetTutorial = true;
    /*
    realm.getSchema()
            .create(TestMigrationClass.class.getSimpleName())
            .addField("id", String.class)
            .addPrimaryKey("id");
    //        */
}

}



### Version

io.realm:realm-gradle-plugin:10.10.1 (also preceding)

### What SDK flavour are you using?

Local Database only

### Are you using encryption?

Yes, using encryption

### Platform OS and version(s)

android 12, 11, 10,9

### Build environment

**Android Studio version: ...**
Android Studio Bumblebee | 2021.1.1 Patch 2
Build #AI-211.7628.21.2111.8193401, built on February 17, 2022
Runtime version: 11.0.11+0-b60-7772763 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 12.1
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 8
Registry: external.system.auto.import.disabled=true, ide.instant.shutdown=false
Non-Bundled Plugins: AceJump (3.8.4), IdeaVIM (1.9.2), com.thoughtworks.gauge (211.6693.111), org.jetbrains.kotlin (211-1.6.10-release-923-AS7442.40), org.intellij.scala (2021.1.22), org.intellij.plugins.markdown (211.7142.37)
**Android Build Tools version: ...**
    buildToolsVersion '30.0.2'

**Gradle version: ...**
        classpath 'com.android.tools.build:gradle:3.6.4'
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32' (we have both kotlin and java but realm is implemented in java)

Ndrocchietto avatar Mar 29 '22 09:03 Ndrocchietto

A marginal note out of all the 60+ crashes only Samsung phones are affected

Ndrocchietto avatar Mar 29 '22 16:03 Ndrocchietto

+1

Sarubbaru avatar Apr 27 '22 14:04 Sarubbaru

any news?

Sarubbaru avatar Apr 27 '22 14:04 Sarubbaru

Nope, we have been able to limit the error refactoring the code, but issue is still present, we get other related stack trace error messages about cache and encryption problems, we have been thinking to try to eliminate decryption, and eventually start to move to sharedPreferences (for key values) and considering Room.

Ndrocchietto avatar Apr 28 '22 08:04 Ndrocchietto

We are presenting the same problem, in crashlytics we see more than 100 reports, 80% are presented in Samsung devices, we have not been able to replicate it, we only know about it from the reports.

What version of Realm are you using?

I just saw that Realm is going to release update 10.10.2 where it states that it fixes bugs when using encryption, hopefully when they release it with that it will fix the problem

Realm 10.10.2

yovankaosio avatar May 12 '22 15:05 yovankaosio

We are presenting the same problem, in crashlytics we see more than 100 reports, 80% are presented in Samsung devices, we have not been able to replicate it, we only know about it from the reports.

What version of Realm are you using?

I just saw that Realm is going to release update 10.10.2 where it states that it fixes bugs when using encryption, hopefully when they release it with that it will fix the problem

Realm 10.10.2

10.10.1 we decided to migrate to Room, is causing too many issues users are complaining for crashes, unfortunately the code that was implementing Realm in our app was inerithed and was poorly written

Ndrocchietto avatar May 16 '22 14:05 Ndrocchietto

We're gonna switch to 10.10.1 to validate how Realm behaves with that version to see if we find anything else, if so we update the information here 👉🏽👈🏽

yovankaosio avatar May 16 '22 15:05 yovankaosio

Hi @Ndrocchietto. We are sad to see you decided to migrate to Room. We have one question though. Does your enable multiprocessing? If so, encryption cannot be used in conjunction with multiprocess. If not, there may be something going on at an operating system level. If you are still interested in fixing the problem, do let us know.

edualonso avatar Jul 11 '22 10:07 edualonso

HI @edualonso thank you very much, we decided to rewrite the app because was in scala and android does not support anymore, we are not using a db anymore, and relying on the backend as source of truth

Ndrocchietto avatar Jul 12 '22 16:07 Ndrocchietto

I will close this issue as it appears to be no longer relevant. As already mentioned encryption cannot be used in a multiprocess scenario (#6805). If you need more input please try to verify if there is in fact multiple instances of the app running, etc. and update the issue.

rorbech avatar Aug 19 '22 13:08 rorbech

Well, we still have the same issue, we get a handful of these each month spread over phone models (Samsung 50%) and Android versions (Android 11 50%) Currently using 10.12.0 and the crash happens just at start up of the application the second time after a fresh installation, the first time the app starts there is no encrypted database. The calls to Realm in App starts is

Realm.init(this); final RealmConfiguration realmConfig = new RealmConfiguration.Builder() .schemaVersion(REALM_VERSION) .encryptionKey(realmKey) .allowWritesOnUiThread(true) .migration(new RealmUpdate()) <--- always called but no migration is done (fresh database) but could this be a problem with a dynamic realm instance here? .build(); Realm.setDefaultConfiguration(realmConfig);

try (Realm localRealm = Realm.getDefaultInstance()) { <--- crash ... }

Fatal Exception: java.lang.RuntimeException Unable to create application com.x.y.App: java.lang.RuntimeException: /data/user/0/com.x.y/files/default.realm: Encrypted interprocess sharing is currently unsupported.DB has been opened by pid: 21087. Current pid is 18149. in /tmp/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 107 android.app.ActivityThread.handleBindApplication (ActivityThread.java:7540) android.app.ActivityThread.access$1500 (ActivityThread.java:301) android.app.ActivityThread$H.handleMessage (ActivityThread.java:2158) android.os.Handler.dispatchMessage (Handler.java:106) android.os.Looper.loop (Looper.java:246) android.app.ActivityThread.main (ActivityThread.java:8595) java.lang.reflect.Method.invoke (Method.java) com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:602) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1130)

Caused by java.lang.RuntimeException /data/user/0/com.x.y/files/default.realm: Encrypted interprocess sharing is currently unsupported.DB has been opened by pid: 21087. Current pid is 18149. in /tmp/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 107 io.realm.internal.OsSharedRealm.nativeGetSharedRealm (OsSharedRealm.java) io.realm.internal.OsSharedRealm. (OsSharedRealm.java:174) io.realm.internal.OsSharedRealm.getInstance (OsSharedRealm.java:259) io.realm.BaseRealm. (BaseRealm.java:142) io.realm.BaseRealm. (BaseRealm.java:109) io.realm.Realm. (Realm.java:161) io.realm.Realm.createInstance (Realm.java:535) io.realm.RealmCache.createInstance (RealmCache.java:508) io.realm.RealmCache.doCreateRealmOrGetFromCache (RealmCache.java:461) io.realm.RealmCache.createRealmOrGetFromCache (RealmCache.java:422) io.realm.Realm.getDefaultInstance (Realm.java:443) com.x.y.App.onCreate (App.java:188) android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1192) android.app.ActivityThread.handleBindApplication (ActivityThread.java:7535) android.app.ActivityThread.access$1500 (ActivityThread.java:301) android.app.ActivityThread$H.handleMessage (ActivityThread.java:2158) android.os.Handler.dispatchMessage (Handler.java:106) android.os.Looper.loop (Looper.java:246) android.app.ActivityThread.main (ActivityThread.java:8595) java.lang.reflect.Method.invoke (Method.java) com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:602) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1130)

Please reopen this issue because we have user which can't use our application but unfortunately we have no devices to test on where this problem occurs.

andersfredlund avatar Nov 04 '22 09:11 andersfredlund