As I understand from this bug - <https://youtrack....
# javascript
m
As I understand from this bug - https://youtrack.jetbrains.com/issue/KT-43500 - it seems like IR Javascript compilation fails when dealing with any compileOnly dependency. Now that the Legacy compiler is deprecated, this would mean that compileOnly dependencies cannot be used for Javascript at all. That seems very unfortunate.
b
What's your use-case for such dependencies in js?
m
My use case is as follows: I have created a symbol processor that makes Android's Room work with Kotlin multiplatform (by generating JVM/JS code). Now I need to be able to use Androidx.room annotations on code that I want to compile on JVM/JS. So I created a module with copies of those annotations, and included it as a compileOnly dependency. If I use an implementation dependency, then I would get a duplicate class error. I think my use case is the standard use case for compileOnly: I want to compile against one implementation, but then be able to use a different implementation at runtime.
b
I see, I think rather than plain copying jvm room annotations, you should create a kmp module that declares expect/actual for those annotations and just typealias them to room annotations on jvm actuals. This is a solution to your immediate problem and NOT an argument against your use-case for compileOnly dependency support
m
Thanks, I did try going down the expect/actual path - but I hit two big problems: 1. You can't include default values in the expect declaration if you use a typealias. So that means any multiplatform code would have to explicitly specify every argument and defaults wouldn't work
b
Although now that I think about it, it might not be an issue with compileOnly, but rather incorrect kmp dependency module that doesn't support all required targets
m
2. The symbol processor (since 1.7) won't resolve expect/actual annotations by default. The annotation processor author has to do that themselves. So when Room's own annotation processor runs, it won't recognize expect/actual as the same thing
b
Legacy js compiler was known to be very lax when it came to enforcing kmp requirements
When room runs it should see only room annotations on jvm. No idea what happens on js
m
It definitely isn't an issue with supporting all kmp targets: I used the same code on JVM and JS
I used a shared source set... e.g. for all non-Android supported targets
b
Got it, I might be wrong then
You mean without declaring all the targets on shared that the consumer module uses?
m
Sorry I don't understand what you mean "without declaring all target on shared that the consumer module uses?"
b
In order to use a kmp library, it must declare and be compiled for all the targets that your consumer uses
m
That is the case... they are both my projects...
b
For example if you have a module that declares js and jvm targets, you can only use libs in commonMain that also declare js and jvm
m
The module itself compiled for JS(BOTH), JVM, and Android
the consumer would compile for Js(legacy), JVM, and Android
b
Regardless if the lib is remote (mavenCentral) or local (module)
m
But if I set the consumer to Js(IR) - then I get the same as error as mentioned on the bug report
👍 1
b
Gotcha, ignore all I said then. Looks like your kmp setup is correct at the very least 😀
Note that that particular error is very generic and happens in many different cases, not just the ones reported there.
m
For now, I could try using exclude on gradle to try and block an implementation dependency from coming into Android
Yes - I see the error itself is quite generic - but what struck me is what I'm doing is exactly the same - using compileOnly for an annotation dependency
My point being to not discount the possibility that your issue might be unrelated
m
I really hope not - I have spent most of the days working on / trying/ thinking about ways around it.
I will try using the dependency as an implementation and exclude to avoid it coming onto Android. Not ideal, but could workaround the issue for now. If that works, I'll message back and maybe add to the discussion on the bug report.
b
You're not alone, lots of people have wasted days on that error
m
The bug report does have an attached basic reproduction case... that was done back in Kotlin 1.4 days...
I think it would be worth testing the reproduction case against Kotlin 1.8 - if it still doing that, then I think it is something that really needs looked at. compile only transitive dependencies are a standard feature, so if IR is now the production system, it should handle that
b
Agreed, especially since IR is in beta already
👍 1
No, wait. It's stable already since 1.8
m
Legacy is deprecated as I understand... all Kotlin/JS has to move over to IR
Exclude dependencies feature missing on Kotlin Multiplatform - oh goodie: https://youtrack.jetbrains.com/issue/KT-31340/Exclude-transitive-dependencies-for-project-dependencies
Sure enough - after I remove use of compileOnly in the dependency, the consumer app compiles using IR on Javascript