Nikita Khlebushkin
02/23/2020, 7:37 PMios
and jvm
that contains class A:
class A {
fun foo() { ... }
}
and another KMP module called analytics with targets ios
and android
that contains class B:
actual class B : A() {
fun bar() { ... }
}
When I run ./gradlew :analytics:assembleRelease
, the analytics-release.aar artifact is generated, and when I plug it in Android library, I can do B().bar()
but not B().foo()
. What am I doing wrong?
EDIT
Added a project to reproduce the issue
https://gitlab.com/NikitaKhlebushkin/kmp-multi-modulekpgalligan
02/23/2020, 8:12 PMNikita Khlebushkin
02/23/2020, 8:33 PMArkadii Ivanov
02/23/2020, 8:48 PManalytics-interfase
dependency should be configured as api
(not as implementation
) for the analytics
module.Nikita Khlebushkin
02/23/2020, 8:57 PMsourceSets {
val commonMain by getting {
dependencies {
api(project(":analytics-interface"))
implementation(kotlin("stdlib-common"))
implementation(kotlin("reflect"))
}
}
}
russhwolf
02/23/2020, 9:48 PMNikita Khlebushkin
02/23/2020, 10:13 PMandroid
target in analytics project to jvm
, but it didn't helpB
class is expect/actual kind of classesrusshwolf
02/24/2020, 1:10 AMexpect
class can’t inherit, it’s that you need to have the exact same class hierarchy between expect
and actual
. There’s a youtrack ticket for it at https://youtrack.jetbrains.com/issue/KT-23703Nikita Khlebushkin
02/24/2020, 6:07 AMexpect class B: A()
, which is the only difference. Anything I could do about it?gmazzo
02/24/2020, 10:39 AMcommonMainApi(project(":a"))
Then the final binary for iOS or JS does not contains any class from ANikita Khlebushkin
02/24/2020, 10:42 AMgmazzo
02/24/2020, 10:47 AMA
, I’ve just added all src/x
of A
as a srcDir
of B
(and C
). A
was my common
module.Arkadii Ivanov
02/24/2020, 10:51 AMgmazzo
02/24/2020, 10:52 AMA
, that B
and C
should consume. Everything compiles just fine, but then when running those classes are missing.Arkadii Ivanov
02/24/2020, 10:53 AMactual class B : A
should not expose you A.gmazzo
02/24/2020, 10:56 AMclass A
is defined in a dependency module a
:
If a
is declared as implementation
, then actual class B : A
should fail to compile for exposing an internal class.
If a
is declared as api
then it should work ok.
But at least on my experience, class A
doesn’t exist at all on native or js targets in module b
artifact 😞Arkadii Ivanov
02/24/2020, 10:58 AMgmazzo
02/24/2020, 11:07 AMcommonJs
code for js
receives an injection dependency for the common module, as it’d expecting to have another native pacakge published for the common
module.
For JVM targets, you’ll see a dependency on the common
module JAR.
So I think this is an edge case not covered, because it doesn’t make sense to my that behaves differently depending on the platform:
for JVM: it uses the transitively model from the POM, with a common jar artifact
for Native and JS: it’s basically the same, expect that there is no dependency mechanism in place. A fat artifact is required then.
I think the “fast” workaround w’d be to produce fat artifacts for all the platforms. The “right” solution ’d be to support native artifact for each platforms: NPM modules and CocoaPodsNikita Khlebushkin
02/24/2020, 1:28 PM