encrypted-datastore
encrypted-datastore copied to clipboard
IncompatibleClassChangeError When updating from 1.0 to 1.1 beta2
Thanks for the great library 👍 . I was looking to upgrade Datastore to 1.1.1 and saw there's a breaking change. So updated encrypted-datastore to 1.1 beta 2 but seeing the below error when attempting to read an existing encrypted datastore (created in v1.0)
java.lang.IncompatibleClassChangeError: Class 'com.google.crypto.tink.streamingaead.InputStreamDecrypter' does not implement interface 'okio.BufferedSource' in call to 'java.io.InputStream okio.BufferedSource.inputStream()' (declaration of 'androidx.datastore.preferences.core.PreferencesSerializer' appears in /data/app/~~eTJYw7Wz9DLV5UqAu9poUA==/com.sptc.mdm-MQep1evLpdddK9RvztVxJA==/base.apk!classes33.dex)
at androidx.datastore.preferences.core.PreferencesSerializer.readFrom(PreferencesSerializer.jvm.kt:46)
at io.github.osipxd.datastore.encrypted.StreamingAeadEncryptingSerializer.readEncryptedFrom(EncryptingSerializer.kt:90)
at io.github.osipxd.datastore.encrypted.WrappingEncryptingSerializer.readFrom(EncryptingSerializer.kt:25)
at androidx.datastore.core.FileReadScope.readData$suspendImpl(FileStorage.kt:169)
at androidx.datastore.core.FileReadScope.readData(Unknown Source:0)
at androidx.datastore.core.StorageConnectionKt$readData$2.invokeSuspend(StorageConnection.kt:74)
at androidx.datastore.core.StorageConnectionKt$readData$2.invoke(Unknown Source:9)
at androidx.datastore.core.StorageConnectionKt$readData$2.invoke(Unknown Source:13)
at androidx.datastore.core.FileStorageConnection.readScope(FileStorage.kt:101)
at androidx.datastore.core.StorageConnectionKt.readData(StorageConnection.kt:74)
at androidx.datastore.core.DataStoreImpl.readDataFromFileOrDefault(DataStoreImpl.kt:331)
at androidx.datastore.core.DataStoreImpl.readDataOrHandleCorruption(DataStoreImpl.kt:373)
at androidx.datastore.core.DataStoreImpl.access$readDataOrHandleCorruption(DataStoreImpl.kt:53)
at androidx.datastore.core.DataStoreImpl$InitDataStore$doRun$initData$1.invokeSuspend(DataStoreImpl.kt:445)
at androidx.datastore.core.DataStoreImpl$InitDataStore$doRun$initData$1.invoke(Unknown Source:8)
at androidx.datastore.core.DataStoreImpl$InitDataStore$doRun$initData$1.invoke(Unknown Source:2)
at androidx.datastore.core.SingleProcessCoordinator.lock(SingleProcessCoordinator.kt:41)
at androidx.datastore.core.DataStoreImpl$InitDataStore.doRun(DataStoreImpl.kt:442)
at androidx.datastore.core.RunOnce.runIfNeeded(DataStoreImpl.kt:505)
at androidx.datastore.core.DataStoreImpl.readAndInitOrPropagateAndThrowFailure(DataStoreImpl.kt:274)
at androidx.datastore.core.DataStoreImpl.access$readAndInitOrPropagateAndThrowFailure(DataStoreImpl.kt:53)
at androidx.datastore.core.DataStoreImpl$readState$2.invokeSuspend(DataStoreImpl.kt:226)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@d5a8401, Dispatchers.Main.immediate]
Get the same error for a fresh install (no existing encrypted datastores). LMK if there's more info I can provide. Thanks
Thank you for the report! I can't reproduce this crash, so could you please provide output of these Gradle tasks?
./gradlew -q :app:dependencies --configuration releaseRuntimeClasspath
./gradlew -q :app:dependencyInsight --configuration releaseRuntimeClasspath --dependency io.github.osipxd:security-crypto-datastore-preferences
* Remember to replace ':app' with your module name
For the first task, it will be enough to provide only the part related to io.github.osipxd:security-crypto-datastore-preferences
. Something like this:
+--- io.github.osipxd:security-crypto-datastore-preferences:1.1.1-beta02
| +--- io.github.osipxd:encrypted-datastore-preferences:1.1.1-beta02
...
| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 (*)
My guess is you've declared different versions for these two dependencies:
implementation("io.github.osipxd:security-crypto-datastore:1.1.1-beta02")
implementation("io.github.osipxd:security-crypto-datastore-preferences:1.0.0")
I'll add versions alignment (#45) to prevent such mistakes in future. Nice catch!
I'm only defining dependency for security-crypto-datastore-preferences
is that an issue? I thought it would pull in the security-crypto-datastore
dependency.
osipxdSecureDatastore = "1.1.1-beta02"
osipxd-secure-datastore-preferences = { group = "io.github.osipxd", name = "security-crypto-datastore-preferences", version.ref = "osipxdSecureDatastore" }
The gradle dependencies outputs
./gradlew -q :app:dependencies --configuration releaseRuntimeClasspath
Produces.
+--- io.github.osipxd:security-crypto-datastore-preferences:1.1.1-beta02
| | +--- io.github.osipxd:encrypted-datastore-preferences:1.1.1-beta02
| | | +--- io.github.osipxd:encrypted-datastore:1.1.1-beta02
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 (*)
| | | | +--- androidx.datastore:datastore-core:1.1.1 (*)
| | | | \--- com.google.crypto.tink:tink-android:1.13.0 (*)
| | | +--- androidx.datastore:datastore-preferences-core:1.1.1 (*)
| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 (*)
| | +--- io.github.osipxd:security-crypto-datastore:1.1.1-beta02
| | | +--- io.github.osipxd:encrypted-datastore:1.1.1-beta02 (*)
| | | +--- androidx.datastore:datastore:1.1.1 (*)
| | | +--- androidx.security:security-crypto:1.0.0 -> 1.1.0-alpha06 (*)
| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 (*)
| | +--- androidx.datastore:datastore-preferences:1.1.1 (*)
| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.23 (*)
./gradlew -q :app:dependencyInsight --configuration releaseRuntimeClasspath --dependency io.github.osipxd:security-crypto-datastore-preferences
Produces...
io.github.osipxd:security-crypto-datastore-preferences:1.1.1-beta02
Variant releaseVariantReleaseRuntimePublication:
| Attribute Name | Provided | Requested |
|-------------------------------------------------|--------------|--------------|
| org.gradle.dependency.bundling | external | |
| org.gradle.libraryelements | aar | |
| org.gradle.status | release | |
| org.gradle.category | library | library |
| org.gradle.usage | java-runtime | java-runtime |
| com.android.build.api.attributes.AgpVersionAttr | | 8.2.2 |
| com.android.build.api.attributes.BuildTypeAttr | | release |
| org.gradle.jvm.environment | | android |
| org.jetbrains.kotlin.platform.type | | androidJvm |
io.github.osipxd:security-crypto-datastore-preferences:1.1.1-beta02
+--- project :data
| +--- releaseRuntimeClasspath
| \--- project :MyModule1
| \--- releaseRuntimeClasspath
\--- project :MyModule2
\--- releaseRuntimeClasspath
Oh, it's weird then. The only explanation I see is when security-crypto-datastore-preferences
version is lower than androidx.datastore:datastore-preferences-core
version.
It results to that PreferencesSerializer
expects Okio types, but encrypted-datastore
1.0.0 doesn't know about such types as they were introduced in datastore
1.1.0.
According to yours dependencies report, datastore
has the same version as encrypted-datastore
, so I have no idea what goes wrong. The only idea I have is to release a new version with this PR and check if the problem will persist.
Agreed it's strange. I'll jump on and test the new release when available. Thanks!
@scottyab, just published v1.1.1-beta03
@scottyab, just a gentle reminder. Have you been able to check if the issue persists in beta03?
Thanks @osipxd moving to beta03 seems to avoid the IncompatibleClassChangeError
we were seeing before. Thanks for the update :)
Great news! Closing this issue