共计 2243 个字符,预计需要花费 6 分钟才能阅读完成。
前言
最近在给公司新架构做技术选型,刚好 Java 17 也正式公布一段日子了,而且是 LTS
长期反对版本,就想着间接用起来吧,外面有些个性还是十分好用的,比方:
- JEP 378:文本块反对
- JEP 395:Record 类型
- JEP 286:变量类型推导
- More…
遇到的问题
其中最次要的起因就是 Java 模块化之后,有些 jdk 外部的类不能被拜访了,然而在 Java 16 之前都只是正告,而在 Java 16 之后则会间接报错,目前依赖了 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.<clinit>(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
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
等干货常识。