realm / realm-kotlin

Kotlin Multiplatform and Android SDK for the Realm Mobile Database: Build Better Apps Faster.
Apache License 2.0
965 stars 61 forks source link

"Only subclasses of RealmObject and EmbeddedRealmObject are allowed in the schema" with Kotlin 1.8.0 #1212

Closed neige-i closed 1 year ago

neige-i commented 1 year ago

Hello, I have a similar problem with the one indicated in this StackOverflow post when minifyEnabled is set to true.

Basically, I can run my app without any problem with Kotlin 1.7.21 and Realm-Kotlin 1.5.2 (and AGP 7.3.1). The problem is when I upgrade to Kotlin version 1.8.0, I get the same error as in the above linked post:

Caused by: java.lang.IllegalArgumentException: Only subclasses of RealmObject and EmbeddedRealmObject are allowed in the schema. Found: my.package.MyRealmDataModel

The problem occurs when building a RealmConfiguration because it calls the io.realm.kotlin.Configuration.SharedBuilder constructor, in which the exception is thrown. The reason the error happens is because clazz.realmObjectCompanionOrNull() returns null, which calls clazz.companionObjectInstance which loops through the class’ nestClasses and finds out the first for which their description.isCompanionObject property returns true. By using the debugger, I managed to reached that code and discovered that the descriptor was a LazyJavaClassDescriptor instance. But, in this ClassDescriptor implementation, the isCompanionObject is always false. I suspect this is due to code generation. Looking at the generated code in my build folder, my realm model is fully converted in java as well as the companion object, but I could be wrong.

I also tried all the rules mentioned in the linked StackOverflow post, to no avail.

cmelchior commented 1 year ago

This can also happen if you didn't apply the Realm Kotlin plugin? If you are doing that, is it something you can reproduce in a sample project we can look at?

neige-i commented 1 year ago

Thank you for your reply. Indeed, the error also happens even if the plugin is not applied. In my case, it is applied at the app module level.

It is reproductible in the little attached sample project:

Thanks in advance

rorbech commented 1 year ago

Hi @neige-i. This is somehow tied to minifying the app. If I disable minification with minifyEnabled = false then it works. We will have to investigate what has changed around that with Kotlin 1.8.0. Thanks for the report.

rorbech commented 1 year ago

Hi @neige-i. It also somehow seems to be tied to Android Gradle Plugin, since it goes away if bump to Android Gradle Plugin 7.4.0. I haven't identified a specific issue but could be some incompatibility between Android Gradle Plugin and Kotlin 1.8.0 when minifying.

Could you verify in your end that it works by bumping to AGP 7.4.0?

msa1422 commented 1 year ago

I am new to the Kotlin Multiplatform and I might be on the wrong issue but I am facing an issue with similar suspects which are Kotlin-1.8.0, AGP-7.4.0, and R8. I will leave it to the experts to decide where the issue lies.

Project compiles with Kotlin-1.8.0, AGP-7.3.1. But when I bump AGP to 7.4.0 a compilation fails while dexing. Here is the error

* What went wrong:
Execution failed for task ':android:app:mergeExtDexDebug'.
> Could not resolve all files for configuration ':android:app:debugRuntimeClasspath'.
   > Failed to transform library-base-release.aar (io.realm.kotlin:library-base-android:1.5.2) to match attributes {artifactType=android-dex, asm-transformed-variant=NONE, dexing-enable-desugaring=true, dexing-enable-jacoco-instrumentation=true, dexing-is-debuggable=true, dexing-min-sdk=24, org.gradle.category=library, org.gradle.status=release, org.gradle.usage=java-runtime, org.jetbrains.kotlin.platform.type=androidJvm}.
      > Execution failed for DexingNoClasspathTransform: /Users/mymac/.gradle/caches/transforms-3/fb6c11c2a3f663e3a6cd4e5e549eca10/transformed/instrumented_library-base-release-runtime.jar.
         > Error while dexing.

If you guys need the full stack trace, please let me know.

TylerMcCraw commented 1 year ago

I'm also seeing this issue with AGP 7.4

rorbech commented 1 year ago

Hi @msa1422. I don't think this is the same issue, so please open a new one with some more details on your project setup, version in play and the full stacktrace. And maybe start by retrying with a clean build.

I am new to the Kotlin Multiplatform and I might be on the wrong issue but I am facing an issue with similar suspects which are Kotlin-1.8.0, AGP-7.4.0, and R8. I will leave it to the experts to decide where the issue lies.

Project compiles with Kotlin-1.8.0, AGP-7.3.1. But when I bump AGP to 7.4.0 a compilation fails while dexing. Here is the error

* What went wrong:
Execution failed for task ':android:app:mergeExtDexDebug'.
> Could not resolve all files for configuration ':android:app:debugRuntimeClasspath'.
   > Failed to transform library-base-release.aar (io.realm.kotlin:library-base-android:1.5.2) to match attributes {artifactType=android-dex, asm-transformed-variant=NONE, dexing-enable-desugaring=true, dexing-enable-jacoco-instrumentation=true, dexing-is-debuggable=true, dexing-min-sdk=24, org.gradle.category=library, org.gradle.status=release, org.gradle.usage=java-runtime, org.jetbrains.kotlin.platform.type=androidJvm}.
      > Execution failed for DexingNoClasspathTransform: /Users/mymac/.gradle/caches/transforms-3/fb6c11c2a3f663e3a6cd4e5e549eca10/transformed/instrumented_library-base-release-runtime.jar.
         > Error while dexing.

