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

部署Spring Boot应用至Heroku时遇ClassNotFoundException问题求助

Heroku部署Spring Boot应用出现NoClassDefFoundError: org/springframework/boot/SpringApplication

问题描述

项目包含两个功能:

  • 向用户问好
  • 获取用户名并保存至PostgreSQL数据库,随后以该名称向用户问好

本地测试运行正常,但部署到Heroku后启动失败,报错如下:

heroku[web.1]: Starting process with command java -Dserver.port=11441 $JAVA_OPTS -jar build/libs/*.jar
app[web.1]: Setting JAVA_TOOL_OPTIONS defaults based on dyno size. Custom settings will override them.
app[web.1]: Picked up JAVA_TOOL_OPTIONS: -XX:+UseContainerSupport -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 
app[web.1]: Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication
app[web.1]:     at com.pro.library.Application.main(Application.java:10)
app[web.1]: Caused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication
app[web.1]:     at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
app[web.1]:     at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
app[web.1]:     at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)

怀疑是jar包构建问题,但查阅多篇Heroku部署文章后仍未定位到原因。

相关配置文件

Procfile

web: java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/*.jar

build.gradle.kts

plugins {
    java
    id("org.springframework.boot") version "2.7.1"
    id("io.spring.dependency-management") version "1.1.0"
}

version = "0.0.1"
java.sourceCompatibility = JavaVersion.VERSION_11

configurations {
    compileOnly {
        extendsFrom(configurations.annotationProcessor.get())
    }
}

repositories {
    mavenCentral()
    maven { url = uri("https://repo.spring.io/milestone") }
    maven { url = uri("https://repo.spring.io/snapshot") }
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-data-jpa:2.7.9")
    implementation("org.springframework.boot:spring-boot-starter-web:2.7.9")

    compileOnly("org.projectlombok:lombok:1.18.26")
    annotationProcessor("org.projectlombok:lombok:1.18.26")
    implementation("org.mapstruct:mapstruct:1.5.3.Final")
    annotationProcessor("org.mapstruct:mapstruct-processor:1.5.3.Final")

    implementation("org.postgresql:postgresql:42.5.4")
    implementation("org.flywaydb:flyway-core:8.5.13")
    implementation("com.vladmihalcea:hibernate-types-52:2.20.0")

    testImplementation("org.springframework.boot:spring-boot-starter-test:2.7.9")
    testImplementation("org.testcontainers:testcontainers:1.17.6")
    testImplementation("org.testcontainers:postgresql:1.17.6")
}

tasks.withType<Test> {
    useJUnitPlatform()
}

tasks.jar {
    manifest {
        attributes(
            "Main-Class" to "com.pro.library.Application",
        )
    }
}

Application.java

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

解决方案

问题根源

手动配置的tasks.jar覆盖了Spring Boot插件默认的构建逻辑。Spring Boot插件原本会生成包含所有依赖的可执行fat jar,但自定义tasks.jar后,生成的是仅包含项目自身代码的普通jar,缺少Spring Boot核心类等依赖,导致运行时类找不到。

修复步骤

  1. 删除自定义的tasks.jar配置
    移除build.gradle.kts中的以下代码块:

    tasks.jar {
        manifest {
            attributes(
                "Main-Class" to "com.pro.library.Application",
            )
        }
    }
    

    Spring Boot插件会自动识别主类并配置manifest信息,无需手动设置。

  2. (可选)禁用普通jar生成
    为避免生成多个jar文件,可明确禁用默认的jar任务,只保留Spring Boot的bootJar任务:

    tasks.named<Jar>("jar") {
        enabled = false
    }
    
  3. 重新部署到Heroku
    提交代码变更后,推送到Heroku:

    git add build.gradle.kts
    git commit -m "Fix jar build configuration for Spring Boot deployment"
    git push heroku main
    

这样生成的jar会包含所有依赖,应用就能在Heroku上正常启动了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:23:13