Hi all, I’m running into an issue with a Kotlin mu...
# multiplatform
a
Hi all, I’m running into an issue with a Kotlin multi-platform/multi-project (is there a better term for that?) gradle build. Most of the sub-projects are common Kotlin code but the one I’m having issues with is JVM only and I’m trying to make it use the gradle application plugin. At first, I tried to just get a simple “Hello, World” application working and I got that working after I realized that besides including the application plugin and configuring the main class I also needed the following:
Copy code
tasks.named<JavaExec>("run") {
  dependsOn(tasks.named<Jar>("jvmJar"))
  classpath(tasks.named<Jar>("jvmJar"))
 }
Now the simple app works when I do
gradle run
, but when I depend on code from other sub-projects that are just common code when I run the application I get
java.lang.NoClassDefFoundError
exceptions for the classes from the common sub-projects. (
gradle check
runs fine btw) I’m assuming this is an issue with how I have the application plugin setup, but I’m not sure what changes need to be made.
m
I'd recommend using the
"application"
plugin with
"org.jetbrains.kotlin.jvm"
(and not
"org.jetbrains.kotlin.multiplatform"
)
Not sure the "application" plugin work with the Kotlin mutliplatform one. I've had issues with tihs in the past
Might be doable but it seems less straightforward than the JVM only thing
a
Okay I'll try that, it didn't occur to me that I could have some projects multi-platform and others just jvm, but that makes sense. Thanks.
Cool that worked, thanks again!
o
Just for the record: You can use the
application
plugin with multiplatform, but you have to add
withJava()
in the
kotlin.jvm()
block to work around https://youtrack.jetbrains.com/issue/KT-42683. Actually, you don't even need the
application
plugin, and without it, you can have more than one executable JVM target. For example, configuring it this way runs
backendJvm
and
frontendJvm
targets:
Copy code
tasks {
    @Suppress("UNUSED_VARIABLE")
    val runBackendJvm by creating(JavaExec::class) {
        group = "application"
        mainClass.set("MainKt")
        jvmArgs = backendJvmArgs
        with(kotlin.targets["backendJvm"].compilations["main"] as KotlinJvmCompilation) {
            classpath = output.allOutputs + runtimeDependencyFiles
        }
    }

    @Suppress("UNUSED_VARIABLE")
    val runFrontendJvm by creating(JavaExec::class) {
        group = "application"
        mainClass.set("MainKt")
        with(kotlin.targets["frontendJvm"].compilations["main"] as KotlinJvmCompilation) {
            classpath = output.allOutputs + runtimeDependencyFiles
        }
    }
}