Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

IncompatibleClassChangeError When updating from 1.0 to 1.1 beta2 #44

Closed
scottyab opened this issue May 9, 2024 · 10 comments 路 Fixed by #46
Closed

IncompatibleClassChangeError When updating from 1.0 to 1.1 beta2 #44

scottyab opened this issue May 9, 2024 · 10 comments 路 Fixed by #46
Labels
bug Something isn't working

Comments

@scottyab
Copy link

scottyab commented May 9, 2024

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]
@scottyab scottyab changed the title IncompatibleClassChangeError When updateing from 1 IncompatibleClassChangeError When updating from 1.0 to 1.1 beta2 May 9, 2024
@scottyab
Copy link
Author

scottyab commented May 9, 2024

Get the same error for a fresh install (no existing encrypted datastores). LMK if there's more info I can provide. Thanks

@osipxd osipxd added the bug Something isn't working label May 9, 2024
@osipxd
Copy link
Owner

osipxd commented May 9, 2024

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 (*)

@osipxd
Copy link
Owner

osipxd commented May 9, 2024

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!

@scottyab
Copy link
Author

scottyab commented May 9, 2024

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

@osipxd
Copy link
Owner

osipxd commented May 9, 2024

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.

@scottyab
Copy link
Author

Agreed it's strange. I'll jump on and test the new release when available. Thanks!

@osipxd
Copy link
Owner

osipxd commented May 13, 2024

@scottyab, just published v1.1.1-beta03

@osipxd
Copy link
Owner

osipxd commented May 16, 2024

@scottyab, just a gentle reminder. Have you been able to check if the issue persists in beta03?

@scottyab
Copy link
Author

Thanks @osipxd moving to beta03 seems to avoid the IncompatibleClassChangeError we were seeing before. Thanks for the update :)

@osipxd
Copy link
Owner

osipxd commented May 20, 2024

Great news! Closing this issue

@osipxd osipxd closed this as completed May 20, 2024
@osipxd osipxd linked a pull request May 20, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants