记录下 RuoYi-Vue 3.8.6 升级 JDK8 到 JDK21 的过程

JDK

1
2
3
4
5
6
<java.version>1.8</java.version>

<!-- ↓↓↓改为下面↓↓↓ -->

<java.version>21</java.version>

SpringBoot

1
2
3
4
5
6
<springboot.version>2.5.15</springboot.version>

<!-- ↓↓↓改为下面↓↓↓ -->

<springboot.version>3.2.5</springboot.version>

Servlet

依赖调整

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>

<!-- ↓↓↓改为下面↓↓↓ -->

<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>

全局包名更换

1
2
3
4
5
6
javax.servlet  →  jakarta.servlet

javax.validation → jakarta.validation

javax.annotation → jakarta.annotation

MySQL 驱动

1
2
3
4
5
6
7
8
9
10
11
12
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

<!-- ↓↓↓改为下面↓↓↓ -->

<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>

Druid 连接池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>

<!-- ↓↓↓改为下面↓↓↓ -->

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>${druid.version}</version>
</dependency>

<druid.version>1.2.27</druid.version>

Lombok

1
2
3
4
5
6
<lombok.version>1.18.20</lombok.version>

<!-- ↓↓↓改为下面↓↓↓ -->

<lombok.version>1.18.30</lombok.version>

PageHelper

1
2
3
4
5
6
<pagehelper.boot.version>1.4.5</pagehelper.boot.version>

<!-- ↓↓↓改为↓↓↓ -->

<pagehelper.boot.version>2.1.1</pagehelper.boot.version>

jaxb-api

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>

<!-- ↓↓↓改为下面↓↓↓ -->

<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>

Kaptcha

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<kaptcha.version>2.3.2</kaptcha.version>
<!-- ↓↓↓改为下面↓↓↓ -->
<kaptcha.version>2.3.3</kaptcha.version>


<!-- 验证码 -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>

<!-- ↓↓↓改为下面↓↓↓ -->

<!-- 验证码 -->
<dependency>
<groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId>
<exclusions>
<exclusion>
<artifactId>servlet-api</artifactId>
<groupId>jakarta.servlet</groupId>
</exclusion>
</exclusions>
</dependency>

MyBatis Plus

这边项目之前已经将 MyBatis 改为了 MyBatis-Plus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<mybatis-plus.version>3.5.12</mybatis-plus.version>

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>

<!-- ↓↓↓改为下面↓↓↓ -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>

<!-- MybatisPlus jdk 11+ 引入可选模块(分页插件) -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>

SaToken

这边项目之前已经将 Security 改为了 SaToken

1
2
3
4
5
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>${satoken.version}</version>
</dependency>

Redisson

1
2
3
4
5
6
7
8
9
10
11
12
13
            <redisson.version>3.25.0</redisson.version>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson.version}</version>
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>org.redisson</groupId>-->
<!-- <artifactId>redisson-spring-data-32</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->

</dependency>

这里之前因为在 SpringBoot2 中引入了 Redisson 所以剔除了SpringBoot3的依赖 , 这里可以删除这一部分剔除了

其它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>

</build>

还有配置文件 yaml 中 redis前要增加一个 data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Spring配置
spring:
# redis 配置
data:
redis:
# 地址
host: xxxx
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: xxx
# 连接超时时间
timeout: 10s

Docker

项目是使用 Docker 来部署的

之前是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#FROM openjdk:8-jdk-alpine
FROM frolvlad/alpine-java:jdk8-slim
VOLUME /tmp
COPY target/ruoyi-admin.jar app.jar

# 获取插件传入的参数
ARG ACTIVE

ENV ACTIVE $ACTIVE
#ENV ACTIVE="druidaws,aws"
ENV TIMEZONE="UTC"
# 设置默认时区 America/Los_Angeles -> UTC
ENV TZ="UTC"
ENTRYPOINT ["java","-jar","-Duser.timezone=${TZ}","/app.jar","--spring.profiles.active=${ACTIVE}"]

这里的 JDK 镜像是三方封装过字体后的 JDK8 镜像 , 我们这里升级 JDK21 后需要修改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
FROM openjdk:21-jdk-slim

# 安装字体依赖(包含中文字体)
RUN apt-get update && \
apt-get install -y --no-install-recommends \
fontconfig \
fonts-dejavu \
fonts-wqy-microhei \
fonts-wqy-zenhei \
libfreetype6 \
libfreetype6-dev \
libxrender1 \
libxext6 \
libxi6 \
&& rm -rf /var/lib/apt/lists/*

# 创建字体缓存
RUN fc-cache -fv

# 验证字体安装
RUN fc-list :lang=zh | grep -i "文泉驿" || echo "Chinese fonts installed"

VOLUME /tmp

COPY target/ruoyi-admin.jar app.jar

ARG ACTIVE
ENV SPRING_PROFILES_ACTIVE=${ACTIVE}
ENV TZ="UTC"

ENTRYPOINT ["java", \
"-jar", \
"-Duser.timezone=${TZ}", \
"/app.jar", \
"--spring.profiles.active=${SPRING_PROFILES_ACTIVE}"]

JENKINS

之前使用Jenkins来打包的,这里也需要升级下依赖的JDK版本,否则无法打包成功

1
image: jenkins/jenkins:jdk21

循环依赖

SpringBoot3 之后会有循环依赖的判定 , 这里看实际情况调整业务代码或者增加@Lasy 注解解决

虚拟线程

JDK21 虚拟线程虽好,但是也不能盲目切换过去 ,有一些场景需要具体分析测试. 比如多个阻塞操作之前是通过线程池运行在不同的线程中,本来是相互不会干扰 , 如果盲目将之前线程池的方法改为分配虚拟线程 , 那么当着两个阻塞操作所在的虚拟线程所属同一个线程的时候,他们阻塞行为就会相互干扰了 , 在 延迟队列 等场景中尤其会出现这种情况 , 使用慎重.

参考链接

CSDN