Gradle Kotlin项目中需显式设置mainClass为编译后的JVM类名(如"com.example.MainKt"),使用application { mainClass.set("...") },且必须应用application插件;Spring Boot项目应禁用该配置,改用bootRun或bootJar。

Gradle Kotlin 项目中如何设置可执行 JAR 的 mainClass
Gradle 默认不自动识别 Kotlin 的 main 函数作为入口,必须显式声明。Kotlin 编译后生成的类名是 MainKt(若文件叫 Main.kt 且在默认包下),不是 Main;如果用了包声明或自定义文件名,类名会变成 com.example.MyAppKt 这类形式。
在 build.gradle.kts 中配置 application 插件时,mainClass 必须设为编译后的 JVM 类名,而非 Kotlin 源码里的函数名:
application { mainClass.set("com.example.MainKt") }- 确保已应用
application插件:plugins { application } - 若用
fun main()顶层函数,Kotlin 编译器会生成xxxKt类;若用object App { fun main() },则类名就是App - 运行前先执行
./gradlew build,检查build/classes/kotlin/main/下生成的 class 文件名是否匹配你写的mainClass
用 JavaExec 任务临时运行某个 Kotlin main 函数
适合快速验证、调试单个 main 函数,不用打包整个应用。和 application 插件无关,纯任务驱动。
在 build.gradle.kts 中注册一个临时任务:
tasks.register<JavaExec>("runDemo") {
classpath = sourceSets.main.runtimeClasspath
mainClass.set("demo.HelloWorldKt")
// 可选:传参
args("--verbose", "test")
}
常见坑点:
- 忘记设置
classpath→ 报NoClassDefFoundError - 写错类名,比如写成
HelloWorld而不是HelloWorldKt→ 报ClassNotFoundException - 没加
sourceSets.main.runtimeClasspath,只写了sourceSets.main.output→ 缺少依赖,运行时报NoSuchMethodError
Kotlin DSL 中 mainClass 是 String 还是 Provider?
Gradle 7.0+ 强制要求 mainClass 使用 Property<string></string>,直接赋值字符串会警告甚至失败。必须用 set() 或 convention()。
正确写法(Kotlin DSL):
application {
mainClass = project.objects.property(String::class.java)
mainClass.set("com.example.LauncherKt")
}
错误写法(会触发 deprecation warning):
application {
mainClass = "com.example.LauncherKt" // ❌ 不推荐,Gradle 8+ 可能报错
}
如果你在 CI 或多模块项目里动态决定入口类,建议统一用 project.findProperty("mainClass") 配合 set(),避免硬编码。
为什么 runApplication 或 Spring Boot 启动类不生效?
Spring Boot 项目里,即使你写了 fun main(),也不要手动设 mainClass。Spring Boot Gradle 插件会自动推导并注入自己的启动逻辑,覆盖原始入口。
此时应:
- 确认已启用
org.springframework.boot插件 - 删掉
application { mainClass.set(...) }块 - 改用
./gradlew bootRun启动,它内部调用的是org.springframework.boot.devtools.restart.RestartLauncher - 若需生成可执行 JAR,用
./gradlew bootJar,它的 MANIFEST.MF 自带正确的Main-Class: org.springframework.boot.loader.JarLauncher
强行指定 mainClass 会导致 Spring 初始化流程跳过,Bean 不加载,@SpringBootApplication 注解失效。


















