目录
1、背景
老项目,jdk版本问1.8,springboot版本为2.6.6,升级jdk和spring全家桶
2、我看到的主要改造内容
主要过程就是解决大的问题,然后不断的启动,解决启动中的报错
2.1、下载JDK17以上的版本,本地安装和项目配置
嗯嗯,这个我这么菜的人都会,我相信人均架构师的大家都会~~~
2.1、包替换
| 原包 | 替换后的包 |
| javax.annotation. | jakarta.annotation. |
| javax.servlet. | jakarta.servlet. |
| javax.persistence. | jakarta.persistence. |
| javax.validation. | jakarta.validation. |
| javax.transaction.* | jakarta.transaction.* |
直接在idea中 control + shift + r全量替换即可
2.2、启动中碰到的异常
2.2.1 Base64包已废弃
启动时编译发现报错:
D:\code\jaylli-backend-server\src\main\java\com\jaylli\backend\client\order\OrderUtil.java:3:16
java: 找不到符号
符号: 类 BASE64Encoder
位置: 程序包 sun.misc
修改新的import路径:
import sun.misc.BASE64Encoder 变更为 import java.util.Base64;
调用的地方修改成对应的调用方式,比如:
new BASE64Encoder().encode(out.toByteArray());
修改为:
Base64.getEncoder().encodeToString(out.toByteArray());
2.2.2 nacos配置失效
2.2.2.1 排错过程
解决编译报错之后,始终无法读取到nacos的配置,开始排查nacos配置的问题,
1、确认是否连接上nacos:尝试手动修改错误的redis配置,比如错误的ip,错误的username或password,发现报错信息没有任何变化(我预期应该是会报nacos失败,账号密码错误这种异常,结果是啥都没有)
2、对比升级之前修改错误的redis配置启动,发现是有一些异常的
3、得出结论,应该是升级springboot之后无法加载nacos配置
查阅资料发现,SpringBoot3.*开始:
1、 配置加载机制变化
Spring Boot 3.0+ 默认不再自动加载 bootstrap.yml 文件
需要通过 spring.config.import 显式引入外部配置
2.2.2.2 有两种方式解决
方式1:application.yml中添加显式nacos配置:
spring:
config:
import:
- nacos:${app_name}.yml
将nacos相关的配置移到application.yml
spring:
cloud:
nacos:
server-addr: ${app_addr}
username: ${username}
password: ${password}
config:
namespace: ${namespace}
group: ${group}
file-extension: yml
喜大普奔,重启生效!!
方式二:继续使用bootstrap.yml,需要引用bootstrap的starter
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
bootstrap.yml中加入显式引入nacos配置:
spring:
config:
import:
- nacos:${app_name}.yml
喜大普奔,重启生效~!~~~!!!
2.2.2.3 问题来了
使用方式2时,想尝试在application.yml中加入显式引入nacos的配置(spring.config.import),然后启动,竟然报错了:
2026-01-04 14:59:51,817 [Thread-2] WARN c.alibaba.nacos.common.executor.ThreadPoolManager:56 - [ThreadPoolManager] Destruction of the end
Exception in thread "main" java.lang.IllegalStateException: java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[CONFIG_LOG_FILE] - 'File' option has the same value "C:\Users\Administrator/logs/nacos/config.log" as that given for appender [CONFIG_LOG_FILE] defined earlier.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[CONFIG_LOG_FILE] - Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[CONFIG_LOG_FILE] - For more information, please visit https://logback.qos.ch/codes.html#earlier_fa_collision
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[NAMING_LOG_FILE] - 'File' option has the same value "C:\Users\Administrator/logs/nacos/naming.log" as that given for appender [NAMING_LOG_FILE] defined earlier.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[NAMING_LOG_FILE] - Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[NAMING_LOG_FILE] - For more information, please visit https://logback.qos.ch/codes.html#earlier_fa_collision
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[REMOTE_LOG_FILE] - 'File' option has the same value "C:\Users\Administrator/logs/nacos/remote.log" as that given for appender [REMOTE_LOG_FILE] defined earlier.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[REMOTE_LOG_FILE] - Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[REMOTE_LOG_FILE] - For more information, please visit https://logback.qos.ch/codes.html#earlier_fa_collision
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:347)
at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:298)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81)
at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:353)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
at com.yifeng.cashier.backend.ApplicationStartUp.main(ApplicationStartUp.java:23)
Caused by: java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[CONFIG_LOG_FILE] - 'File' option has the same value "C:\Users\Administrator/logs/nacos/config.log" as that given for appender [CONFIG_LOG_FILE] defined earlier.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[CONFIG_LOG_FILE] - Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[CONFIG_LOG_FILE] - For more information, please visit https://logback.qos.ch/codes.html#earlier_fa_collision
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[NAMING_LOG_FILE] - 'File' option has the same value "C:\Users\Administrator/logs/nacos/naming.log" as that given for appender [NAMING_LOG_FILE] defined earlier.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[NAMING_LOG_FILE] - Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[NAMING_LOG_FILE] - For more information, please visit https://logback.qos.ch/codes.html#earlier_fa_collision
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[REMOTE_LOG_FILE] - 'File' option has the same value "C:\Users\Administrator/logs/nacos/remote.log" as that given for appender [REMOTE_LOG_FILE] defined earlier.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[REMOTE_LOG_FILE] - Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[REMOTE_LOG_FILE] - For more information, please visit https://logback.qos.ch/codes.html#earlier_fa_collision
at org.springframework.boot.logging.logback.LogbackLoggingSystem.reportConfigurationErrorsIfNecessary(LogbackLoggingSystem.java:291)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:269)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:67)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:58)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:197)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:335)
... 19 more
Disconnected from the target VM, address: '127.0.0.1:12706', transport: 'socket'
报错原因:
1. 配置加载顺序差异
bootstrap.yml:在应用启动早期阶段加载,优先级最高
application.yml:在 SpringApplication.run() 执行时加载
2. 报错原因
将 spring.config.import 放到 application.yml 后,Nacos 配置加载时机发生变化
Nacos 客户端尝试加载远程配置时,日志系统尚未完全初始化完成
产生 Logback 配置冲突或重复初始化错误
解决方案:
1、配置作用
禁用 Nacos 默认日志配置:该配置用于关闭 Nacos 客户端的默认日志配置加载
避免日志冲突:防止 Nacos 自动加载的日志配置与应用日志配置发生冲突
2、使用场景
当将 spring.config.import 配置从 bootstrap.yml 移至 application.yml 时
出现 Logback 配置错误时的解决方案
3、问题解决
在启动类main方法通过设置 System.setProperty("nacos.logging.default.config.enabled","false")
避免 Nacos 自动加载默认日志配置文件
@SpringBootApplication
@MapperScan({"com.jaylli.**.dao"})
@EnableFeignClients
@ConfigurationPropertiesScan
public class ApplicationStartUp {
public static void main(String[] args) {
// 将spring.config.import配置放在bootstrap.yml中不报错
// 放到application.yml后报错,通过引入下面的配置解决
System.setProperty("nacos.logging.default.config.enabled","false");
SpringApplication.run(ApplicationStartUp.class, args);
}
}
再一次喜大普奔,重启生效,解决日志配置冲突导致的启动异常~~~~~
4、解决方案原理分析
通过 System.setProperty("nacos.logging.default.config.enabled","false") 在应用启动前设置系统属性(理论上来说通过其他方式也可以,比如放在启动参数里面java -Dnacos.logging.default.config.enabled=false)
告诉 Nacos 不要加载其默认的日志配置
避免了日志系统的重复配置和冲突问题
5、 注意事项
这是一个临时解决方案
建议优先考虑使用 bootstrap.yml 配置 Nacos 配置中心
保持配置加载顺序的正确性
小结:
不管怎么样,都需要在yml文件中新增显式引入nacos配置:
spring:
config:
import:
- nacos:${app_name}.yml
如果是在bootstrap.yml中新增,需要额外新增依赖包才能正常启动和加载nacos配置:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
如果是在application.yml中新增,则不需要新增上述依赖,但是需要排除Logback 配置冲突的问题,即需要新增参数:
System.setProperty("nacos.logging.default.config.enabled","false");
2.2.3 redis配置失效
springboot2.*之后,redis的配置节点已经做了修改
1. 版本变化点
Spring Boot 2.0+ 开始,Redis 配置节点从 spring.redis.* 变为 spring.data.redis.*
这是 Spring Boot 2.x 版本的重大配置变更
旧版本配置,springboot1.*只支持这种,springboot2.*似乎还兼容这种方式的配置:
spring:
redis:
host: localhost
port: 6379
password: your-password
新版本配置,springboot3.*开始似乎已经完全不支持旧版本的配置了,需要使用新的配置:
spring:
data:
redis:
host: localhost
port: 6379
password: your-password
所以,用到这个配置的地方,最好都改,早改晚改都得改!!
2.2.4 反射报错
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.Object java.util.Collections$SingletonList.element accessible: module java.base does not "opens java.util" to unnamed module @3fd7a715
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
at org.apache.lucene.util.RamUsageEstimator.createCacheEntry(RamUsageEstimator.java:497)
at org.apache.lucene.util.RamUsageEstimator.measureObjectSize(RamUsageEstimator.java:455)
at org.apache.lucene.util.RamUsageEstimator.sizeOf(RamUsageEstimator.java:333)
原因分析:
Java 17+ 模块系统限制:java.util 模块未对匿名模块开放访问权限
Lucene 的 RamUsageEstimator 试图通过反射访问 Collections$SingletonList 的私有字段
安全限制:java.base 模块不向未命名模块开放 java.util 访问权限
解决方案:
方案1:
添加 JVM 参数(推荐)
--add-opens java.base/java.util=ALL-UNNAMED
方案2:自己修改业务代码,改一改实现方式:
升级Lucene版本到9.0.0:
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>9.0.0</version>
</dependency>
然后修改业务代码:
RamUsageEstimator.sizeOf(obj);
修改为:
RamUsageEstimator.shallowSizeOf(obj)
2.2.5 mybatis-plus报错
2026-01-07 14:02:32,015 [http-nio-8080-exec-9] ERROR c.g.f.base.exception.ExceptionLoggerPrintHandler:55 - com.gomcarter.frameworks.base.exception.ExceptionLoggerPrintHandler操作失败, url:/com.jaylli/cart/delete, method:POST, body: , ip: 0:0:0:0:0:0:0:1, Referer: null, UA: Apifox/1.0.0 (https://apifox.com), params: {}, cookie: null,header: {"content-length":"323","host":"localhost:8080","content-type":"application/json","connection":"keep-alive","accept-encoding":"gzip, deflate, br","user-agent":"Apifox/1.0.0 (https://apifox.com)","accept":"*/*"},
org.mybatis.spring.MyBatisSystemException:
### Error updating database. Cause: org.apache.ibatis.builder.BuilderException: The expression 'ids' evaluated to a null value.
### The error may exist in file [D:\code\jaylli\my-cart\target\classes\mybatis\cart\CartMapper.xml]
### The error may involve com.jaylli.cart.dao.CartMapper.deleteByIds
### The error occurred while executing an update
### Cause: org.apache.ibatis.builder.BuilderException: The expression 'ids' evaluated to a null value.
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:99)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:347)
at jdk.proxy2/jdk.proxy2.$Proxy132.delete(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.delete(SqlSessionTemplate.java:244)
at com.baomidou.mybatisplus.core.mapper.BaseMapper.deleteByIds(BaseMapper.java:219)
at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:171)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:92)
原因分析:
mapper里面定义了一个和mybatis-plus一模一样签名的sql:
自己定义的mapper方法和对应的sql:
@Mapper
public interface MyCartMapper extends BaseMapper<CartEntity> {
int deleteByIds(@Param("ids") List<Long> ids);
}
<delete id="deleteByIds">
delete from my_cart
where id in <foreach collection="ids" separator="," open="(" close=")" item="id"> #{id} </foreach>
</delete>
注意,自定义的 deleteByIds 方法使用的别名是 @Param("ids")
mybatis-plus定义了一个一模一样签名的方法:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.baomidou.mybatisplus.core.mapper;
import com.baomidou.mybatisplus.core.batch.BatchSqlSession;
import com.baomidou.mybatisplus.core.batch.MybatisBatch;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.override.MybatisMapperProxy;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.MybatisBatchUtils;
import com.baomidou.mybatisplus.core.toolkit.MybatisUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiPredicate;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.apache.ibatis.executor.BatchResult;
import org.apache.ibatis.ognl.OgnlOps;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
public interface BaseMapper<T> extends Mapper<T> {
...此处省略一万行源码...
default int deleteByIds(@Param("coll") Collection<?> idList) {
return this.deleteByIds(idList, true);
}
...此处省略一万行源码...
}
注意,mybatis-plus定义的相同签名的方法的入参别名是: @Param("coll")
结论:
方法冲突: 自定义的 deleteByIds 方法与 MyBatis-Plus 内置方法签名相同
参数注解: 你的自定义方法使用 @Param("ids"),但 MyBatis-Plus 内置方法使用 @Param("coll")
XML 配置: XML 中可能按 ids 引用参数,但实际调用了内置方法
解决方案:
方案1(推荐):删除自定义的sql
方案2:把自定义的方法改名
方案3:将自定义的sql的别名改成和mybatis-plus默认的一样
为什么升级之前没有问题?因为之前老版本的mybatis-plus里面默认没有这个方法,升级之后新加的
升级之前的版本
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.2</version>
升级之后的版本
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.10.1</version>
至此,所以启动报错都已解决~~~
2.3 docker环境修改
这个我们有运维帮改,但是建议程序员们还是需要了解docker的一些知识,比如dockfile一般怎么写的
2.4 全流程验证
自测+测试

912

被折叠的 条评论
为什么被折叠?



