JDK 8 升级 JDK 17 全流程教学指南

JDK 8 升级 JDK 17

首先已有项目升级是会经历一个较长的调试和自测过程来保证允许和兼容没有问题。先说几个重要的点

  1. 遇到问题别放弃
  2. 仔细阅读报错,精确到每个单词每一行,不是自己项目的代码也要点进去看看源码到底是为啥报错
  3. 明确你项目引入的包,升级到 JDK17 后对应低版本的都需要升级

可能大部分同学都不是完全了解自己的项目都依赖了什么包,这个升级工作一定会加深你对 maven 包管理的理解,以及你对你项目依赖的熟悉程度和你解决排查问题的能力。

项目跑不起来就慢慢调试,问题暂时解决不了就放一放,放松一下,交给下个阶段头脑清醒的自己。

升级你的 maven 编译版本

修改你主工程的 pom 文件

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.7.0</version><configuration><source>17</source><target>17</target></configuration>
</plugin>

我用的是 idea 修改你项目的编译环境

在这里插入图片描述

从新拉 maven 之后你就可以看看哪里报红哪里需要改了,别担心,噩梦才刚刚开始哈哈哈

去除重复依赖

长时间的维护,可能存在一个包在一个 pom 里引入两次的情况 (真服了)

首先项目中 pom 文件不可以出现重复依赖,需要排查去掉

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId>
</dependency>

对于依赖版本,不可以直接出现 RELEASE,你可以定义一个 properties 然后引用一下

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>RELEASE</version><scope>test</scope>
</dependency>

一些依赖的版本升级

这部分只列举我再升级过程中遇到的需要升级的问题

升级 lombok 到 1.18.26

lombok 得用新版本 我之前是 1.18.4 现在换到 26

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version>
</dependency>

升级 springboot 到 2.7.14

你可以在官方文档看到 2.7.14 对应的一些依赖版本

https://docs.spring.io/spring-boot/docs/2.7.14/reference/html/dependency-versions.html#appendix.dependency-versions

<spring.boot.version>2.7.14</spring.boot.version>
<spring.version>5.3.29</spring.version>
<dubbo.version>2.7.23</dubbo.version>

说一下我这里为什么没有选择拥抱 3.x ,因为 dubbo 3 才支持 springboot 3.x 和 spring6.x,而我调用的三方接口都是 dubbo2,dubbo3 应用基本注册不向下兼容 dubbo2,会有诸多问题,所以这里选择

2.7.14 GA 这个官网稳定支持的版本,如果你没有这个问题,可以选择拥抱 3.0

提醒一下如果要升级 springboot3

springboot3 弃用了 javax.servlet.http.HttpServletRequest; 需要替换为 jakarta.servlet.http.HttpServletRequest;

HandlerInterceptorAdapter 被删除了,由 HandlerInterceptor 来代替

yml 配置允许循环依赖

spring:main:allow-circular-references: true

三方包依赖找不到类

我引入的三方包,Spring bean 加载存在问题,感觉是 JDK 升级的问题,跟 spring 的升级没关系

是找不到这个玩意的定义 org.apache.commons.configuration.interpol.ConfigurationInterpolator

nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.apache.commons.configuration.interpol.ConfigurationInterpolator

很怪,明明有就找不到,这里将三方包的引入排除掉,自己项目中单独进行引入

<exclusion><artifactId>commons-configuration</artifactId><groupId>commons-configuration</groupId>
</exclusion><dependency><groupId>commons-configuration</groupId><artifactId>commons-configuration</artifactId><version>1.10</version>
</dependency>

顺便提一个 springbean 加载的问题,如果你引入的三方包有路径下的 bean 需要你进行注册管理,你项目启动类的扫描路径下需要包含他的路径,比如

@SpringBootApplication(scanBasePackages = {"com.你的包","com.三方的需要扫描的包路径"})

当然,如果路径一致,就一个就可以

zookeeper 升级 3.5.10

升级 zookeeper 版本为 3.5.10 , 3.5.x 以下不兼容 JDK17

https://curator.apache.org/zk-compatibility-34.html 还有个 curator 强依赖的场景需要注意升级

如果你服务器的 zookeeper 可以升级最好不过,如果不能

curator 2.x 可以兼容 zookeeper 3.5.x 的版本

如果你之前使用的是 curator 2.x 就只升级 zookeeper 的版本就行了,这样连接你线上的 zookeeper 不会有问题。

否则请将服务器版本同步升级

可参考文章:

