Hi, I have a complex app with more than one Realm (because of sandboxing) and Realms are stored on External Storage. Until recently I was stuck at v1.0.1 because of various problems that were fixed ;)
But now I'm facing a new problem, the compact phase (which is started before opening the realm) is crashing the whole app. Even if I'm catching the RealmError, a native crash occurs afterwards.
Compact Realm before opening it, the Realm exists and is writable.
No explosion
io.realm.exceptions.RealmError: Unrecoverable error. Read-only file system in /home/cc/repo/realm/realm-java-release/realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp line 414
at io.realm.internal.SharedRealm.nativeCompact(Native Method)
at io.realm.internal.SharedRealm.compact(SharedRealm.java:327)
at io.realm.BaseRealm.compactRealm(BaseRealm.java:586)
at io.realm.Realm.compactRealm(Realm.java:1612)
Simple AndroidTestCase
public class RealmExternalTest extends AndroidTestCase {
@Override
protected void setUp() throws Exception {
Realm.init(getContext());
}
@Override
protected void tearDown() throws Exception {
}
public void testRealmCompactExternal() {
File directory = getContext().getExternalFilesDir(null);
directory.mkdirs();
assertTrue(directory.exists());
RealmConfiguration config = new RealmConfiguration.Builder().directory(directory).name("somerealm.realm").build();
Realm realm = Realm.getInstance(config);
File realmFile = new File(config.getPath());
assertTrue(realmFile.exists() && realmFile.canWrite());
{ // simple read/write
Test test = new Test();
realm.beginTransaction();
try {
realm.copyToRealm(test);
realm.commitTransaction();
} catch (Exception e) {
realm.cancelTransaction();
fail();
}
assertTrue(realm.where(Test.class).count() > 0);
}
realm.close();
assertTrue(Realm.compactRealm(config));
}
}
The whole test is passing, except the last line throwing the above exception :/
Realm version(s): 2.3.0
Realm sync feature enabled: no
Android Studio version: 2.2.3
Which Android version and device: Samsung Galaxy Tab S2 (SM-T710) 6.0.1
Hey @tmeunier ,
I don't have a Galaxy Tab, so I can't verify your issue on the particular device. We do have a bunch of unit tests around compaction, here: https://github.com/realm/realm-java/blob/master/realm/realm-library/src/androidTest/java/io/realm/RealmTests.java
I've also run your specific test on a couple of devices and cannot repro the problem.
Can you try this on another device and see if it is a problem there, as well? If you can get it to fail on a Nexus device, that would be particularly interesting.
Attempted to repro on a Samsung Galaxy Note 8.0, 4.4.2. No joy.
Hey @bmeike
I took a look at the tests but they do not include "compact on external storage" ;)
I ran the following tests on other devices/emulators I have :
A) compact a Realm on internal storage (based on your tests)
B) compact a Realm on external storage (the one above)
Samsung Galaxy Tab S2 (6.0.1)
A) OK
B) KO - io.realm.exceptions.RealmError: Unrecoverable error. Read-only file system
Samsung Galaxy Tab 4 (5.0.2)
A) OK
B) KO - io.realm.exceptions.RealmError: Unrecoverable error. Read-only file system
HTC One M8 (6.0.0)
A) OK
B) KO - io.realm.exceptions.RealmError: Unrecoverable error. Read-only file system
Samsung XCover 3 (5.1.1)
A) OK
B) KO - io.realm.exceptions.RealmError: Unrecoverable error. Read-only file system
Wiko Rainbow Lite 4G (5.1.1)
A) OK
B) KO - io.realm.exceptions.RealmError: Unrecoverable error. Read-only file system
Nexus 5 - emulator/rooted (5.1.0)
A) OK
B) OK
Nexus 5 - emulator/rooted (6.0.0)
A) OK
B) OK
Samsung Galaxy S6 - emulator/rooted (6.0.0)
A) OK
B) OK
So, it's working on emulators but not on my devices... Could you give a try with Android 5+ ?
My apologies! I overlooked this line: File directory = getContext().getExternalFilesDir(null);
Although I don't think this is the problem, can you verify that you are using both android.permission.READ_EXTERNAL_STORAGE and android.permission.WRITE_EXTERNAL_STORAGE permission?
Yes. I can duplicate this on both the Nexus 4 5.1.1 and the Samsung Galaxy Tab 8.0
@bmeike No worries.
Yes, permissions are fine. Also, I'm able to create/read/write the Realm on the external storage, just compact is not working. And before upgrade to 2.3.0 it was working...
Yep. I confirm.
I believe the error is beneath this call in shared_realm.cpp:
Group& Realm::read_group()
{
verify_open();
if (!m_group) {
m_group = &const_cast<Group&>(m_shared_group->begin_read());
add_schema_change_handler();
}
return *m_group;
}
A casual review of the code doesn't show any relevant recent changes.
Also, the file does appear to be available, RW, for the process:
shell@mako:/sdcard/Android/data/io.realm.test/files $ ps
...
u0_a112 18535 18533 1088 508 ffffffff 00000000 S /system/bin/sh
u0_a112 18541 18535 6200 1164 ffffffff 00000000 S /data/data/io.realm.test/lldb/bin/lldb-server
u0_a112 18542 18541 9280 1896 ffffffff 00000000 S /data/data/io.realm.test/lldb/bin/lldb-server
u0_a112 18544 18542 8264 3228 ffffffff 00000000 S /data/data/io.realm.test/lldb/bin/lldb-server
root 18635 2 0 0 ffffffff 00000000 S flush-0:18
shell 18679 18426 2412 716 00000000 b6ec9174 R ps
shell@mako:/sdcard/Android/data/io.realm.test/files $ ls -al
-rw-rw---- u0_a86 sdcard_r 147456 2017-02-03 15:23 somerealm.realm
-rw-rw---- u0_a86 sdcard_r 1160 2017-02-03 15:24 somerealm.realm.lock
drwxrwx--- u0_a86 sdcard_r 2017-02-03 15:22 somerealm.realm.management
shell@mako:/sdcard/Android/data/io.realm.test/files $ id u0_a112
uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:shell:s0
sh
I wonder if this is related to #3972 ?
The patch that will allow this test pass is being tracked in https://github.com/realm/realm-core/pull/2445
Good to know, thanks!
need core release v2.3.2