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

如何修复ClassNotFoundException: org.springframework.boot.configurationprocessor.json.JSONObject错误?

问题描述

部署应用时遇到以下错误:

java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)
Caused by: java.lang.NoClassDefFoundError: org/springframework/boot/configurationprocessor/json/JSONObject
    at com.rossmoor.jenarktomds.services.web.GrfPortalClientServiceImpl.getAccessToken(GrfPortalClientServiceImpl.java:53)
    at com.rossmoor.jenarktomds.services.web.GrfPortalClientServiceImpl.downloadAllGrfUsers(GrfPortalClientServiceImpl.java:325)
    at com.rossmoor.jenarktomds.services.DataProcessorImpl.testGrfApi(DataProcessorImpl.java:1939)
    at com.rossmoor.jenarktomds.services.DataProcessorImpl$$FastClassBySpringCGLIB$$716e474b.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
    at com.rossmoor.jenarktomds.services.DataProcessorImpl$$EnhancerBySpringCGLIB$$21e20f26.testGrfApi(<generated>)
    at com.rossmoor.jenarktomds.JenarkToMdsApplication.run(JenarkToMdsApplication.java:76)
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771)
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:755)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
    at com.rossmoor.jenarktomds.JenarkToMdsApplication.main(JenarkToMdsApplication.java:59)
    ... 8 more
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.configurationprocessor.json.JSONObject
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587)
    at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 30 more

引发错误的代码片段:

// create request body
JSONObject request = new JSONObject();
request.put("username", configurationProperties.getGrfPortalUserName());
request.put("password", configurationProperties.getGrfPortalUserPwd());

// set headers
HttpHeaders headers = new HttpHeaders();
headers.add("API-Key", "{{apiKey}}");
headers.add("Authorization", "Basic {{authorization}}");

headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<>(request.toString(), headers);

if (Logger.isInfoEnabled()) Logger.info("Sending request to GRF Portal");
// send request and parse result
ResponseEntity<String> loginResponse = restTemplate
        .exchange(GRF_LOGIN_URL, HttpMethod.POST, entity, String.class);
if (loginResponse.getStatusCode() == HttpStatus.OK)
{
    JSONObject userJson = new JSONObject(loginResponse.getBody());

    if (Logger.isInfoEnabled()) Logger.info("Token Data = " + userJson);

    this.AccessToken = String.valueOf(userJson.get("token"));

    System.out.println("AccessToken = " + AccessToken);
}
else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED)
{
    // nono... bad credentials
    if (Logger.isErrorEnabled()) Logger.error("nono... bad credentials");
}

关键信息

  • 错误仅在生产服务器部署时出现,开发环境或用IntelliJ直接运行无问题
  • 部署步骤:
    1. Gradle build构建应用
    2. Jar2exe将Jar转成exe
    3. 通过安装程序部署为Windows服务

Gradle配置:

plugins {
    id 'org.springframework.boot' version '2.7.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.rossmoor'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-data-rest'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'
    annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

//    // https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-core
//    implementation group: 'org.hibernate.orm', name: 'hibernate-core', version: '6.0.2.Final'
//
//    // https://mvnrepository.com/artifact/jakarta.transaction/jakarta.transaction-api
//    implementation group: 'jakarta.transaction', name: 'jakarta.transaction-api', version: '2.0.1'
//
//    // https://mvnrepository.com/artifact/jakarta.persistence/jakarta.persistence-api
//    implementation group: 'jakarta.persistence', name: 'jakarta.persistence-api', version: '3.1.0'

    // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
    implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'

    // https://mvnrepository.com/artifact/commons-validator/commons-validator
    implementation group: 'commons-validator', name: 'commons-validator', version: '1.7'

    // https://mvnrepository.com/artifact/org.mapstruct/mapstruct
    implementation group: 'org.mapstruct', name: 'mapstruct', version: '1.5.2.Final'

    // https://mvnrepository.com/artifact/com.google.code.gson/gson
    implementation group: 'com.google.code.gson', name: 'gson', version: '2.9.1'

    implementation files('lib/connection-manager-2.0.0.1.jar')
    implementation files('lib/Utils-2.0.0.1.jar')
    implementation files('lib/TinyLog-2.0.0.1.jar')
}

tasks.named('test') {
    useJUnitPlatform()
}
解决方案

问题根源

你代码里用的org.springframework.boot.configurationprocessor.json.JSONObject来自spring-boot-configuration-processor依赖,但这个依赖在Gradle配置里是annotationProcessor范围——这个范围只在编译期生成配置元数据时生效,不会被打包到最终的可执行Jar里。

开发环境能运行是因为IntelliJ会自动把annotationProcessor类加入类路径,但生产部署时,打包后的Jar(以及转成的exe)里没有这个类,所以抛出ClassNotFoundException。

修复方案

方案1:替换为标准JSON库(推荐)

spring-boot-configuration-processor里的JSON类只是内部工具,不应该在业务代码里使用。你已经引入了Gson,直接用它来处理JSON:

修改代码:

import com.google.gson.JsonObject;
import com.google.gson.Gson;

// 创建请求体
JsonObject request = new JsonObject();
request.addProperty("username", configurationProperties.getGrfPortalUserName());
request.addProperty("password", configurationProperties.getGrfPortalUserPwd());

// 转成字符串
String requestBody = new Gson().toJson(request);
HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);

// 解析响应
if (loginResponse.getStatusCode() == HttpStatus.OK) {
    JsonObject userJson = new Gson().fromJson(loginResponse.getBody(), JsonObject.class);
    this.AccessToken = userJson.get("token").getAsString();
    System.out.println("AccessToken = " + AccessToken);
}

这样完全不需要依赖spring-boot-configuration-processor的JSON类,避免依赖范围问题。

方案2:调整依赖范围(不推荐)

如果一定要用这个JSONObject,把spring-boot-configuration-processor的依赖范围改成implementation:

// 替换原来的annotationProcessor行
implementation "org.springframework.boot:spring-boot-configuration-processor"

但不建议这么做,因为这个依赖本来就是用于编译期的,打包到生产环境属于冗余,还可能带来版本冲突风险。

额外检查

确认Gradle构建的是可执行Jar(Spring Boot默认的bootJar任务),而不是普通的jar任务。运行./gradlew bootJar来构建,确保所有依赖都被打包进去。另外,用Jar2exe转换时,要确保它正确处理了Spring Boot Jar的嵌套结构,没有遗漏依赖类。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 08:18:35