官方文章 https://curator.apache.org/zk-compatibility-34.html

csdn 文章 https://blog.csdn.net/wo541075754/article/details/69138878

<apache-curator.version>2.12.0</apache-curator.version>
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>${apache-curator.version}</version><exclusions><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion><exclusion><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>${apache-curator.version}</version><exclusions><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion><exclusion><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId></exclusion></exclusions>
</dependency>

mysql 版本升级 8.0.33

没啥好说的,不升你连不上

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version>
</dependency>

启动项

注意你项目启动时需要增加启动参数,不管是实际运行还是本地调试运行

--add-opens
java.base/java.lang=ALL-UNNAMED
--add-opens
java.base/java.io=ALL-UNNAMED
--add-opens
java.base/java.math=ALL-UNNAMED
--add-opens
java.base/java.net=ALL-UNNAMED
--add-opens
java.base/java.nio=ALL-UNNAMED
--add-opens
java.base/java.security=ALL-UNNAMED
--add-opens
java.base/java.text=ALL-UNNAMED
--add-opens
java.base/java.time=ALL-UNNAMED
--add-opens
java.base/java.util=ALL-UNNAMED
--add-opens
java.base/JDK.internal.access=ALL-UNNAMED
--add-opens
java.base/JDK.internal.misc=ALL-UNNAMED

当然你如果不加也能起可以不加。解释一下

--add-opens 参数是在 JDK 9 及更高版本中引入的,用于在模块系统中打开特定的包以实现反射访问。模块系统引入了更严格的访问控制,以确保代码的可靠性和安全性。在某些情况下,一些库或框架可能依赖于 JDK 内部的类和方法,这些类和方法在模块系统中是受限的,因此需要通过 --add-opens 参数进行显式打开。

具体来说,--add-opens 参数允许你在指定的模块中打开某个包,以便其他模块可以通过反射访问该包中的类和方法。java.base 是 JDK 的基础模块,其中包含了 Java 核心类库。使用 --add-opens java.base/java.lang=ALL-UNNAMED 参数是为了在 JDK 9 及更高版本中允许在 java.base 模块中的 java.lang 包中打开所有未命名的类,从而允许反射访问。

通常情况下,如果你的应用代码遵循良好的编程实践,是不需要使用 --add-opens 参数的。然而,一些第三方库、框架或老旧的代码可能会依赖于 JDK 内部的特性,这时可能会需要使用这个参数来解决访问限制问题。不过,尽量避免在生产环境中过度依赖这种方式,因为这可能会引入一些潜在的风险和不稳定性。

比如

