升级到Java 17没这么简单
前言
最近在给公司新架构做技术选型,刚好 Java 17 也正式发布一段日子了,而且是LTS
长期支持版本,就想着直接用起来吧,里面有些特性还是非常好用的,比如:
- JEP 378:文本块支持
- JEP 395:Record 类型
- JEP 286:变量类型推导
- More...
cglib
和javassist
的框架可能都会因此导致项目无法启动,抛出如下异常:Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @39aeed2f
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at net.sf.cglib.core.ReflectUtils$1.run(ReflectUtils.java:61)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:554)
at net.sf.cglib.core.ReflectUtils.(ReflectUtils.java:52)
at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:243)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:332)
从 Java 16 开始,JEP 396会默认把
--illegal-access
参数设置为deny
,即默认禁用访问封装的包以及反射其他模块,这样就会导致上面的异常,在此之前该参数默认值一直都是--illegal-access=permit
,只会产生警告,而不会报错,所以如果是 Java 16 的话需要在执行 Java 程序时把--illegal-access
设置为permit
,这样就可以解决问题,示例:java -jar --illegal-access=permit app.jar
从 Java 17 开始就更狠了,JEP 403直接把
--illegal-access
参数移除了,如果需要启用访问封装的包,需要在执行 Java 程序时加上--add-opens java.base/java.lang=ALL-UNNAMED
选型,示例:java -jar --add-opens java.base/java.lang=ALL-UNNAMED app.jar
如果是在 IDEA 中运行需要配置对应的 VM 参数,示例:
文章图片
虽然说加完参数之后是可以跑起来,但是我认为这是一个破坏性的改动,因为这样的话,如果有一天 Java 版本变化了,参数又失效了,那么所有的项目都需要更新,这样会导致项目的维护成本大大增加,所以这里不建议使用。
开源框架升级进度跟踪 那么有没有办法不加启动参数就能正常运行呢,答案是肯定的,只不过需要等开源框架全换算 Java 17 的新 API,目前我跟踪到的两个项目都还没有适配 Java 17。
Spring
【升级到Java 17没这么简单】SpringBoot 2.5.0 开始支持 Java 17,没啥问题。
apollo 配置中心
apollo 目前的 master 分支代码是已经适配好了,但是还没有正式发版,比较奇怪的事是, apollo 之前升级了底层依赖包来适配 Java 17,但是后来又回滚回来了,不知道是出于什么原因。
dubbo
dubbo 有个issue 7593四月份就提出来了,但是一直没人跟进。
总结 一顿操作下来发现不行,最终还是先换成了 Java 15,待时机成熟的时候再升级到 Java 17。
我是 MonkeyWie,欢迎扫码关注!不定期在公众号中分享JAVA
、Golang
、前端
、docker
、k8s
等干货知识。
文章图片
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 2018-02-06第三天|2018-02-06第三天 不能再了,反思到位就差改变
- 一个小故事,我的思考。
- 第三节|第三节 快乐和幸福(12)
- 你到家了吗
- 遇到一哭二闹三打滚的孩子,怎么办┃山伯教育
- 死结。
- 赢在人生六项精进二阶Day3复盘
- jhipster|jhipster 升级无效问题
- 子龙老师语录