icerockdev / moko-resources

Resources access for mobile (android & ios) Kotlin Multiplatform development
https://moko.icerock.dev/
Apache License 2.0
1.07k stars 120 forks source link

Can't use Moko resources for JVM target #727

Closed VolodymyrVechirko-TomTom closed 3 months ago

VolodymyrVechirko-TomTom commented 3 months ago

Does MOKO resources support JVM target? I tried MOKO resources library for my KMP test project. There are 3 targets Android, iOS and jvm. Everything is Ok with Android and iOS, I can access resources. But the problem with jvm. I can't access to any of those.

The problem

val font1 = MR.fonts.roboto_medium.font -> This line causes error:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at JvmAppKt.main(JvmApp.kt:12)
Caused by: java.io.FileNotFoundException: Couldn't find font resource at: fonts/Roboto-Medium.ttf

val tt = MR.assets.text1_txt.readText() -> This line causes error:

Exception in thread "main" java.io.FileNotFoundException: Couldn't open resource as stream at: assets/text1.txt
    at dev.icerock.moko.resources.FileResource.readText(FileResource.kt:15)
    at JvmAppKt.main(JvmApp.kt:12)

val uu = MR.files.some_json.readText() -> This line causes error:

Exception in thread "main" java.io.FileNotFoundException: Couldn't open resource as stream at: files/some.json
    at dev.icerock.moko.resources.FileResource.readText(FileResource.kt:15)
    at JvmAppKt.main(JvmApp.kt:12)

MR.images.exit_left.image -> This line causes error:

Exception in thread "main" java.io.FileNotFoundException: Couldn't open resource as stream at: images/exit_left.svg
    at dev.icerock.moko.resources.ImageResource.readImage(ImageResource.kt:39)

System Info

KMP project used as a library. JVM client is a simple Kotlin app:

JvmApp.kt
fun main(args: Array<String>) {
//    val font1 = MR.fonts.roboto_medium.font
//    val tt = MR.assets.text1_txt.readText()
//    val uu = MR.files.some_json.readText()
    val icon = MR.images.exit_left.image
}

build.gradle.kts(:desktopApp)
plugins {
    alias(libs.plugins.kotlinJvm)
}

dependencies {
    implementation(project.project(":shared"))
}

KMP project

build.gradle.kts(:shared)
plugins {
    alias(libs.plugins.kotlinMultiplatform)
    alias(libs.plugins.androidLibrary)
    id("dev.icerock.mobile.multiplatform-resources")
}

kotlin {
    jvm()
    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "17"
            }
        }
    }

    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "Shared"
            export(libs.moko.resources)
        }
    }

    sourceSets {
        commonMain.dependencies {
        }
    }
}

multiplatformResources {
    resourcesPackage.set("shared")
    resourcesClassName.set("MR")
}

dependencies {
    commonMainApi(libs.moko.resources)
}

android {
    namespace = "org.example.project.shared"
    compileSdk = 34
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    defaultConfig {
        minSdk = 24
    }
}

I used latest version of MOKO resources 0.24.0-beta-5. My common source set structure:

- commonMain
  - kotlin
  - moko-resources
    - assets
      - text1.txt
    - files
      - some.json
    - fonts
      - Roboto-Medium.ttf
    - images
      - exit_left.svg
      - exit_right.svg
Alex009 commented 3 months ago

just check samples please

VolodymyrVechirko-TomTom commented 3 months ago

Do you mean this sample?

plugins {
    kotlin("multiplatform") // kotlin("jvm") doesn't work well in IDEA/AndroidStudio (https://github.com/JetBrains/compose-jb/issues/22)
    id("org.jetbrains.compose")
    id("dev.icerock.mobile.multiplatform-resources")
}

We need to use kotlin("multiplatform") with jvm target instead of kotlin("jvm") ?

VolodymyrVechirko-TomTom commented 3 months ago

I found the root cause. The problem was with my JVM app configuration. Now Jvm client works well with MOKO resources. App run command: ./gradlew desktopApp:run

Updated gradle build.gradle.kts(:desktopApp)

plugins {
    kotlin("jvm")
    id("application")
}

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

application {
    mainClass.set("JvmAppKt")
}

dependencies {
    implementation(project.project(":shared"))
}