部署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核心类等依赖,导致运行时类找不到。
修复步骤
删除自定义的
tasks.jar配置
移除build.gradle.kts中的以下代码块:tasks.jar { manifest { attributes( "Main-Class" to "com.pro.library.Application", ) } }Spring Boot插件会自动识别主类并配置manifest信息,无需手动设置。
(可选)禁用普通jar生成
为避免生成多个jar文件,可明确禁用默认的jar任务,只保留Spring Boot的bootJar任务:tasks.named<Jar>("jar") { enabled = false }重新部署到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
相关产品推荐
相关产品推荐

