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

Spring Boot Kotlin项目Jar执行报NoClassDefFoundError问题求助

问题现象与需求

通过Spring Initializr创建了一个Spring Boot项目,构建后的Jar文件无法执行,报错如下:

java -jar build/libs/spring302-0.0.1-SNAPSHOT-plain.jar 
Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
        at com.kaede.spring302.Spring302ApplicationKt.main(Spring302Application.kt)
Caused by: java.lang.ClassNotFoundException: kotlin/jvm/internal/Intrinsics
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
        ... 1 more

需要解决该问题以将项目构建为Docker镜像,请问该如何处理?

项目创建信息

选择的配置如下:

  • Kotlin
  • Gradle 7.2
  • Spring 3.0.2
  • Java 17
    使用IntelliJ进行构建,项目名称为spring302,命名空间为com.kaede。
已尝试的解决步骤

1. 添加Manifest主类配置

最初直接构建后执行Jar报错:

java -jar build/libs/kotlin1-0.0.1-SNAPSHOT-plain.jar

Error: Could not find or load main class

于是在spring302/build.gradle.kts中添加Manifest主类配置:

tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "com.kaede.spring302.Spring302Application"
    }
}

执行后又报错:

java -jar build/libs/spring302-0.0.1-SNAPSHOT-plain.jar
Error: Main method not found in class com.kaede.spring302.Spring302Application, 
please define the main method as:
   public static void main(String[] args)

提示找不到符合Java规范的main方法。

2. 修改主类为classNameKt

了解到Kotlin类编译后会生成classNameKt类,于是修改主类配置:

tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "com.kaede.spring302.Spring302ApplicationKt"
    }
}

执行后出现NoClassDefFoundError:

java -jar build/libs/spring302-0.0.1-SNAPSHOT-plain.jar
Exception in thread "main" java.lang.NoClassDefFoundError: 
kotlin/jvm/internal/Intrinsics
        at com.kaede.spring302.Spring302ApplicationKt.main(Spring302Application.kt)
Caused by: java.lang.ClassNotFoundException: kotlin/jvm/internal/Intrinsics
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
        ... 1 more

通过javap命令确认该类存在main方法:

javap spring302-0.0.1-SNAPSHOT-plain/com/kaede/spring302/Spring302ApplicationKt.class 
Compiled from "Spring302Application.kt"
public final class com.kaede.spring302.Spring302ApplicationKt {
  public static final void main(java.lang.String[]);
}

3. 删除本地仓库后重新构建

执行命令删除本地Maven仓库:

rm -rf ~/.m2/repository 

重新构建后问题仍未解决。

4. 修改main方法实现

将main方法从:

runApplication<Spring302Application>(*args)

修改为:

SpringApplication.run(Spring302Application::class.java, *args)

但依然出现NoClassDefFoundError。

完整build.gradle.kts配置
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "3.0.2"
    id("io.spring.dependency-management") version "1.1.0"
    kotlin("jvm") version "1.7.22"
    kotlin("plugin.spring") version "1.7.22"
}

group = "com.kaede"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "17"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}
tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "com.kaede.spring302.Spring302ApplicationKt"
    }

}
解决方案

你当前构建的是plain jar(仅包含项目自身class文件,不含任何依赖),所以运行时找不到Kotlin标准库等依赖类。Spring Boot Gradle插件提供的bootJar任务才能构建包含所有依赖的可执行fat jar,这是Spring Boot项目正确的可执行jar构建方式。

步骤1:移除自定义Jar任务配置

删除build.gradle.kts中这段自定义配置:

tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "com.kaede.spring302.Spring302ApplicationKt"
    }
}

Spring Boot插件会自动识别Kotlin主类(包括生成的*Kt类),无需手动配置Manifest。

步骤2:构建可执行fat jar

执行Gradle的bootJar任务:

./gradlew bootJar

构建完成后,可执行jar会生成在build/libs/spring302-0.0.1-SNAPSHOT.jar(无-plain后缀)。

步骤3:测试运行Jar

运行生成的fat jar:

java -jar build/libs/spring302-0.0.1-SNAPSHOT.jar

此时应用应能正常启动,不会再出现NoClassDefFoundError。

步骤4:用于Docker构建

直接使用该fat jar编写Dockerfile,示例如下:

FROM openjdk:17-jdk-slim
WORKDIR /app
COPY build/libs/spring302-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

补充说明

  • plain jar是Gradle默认Jar任务的产物,仅适用于作为依赖被其他项目引用,无法单独运行。
  • bootJar任务会自动打包所有依赖到jar中,并配置好启动类和类加载器,是Spring Boot项目的标准构建方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:40:34