JAVA8项目升级JDK17指南

发布时间:2023年12月27日

JAVA8项目升级JDK17指南

随着SpringBoot2.7的发布,支持jdk8~jdk21。Springboot3.X发布,最低需要jdk17。升级jdk17是大势所趋。

参考1:重磅!Spring Boot 2.7 正式发布
参考2:hutool-希望Hutool能支持下JDK8~JDK17的所有版本

一、模块化对反射的影响

由于jdk9增加的模块化设计,导致对系统内置类反射受到限制,出现类似的错误,自己开发的类没有影响。

 public static void main(String[] args) {
        // jdk17使用反射,无需修改,可以正常使用示例
        NucPerson nucPerson = new NucPerson();
        nucPerson.setPersonName("张三");
        ReflectUtil.setFieldValue(nucPerson, "personPhone", "18800001111");
        System.out.println(nucPerson.getPersonPhone());
        System.out.println(ReflectUtil.getFieldMap(NucPerson.class));

        // jdk17使用反射系统模块的类,必须要增加--add-opens的反射示例
        Object stringValue = ReflectUtil.getFieldValue(nucPerson.getPersonName(), "value");
        System.out.println(stringValue);
    }
java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Map sun.reflect.annotation.AnnotationInvocationHandler.memberValues accessible: module java.base does not "opens sun.reflect.annotation" to unnamed module @52d455b8
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) ~[na:na]
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) ~[na:na]
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178) ~[na:na]
	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172) ~[na:na]
	at cn.hutool.core.util.ReflectUtil.setAccessible(ReflectUtil.java:966) ~[hutool-core-5.7.19.jar:na]
	at cn.hutool.core.util.ReflectUtil.getFieldValue(ReflectUtil.java:266) ~[hutool-core-5.7.19.jar:na]
	at cn.hutool.core.util.ReflectUtil.getFieldValue(ReflectUtil.java:234) ~[hutool-core-5.7.19.jar:na]
	at cn.hutool.core.annotation.AnnotationUtil.setValue(AnnotationUtil.java:215) ~[hutool-core-5.7.19.jar:na]

解决:增加jvm启动参数(java虚拟机启动参数)

--add-opens java.base/sun.reflect.annotation=ALL-UNNAMED

汇总:

        -Djdk.home=/Library/Java/JavaVirtualMachines/openjdk-18.0.1.1/Contents/Home
        -Xms24m
        -Xmx768m
        -DTopSecurityManager.disable=true
	--add-exports=java.desktop/com.sun.java.swing.plaf.gtk=ALL-UNNAMED
	--add-exports=java.desktop/sun.awt=ALL-UNNAMED
	--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor.event=ALL-UNNAMED
	--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED
	--add-exports=java.desktop/sun.swing=ALL-UNNAMED
	--add-exports=jdk.attach/sun.tools.attach=ALL-UNNAMED
	--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED
	--add-opens=java.desktop/javax.swing.plaf.synth=ALL-UNNAMED
	--add-opens=java.base/java.net=ALL-UNNAMED
	--add-opens=java.base/java.lang.ref=ALL-UNNAMED
	--add-opens=java.base/java.lang=ALL-UNNAMED
	--add-opens=java.desktop/javax.swing=ALL-UNNAMED
	--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED
	-XX:+IgnoreUnrecognizedVMOptions
	-XX:+HeapDumpOnOutOfMemoryError
	-XX:HeapDumpPath=/Users/duandazhi/Library/Application Support/VisualVM/2.1.2/var/log/heapdump.hprof

--add-opens--add-exports区别,opens是深度反射,可以打开对私有变量、成员的反射;exports只能打开公有变量的反射。总结:使用--add-opens肯定没问题。
java虚拟机选项
总结:模块化需要增加的JVM打开反射参数,对常规业务系统影响不大,毕竟对系统类反射操作很少,对自己开发的类进行反射操作并没有限制。

二、删除的内置类

高版本最坑应该是这一条:
Java 11 :移除JavaEE和CORBA模块

对于Java EE和CORBA模块在Java 9开始就不推荐使用了。而从Java 11开始正式删除了这部分内容,所以当升级到Java 11或更高的版本的话,务必要先更急以下内容相关的代码:
移除的包:

  • java.xml.ws (JAX-WS)
  • java.xml.bind (JAXB)
  • java.activation (JAF)
  • java.xml.ws.annotation (Common Annotations)
  • java.corba (CORBA)
  • java.transaction (JTA)
  • java.se.ee (以上6个模块的聚合模块)

移除的工具:

  • wsgen and wsimport (from jdk.xml.ws)
  • schemagen and xjc (from jdk.xml.bind)
  • idlj, orbd, servertool, and tnamesrv (from java.corba)

不过,我看也有办法,我的项目里面就使用到了webservice,即:jaxb(实体类和xml转换)、soapwebservice的http网络请求。
受到影响的hutool工具类cxf相关:JAXBUtilSoapClient
业务场景,系统请求外部接口使用是webservice,实体类和xml转换需要用JAXBUtil、发送Http请求使用SoapClient

<!-- 适配jdk升级到9及以上,移除了 javax.xml.bind (JAXB) 的问题; javax需要从外部引入 -->
        <!-- https://mvnrepository.com/artifact/jakarta.xml.bind/jakarta.xml.bind-api -->
        <!-- java.xml.bind 模块的接口 API -->
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>4.0.4</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>4.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.4.0-b180830.0438</version>
        </dependency>
        <dependency>
            <groupId>jakarta.activation</groupId>
            <artifactId>jakarta.activation-api</artifactId>
            <version>2.1.2</version>
        </dependency>

        <!-- 适配jdk升级到9及以上,java.lang.NoClassDefFoundError : javax/xml/soap/SOAPException-->
        <!-- create SAAJ meta-factory: Provider com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl not found-->
        <dependency>
            <groupId>javax.xml.soap</groupId>
            <artifactId>javax.xml.soap-api</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.messaging.saaj</groupId>
            <artifactId>saaj-impl</artifactId>
            <version>1.5.1</version>
        </dependency>
	</dependencies>
文章来源:https://blog.csdn.net/ab601026460/article/details/135242324
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。