KMP Expect classes that implement an interface throw "class is not abstract" error
Describe the bug
In our multi-module KMP project, we are using expect/actual classes. We added the new Koin annotations to the project and the kspCommonMainKotlinMetadata gradle task throws an error. The following class, which extends KoinModulesProvider interface (defines a single method provideModules()) shows an error:
expect class XyModuleProvider() : KoinModulesProvider
Error:
Class 'XyModuleProvider' is not abstract and does not implement abstract member 'provideModules'.
Is this a bug or a behavior, that will not change?
Expected behavior No code change is required
Current Fix
Override the interface method in the expect class and use actual override in the actual implementations of the expect class.
Koin project used and used version koin-core = "4.1.0-Beta1" koin-annotations = "2.0.0-Beta3" koin-compiler = "2.0.0-Beta3"
what your KoinModulesProvider provides? is it working in non KMP project?
It is used in a KMP project. KoinModulesProvider is an entry point for the client apps, that do not use Koin to set up the KMP library and provide data needed for Koin dependencies to work
For example this is how the iOS app sets up logging:
class IosNetworkLoggerModuleProvider(private val networkLogger: NetworkLogger) : KoinModulesProvider {
override fun provideModules(): List<Module> = listOf(
module {
single<NetworkLogger> { networkLogger }
},
)
}
coupling it to Module is not ideal, for now. Class module are intended to be agnostic for now. Let's see it as a feature proposal for 2.1
@AmkSk isn't this a K2 issue linked to expect classes implementing interfaces?
https://youtrack.jetbrains.com/issue/KT-59739/K2-MPP-reports-ABSTRACTMEMBERNOTIMPLEMENTED-for-inheritor-in-common-code-when-the-implementation-is-located-in-the-actual
I guess you should explicitly indicate the KoinModulesProvider functions as override in your expect declaration and then mark actual the implementation of these functions.
interface Foo {
fun bar()
}
expect class FooImpl : Foo {
override fun bar()
}
// in platform source sets
actual class FooImpl : Foo {
actual override fun bar() {}
}
I had the same on my side for another case unrelated to Koin and changing that way fixed the issue.
What I don't understand though, is that it worked like a charm, I just added iOS target, it was working, and only ./gradlew --info fails like that, IDE is fine, another gradle task seems fine too…
anyone tried with last Koin updates?
let's reopen if needed