realm / realm-kotlin

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

java.lang.NoSuchMethodError: No virtual method setValue #621

Closed Reedyuk closed 2 years ago

Reedyuk commented 2 years ago

When trying out the example of creating an object for realm creating a Task class, i am getting this error ONLY on android, the iOS target works fine:

java.lang.NoSuchMethodError: No virtual method setValue$library_base_release(Lio/realm/internal/RealmObjectInternal;Ljava/lang/String;Ljava/lang/Object;)V in class Lio/realm/internal/RealmObjectHelper; or its super classes (declaration of 'io.realm.internal.RealmObjectHelper' appears in /data/data/com.abc.android.searchFlowPrototype/code_cache/.overlay/base.apk/classes12.dex)
        at Task.setName(Main.kt:59)

Just for reference Main.kt: 59 is var name.

class Task : RealmObject {
    var name: String = "new task"
    var status: String = "Open"
}
realm.writeBlocking {
            copyToRealm(Task())
        }

Using version 0.8.0 of the plugin and library.

rorbech commented 2 years ago

Seems to be a duplicate of #612. If not, please provide some more details on the actual project setup (modules, publishing (project dependencies vs. maven local), etc.

Reedyuk commented 2 years ago

@rorbech - im currently using:

android {
        publishAllLibraryVariants()
    }

When i add

kotlin.android.buildTypeAttribute.keep=true

when i consume my shared library in my android client, i then get this error:

* What went wrong:
Execution failed for task ':app:checkDebugAarMetadata'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
   > Could not resolve com.abc.mp:Mobile-Library-android:0.0.1.
     Required by:
         project :app > project :PartnersFlow
         project :app > project :PartnerFlow
      > No matching variant of com.abc.mp:Mobile-Library-android:0.0.1 was found. The consumer was configured to find a runtime of a component, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.1.0-beta05', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but:
          - Variant 'releaseApiElements-published' capability com.abc.mp:Mobile-Library-android:0.0.1 declares a component, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.1.0-beta05', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
              - Incompatible because this component declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
          - Variant 'releaseRuntimeElements-published' capability com.abc.mp:Mobile-Library-android:0.0.1 declares a runtime of a component, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.1.0-beta05', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
              - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'

It seems odd that i need to add such a property, given that all the other libraries i am using does not require it.

Reedyuk commented 2 years ago

also im using maven local to publish

rorbech commented 2 years ago

Looks like you are only publishing releases 🤔 Maybe you can get an overview from ./gradlew :outgoingVariants to see if you are actually publishing what you expect.

I also seems like you are using pre Kotlin 1.6.10 since the AGP-version is tracked. Not an issue when you are producing and consuming from the same project, but you might end up hitting https://youtrack.jetbrains.com/issue/KT-49798, so consider upgrading to 1.6.10.

Reedyuk commented 2 years ago

Let me try 1.6.10, as for the variants, its as expected (i checked my local m2 dir).

Mobile-Library
Mobile-Library-android
Mobile-Library-android-debug
Reedyuk commented 2 years ago

When using 1.6.10

