android jetpack compose - How to name expectactual classes in Kotlin Multiplatform? - Stack Overflow

I'm implementing Room in KMP project, and I'm trying to use expectactual to generate the cre

I'm implementing Room in KMP project, and I'm trying to use expect/actual to generate the createDatabaseBuilder() method which is platform dependent. I placed it in my Database.kt file on my commonMain platform:

expect fun createDatabaseBuilder(): RoomDatabase.Builder<Database>

I placed the actual fun createDatabaseBuilder() on the same Database.kt file with the same name and the same package but in the desktopMain platform, but I'm getting this exception when building:

Database.kt:1:1 Duplicate JVM class name 'com/package/myapp/data/datasource/local/DatabaseKt' generated from: DatabaseKt, DatabaseKt

I got this exception in both classes with the same name, the one placed in commonMain and the one placed in desktopMain. If I rename the desktopMain class to Database.jvm.kt class, then it works.

Why is necessary to add that .jvm on the actual class? I'm using expect actual for some other functionalities of the application and I didn't have this issue on them. In these cases I'm using also the same package and the same file name, without the jvm, and it doesn't give this error. I checked the documentation about using expect/actual in multi-platform, and can't find the explanation of this. They just say this:

The expected and actual declarations should be defined in the same package and merged into one declaration in the resulting platform code

But they don't tell how to name the class and how to deal with this exception. I tried adding .jvm because I found that name style on a sample project from an independent repo.

Edit

I'm adding here other file where I'm doing also expect/actual, but I'm not having this problem, and the file can be called exactly the same. The file is called Util.kt in both cases, in same package also.

Expect file Util.kt:

expect fun getAppDataPathPD(appName: String): String

object Util {
    fun getAppDataPath(appName: String) = getAppDataPathPD(appName)
}

Actual file Util.kt:

actual fun getAppDataPathPD(appName: String): String {
    //STUFF
}

I'm implementing Room in KMP project, and I'm trying to use expect/actual to generate the createDatabaseBuilder() method which is platform dependent. I placed it in my Database.kt file on my commonMain platform:

expect fun createDatabaseBuilder(): RoomDatabase.Builder<Database>

I placed the actual fun createDatabaseBuilder() on the same Database.kt file with the same name and the same package but in the desktopMain platform, but I'm getting this exception when building:

Database.kt:1:1 Duplicate JVM class name 'com/package/myapp/data/datasource/local/DatabaseKt' generated from: DatabaseKt, DatabaseKt

I got this exception in both classes with the same name, the one placed in commonMain and the one placed in desktopMain. If I rename the desktopMain class to Database.jvm.kt class, then it works.

Why is necessary to add that .jvm on the actual class? I'm using expect actual for some other functionalities of the application and I didn't have this issue on them. In these cases I'm using also the same package and the same file name, without the jvm, and it doesn't give this error. I checked the documentation about using expect/actual in multi-platform, and can't find the explanation of this. They just say this:

The expected and actual declarations should be defined in the same package and merged into one declaration in the resulting platform code

But they don't tell how to name the class and how to deal with this exception. I tried adding .jvm because I found that name style on a sample project from an independent repo.

Edit

I'm adding here other file where I'm doing also expect/actual, but I'm not having this problem, and the file can be called exactly the same. The file is called Util.kt in both cases, in same package also.

Expect file Util.kt:

expect fun getAppDataPathPD(appName: String): String

object Util {
    fun getAppDataPath(appName: String) = getAppDataPathPD(appName)
}

Actual file Util.kt:

actual fun getAppDataPathPD(appName: String): String {
    //STUFF
}
Share Improve this question edited Feb 3 at 22:38 halfer 20.4k19 gold badges109 silver badges202 bronze badges asked Jan 31 at 10:25 NullPointerExceptionNullPointerException 37.9k80 gold badges231 silver badges405 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

This is because the expect/actual functions in this case are top-level. Java doesn't have top-level functions, so kotlin creates a class that contains all the top-level functions from that file as static functions. This class is by default named FileNameKt. So you end up with multiple classes of same name and same package.

One way to get around this is a different filename, as you discovered. The convention in android repos is FileName.platform.kt, as you mentioned.

Another possibility is to use @JvmName annotation which allows you to change the name of the generated class to whatever you like:

@file:JvmName("JvmDatabase")
package ...

actual fun createDatabaseBuilder(): RoomDatabase.Builder<Database> {}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745268740a4619615.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信