Hello multiplatform experts and Kotlin enjoyers, ...
# multiplatform
s
Hello multiplatform experts and Kotlin enjoyers, We are authoring a multiplatform Jetpack Compose application, for Desktop / Android mostly (for now). We are running into a particular problem when using "JVM-common" source sets; these are source sets which define (mostly) models and other simple shared code, which need to be serializable and storable in engines like Room (i.e. just annotation-driven storage). These "JVM-common" platforms are needed because certain targets do not ship JS support. We use the Kotlin hierarchy APIs for this, which are in alpha. When we prepare a JVM common source set, these work fine downstream in JVM targets, but not in Android targets; in Android targets, our models show up as missing symbols in IDEA. Gradle builds these just fine, so it is clear Kotlin can resolve the types at the compiler level, but IDEA is not able to resolve them, suggesting that the tooling API cannot see them or the Kotlin daemon may have a bug. Has anybody encountered this before? Surely there has to be a way to share common code across "JVM-like" platforms, to include desktop JVM and Android.
a
Same issue on my project. You can install the Android plugin on IDEA (but it does not support last Android plugin version), or install Android studio to work on the Android side.
s
The default
jvmMain
doesn't target Android, because it include some desktop-only
javax
APIs. I usually deal with this by creating an
jvmAndAndroidMain
(or whatever name you desire) source set, and making the (desktop) JVM and Android source sets depend on it. KMP then automatically allows me to use only the shared APIs. Regarding builds working but the IDE still showing errors, it's because there's currently a disconnect between what the compiler sees at compile-time, and what is considered to be "correct". The IDE is right about the errors, but the compiler doesn't care about that, and if it finds all the APIs that are used, then the build will succeed. In fact, you could use platform-specific code in
commonMain
, and the build will succeed with no warning when you build for that particular platform, while the IDE will rightfully point out the error. JetBrains is working on making the compiler aware of platform boundaries, so errors (or at least warnings) will be raised on improper usage.
Here's the code:
Copy code
kotlin {
    ...

    // using dependsOn() disables the default hierarchy, so we need to re-apply it manually.
    applyDefaultHierarchyTemplate()

    sourceSets {
        commonMain.dependencies { ... }

        val jvmAndAndroidMain by creating {
            dependsOn(commonMain.get())
        }
        androidMain {
            dependsOn(jvmAndAndroidMain)
            dependencies { ... }
        }
        val jvmMain by getting {
            dependsOn(jvmAndAndroidMain)
            dependencies { ... }
        }
    }
}
Note that because we're using
dependsOn
, the default KMP hierarchy gets disabled, so we have to explicitly apply it using
applyDefaultHierarchyTemplate
For nicer names, I usually rename
jvmMain
to
desktopMain
, keeping the
jvmMain
name for the one shared between
desktopMain
and
androidMain
.
s
@Skaldebane Thank you for your response here; We've tried this approach, but in downstream Android libs some symbols end up invisible. Have you encountered that?
I wonder if it's temporary in IDEA, because still Gradle builds it fine.
@alexandre mommers Are you saying you guys do not experience those type issues in IDEA? We will give that a try. Thank you
(Thank you as well @Skaldebane)
s
@Samuel Gammon That's quite interesting. My use case was some Ktor sockets code that was shared between JVM and Android, but not other platforms, and I've not encountered any issues with that. It's a couple of functions and classes, which are then consumed directly by common code, which is maybe why I've not encountered this issue (I don't use it from Android platform-specfic code). If the behavior seems unexpected or erroneous, it may be worth it to open an issue for this on YouTrack, and see what JetBrains has to say.
a
@Samuel Gammon As shown in the screenshot, IntelliJ IDEA on the left doesn't recognize "androidMain" and lacks syntax highlighting, unlike Android Studio on the right where everything appears normal.
s
@alexandre mommers I think that's not the issue he's facing. As for what you're talking about, it seems like you're missing the Android plugin in IntelliJ IDEA (otherwise something's wrong). However note that the Android plugin doesn't yet support the latest version of IntelliJ IDEA (2024.2) so that might be why. I just noticed that today after I upgraded awkward monkey
a
@Skaldebane even with the android plugin the androidMain source set is not recognized while gradle is compiling fine. Note, two week ago, the android code was red with error on IDEA, something change, may be an update.
s
Oh wait, the Android plugin actually has an update; I'll update and respond to you.
It seems to be working fine. With Kotlin 2.0 and IntelliJ IDEA.
(note that I have
iosMain
and
wasmJsMain
intentionally disabled)
The run configuration is available and I can build and run just fine.
So it's maybe something with your particular Gradle configuration?