Spring Boot Kotlin 项目用gradle构建运行时报错 “NoSuchMethodException“ 的问题排查与解决
使用 Kotlin 和 Spring Boot 构建 REST 服务。在 Kotlin 中,顶层函数默认会被编译到独立的类中,并添加。但 Spring Boot 默认查找入口方法时,只会寻找。这导致 Spring Boot 无法找到正确的入口方法,抛出。,因为它简单且更符合 Kotlin 的特性,无需改变代码逻辑。无论采用哪种方案,重新构建后,确保 JAR 包的。后缀类中),只需修改 Gradle
Spring Boot Kotlin 项目用gradle构建运行时报错 “NoSuchMethodException” 的问题排查与解决
在开发基于 Spring Boot 和 Kotlin 的项目时,构建成功但运行时出现以下错误:
Exception in thread "main" java.lang.NoSuchMethodException: site.achun.biz.share.ShareApplication.main([Ljava.lang.String;)
at java.base/java.lang.Class.getDeclaredMethod(Class.java:2675)
...
问题背景
报错场景
-
使用 Kotlin 和 Spring Boot 构建 REST 服务。
-
构建工具为 Gradle。
-
项目结构清晰,顶层入口定义如下:
@SpringBootApplication class ShareApplication fun main(args: Array<String>) { runApplication<ShareApplication>(*args) }
关键日志
运行 JAR 包时,报以下错误:
Exception in thread "main" java.lang.NoSuchMethodException: site.achun.biz.share.ShareApplication.main([Ljava.lang.String;)
排查发现
通过 javap 检查生成的类文件,发现 main 方法并未生成在 ShareApplication.class 中,而是被编译到了 ShareApplicationKt.class。
问题分析
在 Kotlin 中,顶层函数默认会被编译到独立的类中,并添加 Kt 后缀。例如,main 方法会被放入 ShareApplicationKt.class 中。但 Spring Boot 默认查找入口方法时,只会寻找 Start-Class 指向的类中的 main 方法。
具体来说:
Start-Class的值:定义在build.gradle.kts的application.mainClass中,默认为ShareApplication。- 实际入口方法所在的类:
ShareApplicationKt。
这导致 Spring Boot 无法找到正确的入口方法,抛出 NoSuchMethodException。
解决方法
针对该问题,有两种常用解决方案:
方案 1:将 main 方法移入类中
为了兼容 Java 的传统规范,可以将 main 方法移入 ShareApplication 类中。修改后的代码如下:
@SpringBootApplication
class ShareApplication {
companion object {
@JvmStatic
fun main(args: Array<String>) {
runApplication<ShareApplication>(*args)
}
}
}
关键点:
- 使用
companion object声明静态上下文。 - 添加
@JvmStatic注解,确保生成静态的main方法。
完成后,重新构建并运行:
./gradlew clean build
java -jar build/libs/achun-biz-share-1.0-SNAPSHOT.jar
方案 2:修改 Start-Class 指向 ShareApplicationKt
如果希望保持 Kotlin 的默认行为(顶层函数保留在 Kt 后缀类中),只需修改 Gradle 的 mainClass 配置:
在 build.gradle.kts 中,更新 application 插件的 mainClass 配置:
application {
mainClass.set("site.achun.biz.share.ShareApplicationKt")
}
然后重新构建:
./gradlew clean bootJar
java -jar build/libs/achun-biz-share-1.0-SNAPSHOT.jar
效果:
- Spring Boot 的
Start-Class会正确指向ShareApplicationKt,找到入口方法。
验证
检查 META-INF/MANIFEST.MF
无论采用哪种方案,重新构建后,确保 JAR 包的 META-INF/MANIFEST.MF 文件包含以下内容:
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: site.achun.biz.share.ShareApplicationKt
验证入口类
检查生成的类文件,确认 main 方法位置是否正确:
javap -c build/classes/kotlin/main/site/achun/biz/share/ShareApplicationKt.class
最终选择
我们最终采用了 方案 2,因为它简单且更符合 Kotlin 的特性,无需改变代码逻辑。
总结
经验教训
- Kotlin 项目中,顶层函数默认会被编译到独立的
Kt类中。 - Spring Boot 默认只在
Start-Class指向的类中查找main方法。
推荐方法
- 如果追求与 Java 的兼容性,推荐使用 方案 1。
- 如果希望充分利用 Kotlin 特性,可以选择 方案 2,只需在 Gradle 中调整
mainClass配置。
常用排查命令
- 查看 JAR 包内容:
jar -tf build/libs/<your-jar>.jar - 检查
META-INF/MANIFEST.MF:unzip -p build/libs/<your-jar>.jar META-INF/MANIFEST.MF - 查看生成的类文件:
javap -c build/classes/kotlin/main/<your-class>.class

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)