If you guys need the full stack trace, please let me know.

rorbech commented 1 year ago

@TylerMcCraw Are you seeing the original issue or the one posted by msa1422? I any case could you provide some more details on your project setup, versions in play, etc.?

TylerMcCraw commented 1 year ago

Both, actually, depending on the versions I use.

With AGP 7.3.0, Realm-Kotlin 1.5.2, and Kotlin 1.8.0, if minifyEnabled is set to true, I receive the

Caused by: java.lang.IllegalArgumentException: Only subclasses of RealmObject and EmbeddedRealmObject are allowed in the schema

error in my log when opening the application.

With AGP 7.4.0, Realm-Kotlin 1.5.2, and Kotlin 1.8.0, I receive the

Failed to transform library-base-release.aar (io.realm.kotlin:library-base-android:1.5.2)

error in my log when building the project.

rorbech commented 1 year ago

@TylerMcCraw Can your create a new issue to track this new error with appropriate information. Ideally a reproduction project, because I cannot replicate your observations with AGP 7.4.0, Realm Kotlin 1.5.2 and Kotlin 1.8.0.

TylerMcCraw commented 1 year ago

Sure thing! I'll add details as soon as I can. Maybe there's something going on with configuration caching or some other gradle property. I'll investigate.

In regards to the original issue around Kotlin 1.8.0 and minify, do you have any ideas yet? I've been trying to define explicit keep rules for all sorts of things, but haven't been able to get past this exception.

rorbech commented 1 year ago

No, unfortunately not. You could try to include the full proguard configuration from our project from https://github.com/realm/realm-kotlin/blob/releases/packages/library-base/proguard-rules-consumer-common.pro, but it could be that the combination of Kotlin 1.8.0/AGP 7.3.1 just somehow not takes it into account. There is probably a bigger chance to workaround it if we can find out what is going wrong when bumping to 7.4.0.

clementetb commented 1 year ago

We have not found yet what is causing this incompatibility with minify, AGP<7.4.0, and Kotlin 1.8.0. Meanwhile, the best solution would be to bump to 7.4.0.

@TylerMcCraw I haven't been able to reproduce the issue you are posting so it might have something to do with your project setup. Would you be able to create a sample project that reproduces the issue?

TylerMcCraw commented 1 year ago

I've just now been able to find a workaround to my issues.

Realm 1.6.0, AGP 7.4.0, Kotlin 1.8.0, targeting Java 11 And the one kicker: I had testCoverageEnabled = true set for all my debug variants on all modules. Removing this got rid of the Failed to transform library-base-release.aar error. And then by using AGP 7.4.0 + Kotlin 1.8.0, I was able to get around the original issue here when minification is enabled (via R8)

I'll try to write up more information tomorrow, if possible. And if I'm certain it's based on this config, I'll create another issue with a sample project. But, I just wanted to quickly post an update so people can check their testCoverageEnabled config

msa1422 commented 1 year ago

@TylerMcCraw, your work around works for me too. For Realm 1.5.2, Kotlin 1.8.0 and AGP 7.4.0, I was getting Failed to transform library-base-release.aar I had enableUnitTestCoverage = true and enableAndroidTestCoverage = true set in ApplicationBuildType for debug builds.

After changing enableAndroidTestCoverage = false, the project is now compiling.

I tried bumping Realm to latest 1.6.0, Getting the same Failed to transform library-base-release.aar with enableUnitTestCoverage = true and enableAndroidTestCoverage = true Error goes away with enableAndroidTestCoverage = false

cmelchior commented 1 year ago

Great find @TylerMcCraw. Thank you 🥳

Regarding the original exception I noticed a few things using the project from here https://github.com/realm/realm-kotlin/issues/1212#issuecomment-1384229709

  1. It fails with Caused by: java.lang.IllegalArgumentException: Only subclasses of RealmObject and EmbeddedRealmObject are allowed in the schema. Found: fr.neige_i.realmkotlintest.FooRealm. This is due to debug.isMinifyEnabled = true:
        debug {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }

If this is set to false, it compiles correctly. We did fix a few things in this area in 1.5.2, so not 100% sure how this managed to slip through the cracks.

  1. If you then bump only the Realm Kotlin plugin to 1.6.0 (and not the library dependency). It will crash with
e: org.jetbrains.kotlin.backend.common.CompilationException: Back-end: Please report this problem https://kotl.in/issue
/Users/cm/Downloads/RealmKotlinTest/app/src/main/java/fr/neige_i/realmkotlintest/FooRealm.kt:-1:-1
Details: Internal error in file lowering: java.lang.IllegalStateException: Cannot find io.realm.kotlin.types.RealmAny on platform JVM (1.8).
        at io.realm.kotlin.compiler.IrUtilsKt.fatalError(IrUtils.kt:575)
 ...
Caused by: java.lang.IllegalStateException: Cannot find io.realm.kotlin.types.RealmAny on platform JVM (1.8).
        ... 63 more

If you set both the plugin and library dependency to 1.6.0 it compiles on my machine at least.

Bottom line, it looks like there are still some issues around obfuscation we need to look at.

clementetb commented 1 year ago

We have created a new issue to track this enablAndroidTestCoverage issue.

cmelchior commented 1 year ago

Closing this issue. The fix for this is to move to AGP 7.4 and we are tracking Realm Kotlin working with testCoverage enabled in #1243.