import sun.misc.Unsafe;public class RestrictedAccessExample {public static void main(String[] args) {try {// 使用反射获取 Unsafe 类的实例Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");Unsafe unsafe = (Unsafe) unsafeClass.getDeclaredField("theUnsafe").get(null);// 使用 Unsafe 实例调用内部方法long value = 42;long address = unsafe.allocateMemory(8);unsafe.putLong(address, value);System.out.println("Value at address: " + unsafe.getLong(address));} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}}
}

全部启动项示例

当然你之前的垃圾回收器可能还在用 CMS ,那已经废弃了,所以需要改,用 G1 或者 ZGC 吧,这里我推荐直接用 ZGC。

ZGC 在 17 中已经非常成熟

-Xms2G -Xmx2G -XX:MaxDirectMemorySize=256M -XX:ThreadStackSize=512 -XX:MaxMetaspaceSize=256M -XX:MetaspaceSize=256M -XX:-OmitStackTraceInFastThrow -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -XX:ZAllocationSpikeTolerance=5 -Xlog:gc:/logs/gc.log 
--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/jdk.internal.access=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED  -jar dyinggq.jar

详细参数配置根据自己服务自行适配调整。

报错集

这里收录一下报错和解决方案

nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.apache.commons.configuration.interpol.ConfigurationInterpolator

这个找不到类,找到对应的调用位置,看看为啥没有。最后解决方案是排除了三方包的引入,自行单独引入该包

<exclusion><artifactId>commons-configuration</artifactId><groupId>commons-configuration</groupId>
</exclusion><dependency><groupId>commons-configuration</groupId><artifactId>commons-configuration</artifactId><version>1.10</version>
</dependency>

这个报错是你 zookeeper 的客户端包版本不兼容你服务器的版本

Caused by: java.lang.IllegalStateException: KeeperErrorCode = Unimplemented for org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.createEphemeral(CuratorZookeeperClient.java:114)at org.apache.dubbo.remoting.zookeeper.AbstractZookeeperClient.create(AbstractZookeeperClient.java:83)at org.apache.dubbo.registry.zookeeper.ZookeeperRegistry.doRegister(ZookeeperRegistry.java:125)... 77 common frames omitted

这里是因为我当时升级 zookeeper 的时候 curator 也一起升到 3.x 了,而线上服务 zookeeper 的版本是 3.4.x

<apache-curator.version>2.12.0</apache-curator.version>

所以 curator 还用老版本

dubbo No such extension cid for loadbalance/org.apache.dubbo.rpc.cluster.LoadBalanced

dubbo 找不到自定义的 Balance ,这个有很多情况,我说我的情况,我的情况是项目服务还在使用

com.alibaba.dubbo ,然后我想一起升级到 org.apache.dubbo ,结果找不到了,想来是路径的问题,老的都是继承的

com.alibaba.dubbo .rpc.cluster.LoadBalanced 你升级了需要org.apache.dubbo.rpc.cluster.LoadBalanced

这个如果你依赖三方包的,还真改不了,好在,之前版本的 dubbo 也能在 jdk17 下运行。

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut aspect

这个是 aspectj 版本不匹配

排除其他包引入的 aspecj 引入对应 springboot 版本的 aspecj ,我这里给的是 springboot 2.7.14 对应的

<aspectjweaver.version>1.9.7</aspectjweaver.version>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>${aspectjweaver.version}</version>
</dependency>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/43087.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第三届“赣政杯”网络安全大赛 | 赛宁筑牢安全应急防线

​​为持续强化江西省党政机关网络安全风险防范意识&#xff0c;提高信息化岗位从业人员基础技能&#xff0c;提升应对网络安全风险处置能力。由江西省委网信办、江西省发展改革委主办&#xff0c;江西省大数据中心、国家计算机网络与信息安全管理中心江西分中心承办&#xff0…

Qt扫盲-QTableView理论总结

QTableView理论总结 一、概述二、导航三、视觉外观四、坐标系统五、示例代码1. 性别代理2. 学生信息模型3. 对应视图 一、概述 QTableView实现了一个tableview 来显示model 中的元素。这个类用于提供之前由QTable类提供的标准表&#xff0c;但这个是使用Qt的model/view架构提供…

MySQL 存储过程

create procedure 存储过程名 &#xff08;in | out | INPUT 参数名 参数类型&#xff0c;。。。&#xff09; 【characteristics 。。。】begin存储过程体end存储过程的参数类型 IN 、OUT、INPUT 都可以在一个存储过程带多个 没有参数&#xff08;无参数无返回&#xff09;仅…

边缘网络的作用及管理工具

自从引入软件即服务 &#xff08;SaaS&#xff09; 以来&#xff0c;它一直引领着全球按需软件部署创新的竞赛&#xff0c;它提供的灵活性以及其云计算架构带来的易于集成使其成为交付业务应用程序的标准。 在 SaaS 模型中&#xff0c;最佳用户体验的三重奏涉及无缝设置、低延…

JMeter 特殊组件-逻辑控制器与BeanShell PreProcessor 使用示例

文章目录 前言JMeter 特殊组件-逻辑控制器与BeanShell PreProcessor 使用示例1. 逻辑控制器使用1.1. While Controller 使用示例1.2. 如果&#xff08;If&#xff09;控制器 使用示例 2. BeanShell PreProcessor 使用示例 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞…

Java课题笔记~ SpringBoot简介

1. 入门案例 问题导入 SpringMVC的HelloWord程序大家还记得吗&#xff1f; SpringBoot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化Spring应用的初始搭建以及开发过程 原生开发SpringMVC程序过程 1.1 入门案例开发步骤 ①&#xff1a;创建新模块&#…

设计模式-过滤器模式(使用案例)

过滤器模式&#xff08;Filter Pattern&#xff09;或标准模式&#xff08;Criteria Pattern&#xff09;是一种设计模式&#xff0c;这种模式允许开发人员使用不同的标准来过滤一组对象&#xff0c;通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式…

服务器安装centos7踩坑

1、制作启动工具 下载iso https://developer.aliyun.com/mirror/?spma2c6h.25603864.0.0.20387abbo2RFbn http://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/?spma2c6h.25603864.0.0.1995f5ad4AhJaW下载 UltraISO https://cn.ultraiso.net/插入u盘启动 到了如图所示页面…

nginx php-fpm安装配置

nginx php-fpm安装配置 nginx本身不能处理PHP&#xff0c;它只是个web服务器&#xff0c;当接收到请求后&#xff0c;如果是php请求&#xff0c;则发给php解释器处理&#xff0c;并把结果返回给客户端。 nginx一般是把请求发fastcgi管理进程处理&#xff0c;fascgi管理进程选…

架构演进及常用架构

1架构演进及常用架构 1.1单体分层架构 1.2 多应用微服务架构 1.3 分布式集群部署 部署 CDN 节点&#xff1a; 用户访问量的增加意味着用户地域的分散请求&#xff0c;如果所有请求都直接发送中心服务器的话&#xff0c;距离越远&#xff0c;响应速度越差&#xff0c;这时就需…

【编织时空四:探究顺序表与链表的数据之旅】

本章重点 链表的分类 带头双向循环链表接口实现 顺序表和链表的区别 缓存利用率参考存储体系结构 以及 局部原理性。 一、链表的分类 实际中链表的结构非常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; 1. 单向或者双向 2. 带头或者不带头 3. 循环或者非…

yolov5封装进ros系统

一&#xff0c;要具备ROS环境 ROS环境搭建可以参考我之前的文章 ROS参考文章1 ROS参考文章2   建立ROS工作空间 ROS系统由自己的编译空间规则。 cd 你自己想要的文件夹&#xff08;我一般是home目录&#xff09; mkdir -p (你自己的文件夹名字&#xff0c;比如我是yolov5…

C++的stack和queue+优先队列

文章目录 什么是容器适配器底层逻辑为什么选择deque作为stack和queue的底层默认容器优先队列优先队列的模拟实现stack和queue的模拟实现 什么是容器适配器 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总 结)&#xff0c;…

PyTorch训练深度卷积生成对抗网络DCGAN

文章目录 DCGAN介绍代码结果参考 DCGAN介绍 将CNN和GAN结合起来&#xff0c;把监督学习和无监督学习结合起来。具体解释可以参见 深度卷积对抗生成网络(DCGAN) DCGAN的生成器结构&#xff1a; 图片来源&#xff1a;https://arxiv.org/abs/1511.06434 代码 model.py impor…

Electron入门,项目启动。

electron 简单介绍&#xff1a; 实现&#xff1a;HTML/CSS/JS桌面程序&#xff0c;搭建跨平台桌面应用。 electron 官方文档&#xff1a; [https://electronjs.org/docs] 本文是基于以下2篇文章且自行实践过的&#xff0c;可行性真实有效。 文章1&#xff1a; https://www.cnbl…

基于Javaweb的摄影作品网站/摄影网站

摘 要 随着信息化时代的到来&#xff0c;系统管理都趋向于智能化、系统化&#xff0c;摄影作品网站也不例外&#xff0c;但目前国内的有些网站仍然都使用人工管理&#xff0c;浏览网站人数越来越多&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的…

AMD fTPM RNG的BUG使得Linus Torvalds不满

导读因为在 Ryzen 系统上对内核造成了困扰&#xff0c;Linus Torvalds 最近在邮件列表中表达了对 AMD fTPM 硬件随机数生成器的不满&#xff0c;并提出了禁用该功能的建议。 因为在 Ryzen 系统上对内核造成了困扰&#xff0c;Linus Torvalds 最近在邮件列表中表达了对 AMD fTPM…

【【Verilog典型电路设计之FIFO设计】】

典型电路设计之FIFO设计 FIFO (First In First Out&#xff09;是一种先进先出的数据缓存器&#xff0c;通常用于接口电路的数据缓存。与普通存储器的区别是没有外部读写地址线&#xff0c;可以使用两个时钟分别进行写和读操作。FIFO只能顺序写入数据和顺序读出数据&#xff0…

【从0开始学架构笔记】01 基础架构

文章目录 一、架构的定义1. 系统与子系统2. 模块与组件3. 框架与架构4. 重新定义架构 二、架构设计的目的三、复杂度来源&#xff1a;高性能1. 单机复杂度2. 集群复杂度2.1 任务分配2.2 任务分解&#xff08;微服务&#xff09; 四、复杂度来源&#xff1a;高可用1. 计算高可用…

GitKraken保姆级图文使用指南

前言 写这篇文章的原因是组内的产品和美术同学&#xff0c;开始参与到git工作流中&#xff0c;但是网上又没有找到一个比较详细的使用教程&#xff0c;所以干脆就自己写了一个[doge]。文章的内容比较基础&#xff0c;介绍了Git内的一些基础概念和基本操作&#xff0c;适合零基…