Could not determine the dependencies of task ':compileIosMainKotlinMetadata'.
> Could not resolve all artifacts for configuration ':allSourceSetsCompileDependenciesMetadata'.
   > Could not resolve io.realm.kotlin:library-base:0.8.0.
     Required by:
         project :
      > The consumer was configured to find a usage of 'kotlin-metadata' of a library, preferably optimized for non-jvm, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common'. However we cannot choose between the following variants of io.realm.kotlin:library-base:0.8.0:
          - debugApiElements-published
          - debugRuntimeElements-published
          - iosArm64ApiElements-published
          - iosSimulatorArm64ApiElements-published
          - iosX64ApiElements-published
          - jvmApiElements-published
          - jvmRuntimeElements-published
          - macosApiElements-published
          - macosArm64ApiElements-published
          - metadataApiElements
          - releaseApiElements-published
          - releaseRuntimeElements-published
        All of them match the consumer attributes:
          - Variant 'debugApiElements-published' capability io.realm.kotlin:library-base:0.8.0 declares an API of a library, preferably optimized for Android, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
              - Unmatched attributes:
                  - Provides attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.1.0-beta05' but the consumer didn't ask for it
                  - Provides attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug' but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
          - Variant 'debugRuntimeElements-published' capability io.realm.kotlin:library-base:0.8.0 declares a runtime of a library, preferably optimized for Android, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
              - Unmatched attributes:
                  - Provides attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.1.0-beta05' but the consumer didn't ask for it
                  - Provides attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug' but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
          - Variant 'iosArm64ApiElements-published' capability io.realm.kotlin:library-base:0.8.0 declares a usage of 'kotlin-api' of a library, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':
              - Unmatched attributes:
                  - Provides attribute 'artifactType' with value 'org.jetbrains.kotlin.klib' but the consumer didn't ask for it
                  - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
                  - Provides release status but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.native.target' with value 'ios_arm64' but the consumer didn't ask for it
          - Variant 'iosSimulatorArm64ApiElements-published' capability io.realm.kotlin:library-base:0.8.0 declares a usage of 'kotlin-api' of a library, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':
              - Unmatched attributes:
                  - Provides attribute 'artifactType' with value 'org.jetbrains.kotlin.klib' but the consumer didn't ask for it
                  - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
                  - Provides release status but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.native.target' with value 'ios_simulator_arm64' but the consumer didn't ask for it
          - Variant 'iosX64ApiElements-published' capability io.realm.kotlin:library-base:0.8.0 declares a usage of 'kotlin-api' of a library, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':
              - Unmatched attributes:
                  - Provides attribute 'artifactType' with value 'org.jetbrains.kotlin.klib' but the consumer didn't ask for it
                  - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
                  - Provides release status but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.native.target' with value 'ios_x64' but the consumer didn't ask for it
          - Variant 'jvmApiElements-published' capability io.realm.kotlin:library-base:0.8.0 declares an API of a library, preferably optimized for standard JVMs, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm':
              - Unmatched attributes:
                  - Provides its elements packaged as a jar but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
          - Variant 'jvmRuntimeElements-published' capability io.realm.kotlin:library-base:0.8.0 declares a runtime of a library, preferably optimized for standard JVMs, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm':
              - Unmatched attributes:
                  - Provides its elements packaged as a jar but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
          - Variant 'macosApiElements-published' capability io.realm.kotlin:library-base:0.8.0 declares a usage of 'kotlin-api' of a library, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':
              - Unmatched attributes:
                  - Provides attribute 'artifactType' with value 'org.jetbrains.kotlin.klib' but the consumer didn't ask for it
                  - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
                  - Provides release status but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.native.target' with value 'macos_x64' but the consumer didn't ask for it
          - Variant 'macosArm64ApiElements-published' capability io.realm.kotlin:library-base:0.8.0 declares a usage of 'kotlin-api' of a library, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':
              - Unmatched attributes:
                  - Provides attribute 'artifactType' with value 'org.jetbrains.kotlin.klib' but the consumer didn't ask for it
                  - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
                  - Provides release status but the consumer didn't ask for it
                  - Provides attribute 'org.jetbrains.kotlin.native.target' with value 'macos_arm64' but the consumer didn't ask for it
          - Variant 'metadataApiElements' capability io.realm.kotlin:library-base:0.8.0 declares a usage of 'kotlin-api' of a library, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common':
              - Unmatched attributes:
                  - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
                  - Provides release status but the consumer didn't ask for it
          - Variant 'releaseApiElements-published' capability io.realm.kotlin:library-base:0.8.0 declares an API of a library, preferably optimized for Android, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
              - Unmatched attributes:
                  - Provides attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.1.0-beta05' but the consumer didn't ask for it
                  - Provides attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
          - Variant 'releaseRuntimeElements-published' capability io.realm.kotlin:library-base:0.8.0 declares a runtime of a library, preferably optimized for Android, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
              - Unmatched attributes:
                  - Provides attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.1.0-beta05' but the consumer didn't ask for it
                  - Provides attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
Reedyuk commented 2 years ago

Also my gradle.properties for my library:

kotlin.code.style=official
kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.enableDependencyPropagation=false
android.useAndroidX=true

org.gradle.jvmargs=-Xmx2048m
org.gradle.parallel=true

kotlin.native.binary.memoryModel=experimental
Reedyuk commented 2 years ago

Just further looking into this error, when doing the suggested in #612 my library is unable to find kotlin-metadata. When i check maven central: https://mvnrepository.com/artifact/io.realm.kotlin/library-metadata There is no library-metadata for version 0.8.0

Could this be the reason i am getting the error?

Also i think you should set this issue as open, as i dont think its currently resolved.

Reedyuk commented 2 years ago

