Closed creativepsyco closed 9 years ago
Hello @creativepsyco I can reproduce this probem too. We are investigating this.
:+1: Sounds good.
@creativepsyco When you don't call Realm.compactRealm()
everything is fine, right? We are currently investigating the underlying method in the storage engine. My recommendation is to disable compaction. I hope we will be able to release a patch to fix it.
Yes everything is fine if I don't call Realm.compactRealm()
. I suppose some format related issues with the core storage engine. Thanks for the prompt reply :+1:
0.83.1 was released today with a fix for this.
:+1: Verified and it works.
Hi, I'm running into this problem with 0.86.0. Old Realm was dropped and new one was created on this version.
Fatal Exception: java.lang.RuntimeException: Unable to create application com.company.myapp.app: java.lang.IllegalArgumentException: Illegal Argument: Invalid format of Realm file.
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5116)
at android.app.ActivityThread.access$1600(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1509)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by java.lang.IllegalArgumentException: Illegal Argument: Invalid format of Realm file.
at io.realm.internal.SharedGroup.nativeCreate(SharedGroup.java)
at io.realm.internal.SharedGroup.<init>(SharedGroup.java:71)
at io.realm.internal.SharedGroupManager.compact(SharedGroupManager.java:174)
at io.realm.BaseRealm.compactRealm(BaseRealm.java:547)
at io.realm.Realm.compactRealm(Realm.java:1095)
at com.company.myapp.app.checkForMigration(app.java:122)
at com.company.myapp.app.onCreate(app.java:91)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1020)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5113)
at android.app.ActivityThread.access$1600(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1509)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
The Invalid format of Realm file.
message indicate that the Realm file is damaged in some way. Can you elaborate a bit on your setup?
We had a previous version of Realm installed, and decided it would be easier to drop the old Realm and create a new one.
This is what we do immediately prior to attempting to compact Realm.
RealmConfiguration oldRealm = new RealmConfiguration.Builder(this)
.name("default.realm")
.build();
boolean needToRebuildRealm = false;
File f = new File(getFilesDir().getAbsolutePath(), "default.realm");
if (f.exists()) {
FSLog.log("old realm exists, will be rebuilding");
needToRebuildRealm = true;
}
Realm.deleteRealm(oldRealm);
RealmConfiguration.Builder builder = new RealmConfiguration.Builder(this)
.name("cache")
.migration(new MigrationToLatest())
.schemaVersion(MigrationToLatest.LATEST_VERSION);
RealmConfiguration realmConfiguration = builder.build();
Realm.setDefaultConfiguration(realmConfiguration);
I'm not really sure how I can help elaborate on the setup, what exactly are you looking for?
The error happens when you call compactRealm()
. How do you call that method?
Oh, immediately below the block above with this:
Realm.compactRealm(realmConfiguration);
@erichkleung I have tried to reproduce your case without luck. Please take a look at #1958 and tell me if my test differs from your code.
@kneth i still get this problem in io.realm:realm-android:0.87.4 if i do not use compactRealm the realm file increase fast when will you fix this!
Hi @LiuDeng. This issue is unrelated to any file size increase. Please create a new issue with all relevant information instead.
@cmelchior i mean if i do not use compactRealm the realm size increase fast
Hello, @LiuDeng. Could you create another issue for your problem? It would be helpful to handle your problem.
Hello, I am not using this method Realm.compactRealm() but still I am facing the same crash here.
Caused by: java.lang.IllegalArgumentException: Illegal Argument: Invalid format of Realm file.
at io.realm.internal.SharedGroup.createNativeWithImplicitTransactions(Native Method)
at io.realm.internal.SharedGroup.
I am using Realm 0.85.
Can you please help me with this. Thanks.
@puneetagarwal Many things can cause this exception. For example, if you have an encrypted Realm file, and open it with the wrong key. Can you share your configuration?
Hi Kneth, Here is the code for my realm configuration:-
`private void configureRealm() { byte[] key = null;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
SecurePreferences securePreferences = new SecurePreferences(this);
if (!securePreferences.contains("DBAlias")) {
// generate a key
key = new byte[64];
new SecureRandom().nextBytes(key);
// store the key in the encrypted shared prefs
securePreferences.edit().putString("DBAlias", Base64.encodeToString(key, Base64.DEFAULT)).apply();
} else {
String keyString = securePreferences.getString("DBAlias", null);
key = Base64.decode(keyString, Base64.DEFAULT);
}
} else {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
List<String> keyAliases = new ArrayList<>();
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
keyAliases.add(aliases.nextElement());
}
SharedPreferences sharedPreferences = getSharedPreferences("DBPrefs", Context.MODE_PRIVATE);
if (!keyStore.containsAlias("DBAlias")) {
// create a keystore alias
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
end.add(Calendar.YEAR, 1);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(this)
.setAlias("DBAlias")
.setSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
.setSerialNumber(BigInteger.ONE)
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.build();
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
generator.initialize(spec);
KeyPair keyPair = generator.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// generate a key
key = new byte[64];
new SecureRandom().nextBytes(key);
// encrypt the new key
Cipher input = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
input.init(Cipher.ENCRYPT_MODE, publicKey);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, input);
cipherOutputStream.write(key);
cipherOutputStream.close();
// store the encrypted key in the shared prefs
sharedPreferences.edit().putString("DBAlias", Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT)).apply();
} else {
String encryptedString = sharedPreferences.getString("DBAlias", null);
if (encryptedString != null) {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry("DBAlias", null);
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
CipherInputStream cipherInputStream = new CipherInputStream(new ByteArrayInputStream(Base64.decode(encryptedString, Base64.DEFAULT)), output);
List<Byte> values = new ArrayList<>();
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
values.add((byte) nextByte);
}
key = new byte[values.size()];
for (int i = 0; i < key.length; i++) {
key[i] = values.get(i);
}
}
}
} catch (NoSuchAlgorithmException |
KeyStoreException |
CertificateException |
IOException |
NoSuchProviderException |
InvalidAlgorithmParameterException |
InvalidKeyException |
UnrecoverableEntryException |
NoSuchPaddingException e) {
e.printStackTrace();
}
}
RealmConfiguration config = null;
if (key != null) {
config = new RealmConfiguration.Builder(getApplicationContext())
.encryptionKey(key)
.schemaVersion(AppRealmMigration.REALM_VERSION) // Must be bumped when the schema changes
.deleteRealmIfMigrationNeeded()
.migration(new AppRealmMigration()) // Migration to run
.build();
} else {
config = new RealmConfiguration.Builder(getApplicationContext())
.schemaVersion(AppRealmMigration.REALM_VERSION) // Must be bumped when the schema changes
.deleteRealmIfMigrationNeeded()
.migration(new AppRealmMigration()) // Migration to run
.build();
}
Realm.setDefaultConfiguration(config);
}`
I just added deleteRealmIfMigrationNeeded ()
method to resolve this issue in case if there is any issue with the DB migration. Does it helped you to understand if I am doing something wrong.
Thanks.
deleteRealmIfMigrationIsNeeded
will delete your Realm file, and all (Realm) data will be wiped.
If you can reproduce it on your local devices, it might be useful to log the key to see if you get the exact key every time.
I tried to reproduce this issue at our end and it's not crashing but it crashes in the play store version only on some devices.
Is this possible that if I use deleteRealmIfMigrationIsNeeded()
and migration()
methods at the same time while creating Realm configuration, it throws this exception "IllegalArgumentException: Illegal Argument: Invalid format of Realm file."
Also, if I add name()
method to create a realm file, will it create a new Realm file with that name or it just renames the previous one. As I am not using name()
method right now and Realm creates a file with a default name.
Hope to hear from you soon. Thanks.
Hi peeps,
I am currently running into an
IllegalArgumentException
indicating that the format of the Realm file is invalid when I am trying to callRealm.compactRealm(realmConfiguration...)
before I use the realm file.I have a sample project to demonstrate the crash here: https://github.com/creativepsyco/sample-realm-crash/
Essentially I am trying to compact the realm file before it is ever used in the app.
Steps to reproduce:
0.82.2
build.gradle
edit the version to0.83.0
Is the
SharedGroupManager.compact()
implementation compatible with the new format of the Realm File? Right now it seems to be unusable with any Realm created byv0.83
orv0.82.2
Regards Mohit