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

这篇具有很好参考价值的文章主要介绍了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 修改你项目的编译环境

JDK 8 升级 JDK 17 全流程教学指南,JVM,java,dying搁浅,JDK17,JDK升级,JDK8升级JDK17

从新拉 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 对应的文章来源地址https://www.toymoban.com/news/detail-646742.html

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

到了这里,关于JDK 8 升级 JDK 17 全流程教学指南的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JDK8-JDK17版本升级

    记录Records是添加到 Java 14 的一项新功能。它允许你创建用于存储数据的类。它类似于 POJO 类,但代码少得多;大多数开发人员使用 Lombok 生成 POJO 类,但是有了记录,你就不需要使用任何第三方库。 sealed将类的继承限制为一组有限的子类 密封类的子类可以声明为fina

    2024年01月17日
    浏览(43)
  • JDK11 升级 JDK17 最全实践干货来了

    上篇文章给大家带来了JDK8升级JDK11的最全实践,相信大家阅读后已经对JDK11有了比较深入的了解。2021年9月14日,Oracle发布了可以长期支持的JDK17版本,那么从JDK11到JDK17,到底带来了哪些特性呢?亚毫秒级的ZGC效果到底怎么样呢?值得我们升级吗?而且升级过程会遇到哪些问题

    2024年02月05日
    浏览(56)
  • springboot升级到3.x + jdk升级到17

    jdk由 1.8 升级到 17 spring-boot由 2.7.6 升级到 3.1.2 版本 spring-cloud-alibaba由 2021.0.4.0 升级到 2022.0.0.0-RC2 版本 maven构建插件里的配置要改为17: javax相关的包要改为jakarta: Spring Boot3.0已经将依赖项从Java EE迁移到Jakarta EE API(主要是避免Oracle 的版权问题),所以要将项目中的 javax.se

    2024年02月02日
    浏览(36)
  • JDK8升级JDK17过程中遇到的那些坑

    JDK8虽然非常好,但是JDK版本已经发布到JDK20了,且JDK8后的版本升级了很多新的特性,如模块化、ZGC以及虚拟线程、结构性并发等,也是非常有吸引力的,所以决定将基于JDK8的项目升级到最近的LTS版本JDK17。 下载JDK17的最新版本 jdk-17_linux-x64_bin.tar.gz ,解压缩后移动到 /usr/lib

    2024年02月11日
    浏览(38)
  • 关于老项目从JDK8升级到JDK17所需要注意的细节

    这个是最简单的网上很多教程我这边就不在重复了 🌸1.第一种方式 🌸1.1.修改Idea中的JDK版本 跟步骤修改 修改Java Compiler 🌸1.2.关于修改过程中遇到的异常 如果出现下面异常按照上述步骤定可以解决 🌸1.3.IDEA工具栏操作Maven正常,但使用mvn命令运行就报错 使用侧工具栏的打包

    2024年02月07日
    浏览(43)
  • JVM 17 调优指南:如何进行JVM调优,JVM调优参数

    在这篇文章中,我会详细介绍JVM调优的概念、重要性和具体的JVM调优参数。此外,我将提供12个实用的代码示例,每个示例都会包含JVM调优参数和相应的Java代码。 本文已收录于,我的技术网站 ddkk.com,有大厂完整面经,工作技术,架构师成长之路,等经验分享 JVM调优是调整

    2024年02月02日
    浏览(45)
  • 解锁滴滴ES的性能潜力:JDK 17和ZGC的升级之路

    前文介绍了滴滴自研的ES强一致性多活是如何实现的,其中也提到为了提升查询性能和解决查询毛刺问题,滴滴ES原地升级JDK17和ZGC,在这个过程中我们遇到了哪些问题,怎样解决的,以及最终上线效果如何,这篇文章就带大家深入了解。 背景 滴滴ES在2020年的时候由2.X升级到

    2024年02月13日
    浏览(37)
  • 如何在一台服务器上同时运行搭载JDK 8, JDK 17, 和 JDK 21的项目:终极指南

    在企业开发环境中,常常需要在同一台服务器上运行使用不同Java开发工具包(JDK)版本的多个项目。本文详细介绍如何在Linux服务器(以Ubuntu 20.04为例)上同时安装并配置JDK 8, JDK 17, 和JDK 21,使得不同的Java应用可以并存并运行,无需干扰。从下载JDK到配置独立的运行环境,本

    2024年04月23日
    浏览(54)
  • [Java]JDK17新特性

    目录   一、JDK新特性 1.1Java Record 1.1.1Record的使用 1.1.2Instance Methods 1.1.3静态方法 Static Method 1.1.4Record构造方法 1.1.5Record与Lombok 1.1.6Record实现接口 1.1.7Local Record 1.1.8嵌套Record 1.1.9instanceof判断Record类型 1.1.10总结 1.2Switch 1.2.1箭头表达式 1.2.2yield返回值 1.2.3Java Record 1.3Text Block 1.3.1认识

    2024年02月07日
    浏览(46)
  • Java中jdk1.8和jdk17相互切换

    之前做Java项目时一直用的是jdk1.8,现在想下载另一个jdk版本17,并且在之后的使用中可以进行相互切换,我将jdk切换时所遇到的问题记录下来并分享出来供大家参考。 环境变量配置如下: 步骤1 步骤2 (注:@MAVEN_HOME%bin;是配置maven时的环境变量,如果没有安装maven就不用管)

    2024年02月03日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包