NativeScript/android

`You are trying to set "Companion" which is a final field!` when using Kotlin classes in NS

tailsu opened this issue ยท 11 comments

Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project:

  • CLI: 4.2.4
  • Cross-platform modules:
    "nativescript-theme-core": "~1.0.4",
    "tns-core-modules": "~4.2.0"
  • Android Runtime: 4.2.0
  • iOS Runtime (if applicable):
  • Plugin(s):

Describe the bug
Calling new SomeClass() fails with Error: You are trying to set "Companion" which is a final field! Final fields can only be read. if SomeClass is a Kotlin class with a companion object.

To Reproduce
kotlinplugin.zip

Add (tns plugin add) the attached plugin into a new {N} project. Import and execute:

var test = require("nativescript-kotlintest");
test.doTest();

index.js of NS plugin:

module.exports = {
    doTest: function() {
        new com.example.stedra.myapplication.ScanbotSDKInitializer(); // <-- this crashes
    }
};

ScanbotSDKInitializer.kt:

package com.example.stedra.myapplication

class ScanbotSDKInitializer {
    companion object {
        private var initialized = false

        @JvmStatic
        fun isInitialized() = initialized
    }

    fun initialize() {
        initialized = true
    }
}

Expected behavior
To not crash.

Additional context
Kotlin companion objects are implemented using a nested class SomeClass$Companion and a field named Companion of that same type in SomeClass. This doesn't seem to be possible with Java itself, but the JVM seems OK with it. The clash of type and field names or the non-standard implementation of the nested class might be the reason for this buggy behavior.

Hi,
I just re-tried it with NativeScript 5 (CLI 5.1.0) and the error still persists:

System.err: com.tns.NativeScriptException: 
System.err: Calling js method onViewAttachedToWindow failed
System.err: 
System.err: Error: You are trying to set "Companion" which is a final field! Final fields can only be read.
System.err: File: "file:///data/data/org.nativescript.Tns5PlaygroundVanilla/files/app/tns_modules/nativescript-kotlintest/index.js, line: 4, column: 45
System.err: 
System.err: StackTrace: 
System.err: 	Frame: function:'doTest', file:'file:///data/data/org.nativescript.Tns5PlaygroundVanilla/files/app/tns_modules/nativescript-kotlintest/index.js', line: 4, column: 46

@darind Are there plan when this will be adressed? With the increasing usage ob Kotlin in Android (including libs) it seems to become more and more relevant.

If you see anything I can provide to support solving this, please let me know, would be happy to contribute and help this getting solved.

Hi,
Any help on this??

Hi, we are looking into addressing this issue. As a possible workaround, the kotlin method that you would like to consume from javascript can be wrapped in a plain Java method - either as a NativeScript plugin or directly as a .java file in the App_Resources folder.

This is becoming more of a problem with kotlin gaining adoption for Android libraries. I've personally run into it also forgetting that it's not compatible.

Curious if there is a sample of the workaround. I'm not really following the "wrapped in a plain Java method"

@bradmartin, the suggested workaround is to write a Java module that contains some plain Java classes calling into the Kotlin library. Then in your NativeScript application you will directly consume the exposed Java classes instead of trying to call the Kotlin library.

Understand now. Just not thrilled about it. Any discussion internally about this in recent months? Anything that I could possibly explore to provide insight?

I had a similar problem when I started writing my last lib in kotlin ... I had to revert to java hoping this can be addressed soon

I am stucked in a plugin also as described here.

Any update on this please? Kotlin is now super popular and many libraries are now developed with it. This issue makes it impossible to write plugin of those native libraries! Hope someone will update if we can expect anything on this soon.

@sam0829 try updating to at least 6.1 or the latest

@triniwiz indeed. I just tried with 6.2 and my plugin is working now as expected.