You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为非Compose的KMP项目添加JavaFX桌面模块遇阻求助

非Compose KMP项目配置可运行JavaFX桌面模块

问题背景

我正在制作一个采用平台专属语言/UI的KMP模板项目(Android用XML视图、iOS用Swift和视图控制器、桌面端用JavaFX UI)。以不共享UI的KMP向导为基础添加桌面模块时,遇到了模块无法被识别为可运行项的问题:

  1. 在项目根目录创建desktop目录,settings.gradle.kt中添加include(":desktop")
  2. 从新建的JavaFX项目中复制build.gradle.kt和源码到desktop文件夹,结构如下:
-desktop
 -src
  -main
   -java
   -kotlin
   -resources
 -build.gradle.kt
  1. 配置了desktop模块的build.gradle.kt(代码见下方),但模块无法被识别为可运行项。

原desktop模块的build.gradle.kt配置:

plugins {
    java
    alias(libs.plugins.kotlinMultiplatform)
    application
    alias(libs.plugins.javaModularity)
    alias(libs.plugins.javafxPlugin)
    alias(libs.plugins.jlinkPlugin)
}

group = "com.example.desktop"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

val junitVersion = "5.10.0"

tasks.withType<JavaCompile> {
    options.encoding = "UTF-8"
}

application {
    mainModule = "com.example.desktop.demo2"
    mainClass.set("com.example.desktop.demo2.HelloApplication")
}

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

    sourceSets {
        val desktopMain by getting

        val commonMain by getting {
            dependencies {
                // Reference to the shared module
                implementation(projects.shared)
            }
        }

        desktopMain.dependencies{

        }
    }
}

javafx {
    version = "20.0.1"
    modules = listOf("javafx.controls", "javafx.fxml")
}

dependencies {
    implementation(projects.shared)
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
}

tasks.test {
    useJUnitPlatform()
}

jlink {
    imageZip.set(project.file("${buildDir}/distributions/app-${javafx.platform.classifier}.zip"))
    options = listOf("--strip-debug", "--compress", "2", "--no-header-files", "--no-man-pages")
    launcher {
        name = "app"
    }
}

tasks.register("jlinkZip2") {
    group = "distribution"
}

解决方案

1. 关联KMP JVM目标与运行入口

原配置中kotlin.jvm("desktop")和application插件的入口配置存在分离,导致Gradle无法识别运行项。需要将application配置移到JVM块内部,并添加withJava()确保Java代码被正确编译:

kotlin {
    jvm("desktop") {
        withJava()
        compilations.all {
            kotlinOptions {
                jvmTarget = "17"
            }
        }
        // 将application配置移至此处,绑定到当前JVM目标
        application {
            mainModule = "com.example.desktop.demo2"
            mainClass.set("com.example.desktop.demo2.HelloApplication")
        }
    }

    sourceSets {
        val desktopMain by getting {
            dependencies {
                implementation(projects.shared)
            }
        }
        val commonMain by getting
    }
}

2. 修复重复依赖问题

原配置中dependencies块和sourceSets.desktopMain.dependencies重复声明了projects.shared,统一将共享模块依赖移至desktopMain的依赖块,删除根级dependencies中的重复项:

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
}

3. 验证模块与类路径一致性

检查module-info.java(若存在)中的模块名是否和mainModule配置的com.example.desktop.demo2完全一致,同时确认HelloApplication类的包路径与配置中的主类路径完全匹配,避免因路径不匹配导致主类无法被找到。

4. 同步并验证运行项

完成配置修改后:

  • 点击IntelliJ中的「Sync Project with Gradle Files」按钮
  • 查看Gradle面板的desktop模块下,Application分组中会出现run任务,此时即可运行该模块

额外优化建议

  • 若项目未使用Java模块化,可移除javaModularity插件,减少配置复杂度
  • 确保JavaFX版本与JVM目标版本兼容(JVM 17建议使用JavaFX 17+版本)

内容的提问来源于stack exchange,提问作者tyczj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 04:35:57