Shot in the dark, based off this information: https://youtrack.jetbrains.com/issue/KT-49798 What version of the android plugin did you publish 0.8.0 with? 7.1.0-beta05?

Would you be able to publish 0.8.1 with 7.1.0-rc01? https://maven.google.com/web/index.html#com.android.tools.build:gradle:7.1.0-rc01

Reedyuk commented 2 years ago

@rorbech - added a pr for you to review to bump the android gradle to 7.1.0-rc01

rorbech commented 2 years ago

@Reedyuk Thanks, but I don't think bumping to 7.1.0-rc01 changes anything. I think I would have to setup a library and app project consuming it through mavenLocal to get the insight in where the attribute publishing/mismatches starts and how to align it. Are you able to share your sample project(s) so that I could test with that? Then I would also be able to verify if updating AGP should have any effect.

Reedyuk commented 2 years ago

i will try to if i get time, currently as it happens i only need read access to a pre-existing realm database so probably could get away without needing this.

Reedyuk commented 2 years ago

Android when reading properties also fails in the same way.

java.lang.NoSuchMethodError: No virtual method getValue$library_base_release(Lio/realm/internal/RealmObjectInternal;Ljava/lang/String;)Ljava/lang/Object; in class Lio/realm/internal/RealmObjectHelper; or its super classes (declaration of 'io.realm.internal.RealmObjectHelper' appears in /data/data/com.abc.android.searchFlowPrototype/code_cache/.overlay/base.apk/classes12.dex)
        at ingredients.getName(Main.kt:62)
        at com.abc.mp.viewModels.partner.partnersView.UDPartnersViewModel$2.invokeSuspend(UDPartnersViewModel.kt:70)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Reedyuk commented 2 years ago

@rorbech - Here is a sample project with the issue: https://github.com/Reedyuk/kmm-basic-sample/tree/Realm-Issue

I have worked out roughly what the issue is, it is around publishing to maven local, something seems to be missing or not being published.

When including a dependency via:

implementation(project(":shared"))

Its working, the realm db is returning values without crashing.

But if you:

./gradlew :shared:publishToMavenLocal

An make sure you are using this in the android dependencies:

implementation("KmmSample:shared-android:0.0.1") 

When running on an android client, then you will get the following error:

java.lang.NoSuchMethodError: No virtual method getValue$library_base_release(Lio/realm/internal/RealmObjectInternal;Ljava/lang/String;)Ljava/lang/Object; in class Lio/realm/internal/RealmObjectHelper; or its super classes (declaration of 'io.realm.internal.RealmObjectHelper' appears in /data/app/~~dic_-PdTDzrlbm3ihUBCGQ==/com.jetbrains.androidApp-tofoLNUfzj_xkDZPtYVCxw==/base.apk)
        at com.jetbrains.kmm.shared.ingredients.getName(Platform.kt:31)
        at com.jetbrains.kmm.shared.PlatformKt.initialize(Platform.kt:26)
        at com.jetbrains.kmm.androidApp.MainActivity.onCreate(MainActivity.kt:60)
        at android.app.Activity.performCreate(Activity.java:8000)
        at android.app.Activity.performCreate(Activity.java:7984)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Reedyuk commented 2 years ago

Any update on this? as its a real blocker from me using it with a big client of mine.

nhachicha commented 2 years ago

@Reedyuk a quick workaround could be to use -debug when in development mode (or when you want to run the debug version of the APK)

implementation("KmmSample:shared-android-debug:0.0.1")

You will also need to enable strict variant matching in your Gradle properties file

kotlin.android.buildTypeAttribute.keep=true

If you want to run your APK in release mode then specify a release signing block and use the release variant of the library as follow:

implementation("KmmSample:shared-android:0.0.1")

Android Gradle module

android {
    signingConfigs {
        getByName("debug") {
            keyAlias = "androiddebugkey"
            keyPassword = "android"
            storeFile = rootProject.file("debug.keystore")
            storePassword = "android"
        }
    }
buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            signingConfig = signingConfigs.getByName("debug")
        }
    }
...

This is needed because some methods in the published AAR dependencies are suffixed by the module name and variant ex

RealmObjectHelper.INSTANCE.getValue$library_base_release(this, "amount");

This causes the getValue method for instance to be not found if you're pulling the wrong variant (of the fallback variant i.e release while using a debug APK mode)

nhachicha commented 2 years ago

Fixed in 0.8.2