JsName and JVMName cannot be used in the same project

I am trying to create a library that can both be compiled into jar file for an Android project and transpiled to JavaScript for a Node.js project.

The code is exactly the same for both platforms and has no platform specific parts. Therefor, I don’t want to split it in common and platform specific code and I don’t want to create custom interfaces (facades) for each platform.

The problem is that a lot of the names get mangled. I know about the @JsName and @JVMName annotations, but they are not compatible with each other and:

  • kotlin plugin doesn’t understand @JVMName;
  • kotlin2js plugin doesn’t understand @JsName.

I searched for a solution but didn’t find a good one.

I hope you can help me!

Best Regards,
Alex

1 Like

You will have to create a normal multi-platform project. Just put all your code into the common project. You still have to create a js and android module, but you don’t have to add any code to it. Just make sure that the build file is set up correctly.
If you later need any platform specific code you can just add it to the platform modules and add expect functions to the common module.

Woops. Now that I said that, there is still one problem, but it should be fixed in 1.2.60 I think, not sure
see here for more info:

https://youtrack.jetbrains.com/issue/KT-18882
https://youtrack.jetbrains.com/issue/KT-24478

@Wasabi375, thank you for the reply! I have already checked the ticket mentioned by you. The fact that it is not yet present and nobody confirmed that it will be is concerning for me and is the reason to post my ticket.

Anyway, thanks again for the quick reply and lets hope they add JsName in the common library

I just tried the early access preview of Kotlin v1.2.60, as described in this post:

And the JsName annotation is not added in the common library.

Woops, looks like only one of the 2 tickets is part of 1.2.6. Looks like KT-24478 has no target version yet. My bad.

To clarify, in 1.2.60 we introduced a mechanism to declare such annotations in common code, so that they would be available on platforms (@OptionalExpectation, described in KT-18882). We did not yet add all relevant annotations to the common standard library. This requires more changes, which will (unfortunately) likely not make it into 1.2.60. They are tracked under KT-24478.

You can of course create your own expect annotations that are typealiased to the platform ones on the platform or implemented as (source only) dummies on platforms that don’t have that annotation. It works (even on 1.2.51) with some limitations - first of which is that intellij doesn’t like it (there are still numerous multiplatform limitations in intellij). If you are happy to ignore warnings you can even use the EAP plugin in intellij while targeting 1.2.51.

1 Like

Any update on this topic? I don’t see any resolution yet.

@aleks.p.petrov Since Kotlin 1.2.70 you can use both JsName and JvmName annotations in common code.

However you can’t just take that code and compile it twice — for JS and JVM, you need to structure it as a multiplatform project, that distinguishes common and platform specific code. You can read more about the current approach to authoring multiplatform projects here:
https://kotlinlang.org/docs/reference/multiplatform.html
https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html