解決JDK9以上的非法反射訪問警告的問題
1 問題描述
JDK9以上很多庫都有這種非法反射訪問的警告,比如protostuff:

解決方法兩個:
JDK降級添加JVM參數(shù)
2 原因
降到JDK8能解決以上問題。
但是這不是本文的重點。
先說一下出現(xiàn)該警告的原因,筆者使用的JDK為OpenJDK 11,JDK9以上模塊不能使用反射去訪問非公有的成員/成員方法以及構(gòu)造方法,除非模塊標識為opens去允許反射訪問。舊JDK制作的庫(JDK8及以下)運行在JDK9上會自動被標識為未命名模塊,為了處理該警告,JDK9以上提出了一個新的JVM參數(shù):--illegal-access。
3--illegal-access
該參數(shù)有四個可選值:
permit:默認值,允許通過反射訪問,因此會提示像上面一樣的警告,這個是首次非法訪問警告,后續(xù)不警告warn:每次非法訪問都會警告debug:在warn的基礎(chǔ)上加入了類似e.printStackTrace()的功能deny:禁止所有的非法訪問除了使用特別的命令行參數(shù)排除的模塊,比如使用--add-opens排除某些模塊使其能夠通過非法反射訪問
因此解決的辦法很簡單,將其設(shè)置為deny,并添加--add-opens開啟對應的允許非法反射訪問的模塊即可。
可以通過先設(shè)置為debug找到對應的非法訪問的代碼,比如protostuff中的非法反射訪問代碼段如下:


這都是JDK基本模塊的代碼,因此,添加--add-opens=java.base/java.lang.invoke=ALL-UNNAMED即可。--add-opens可以使模塊中的包對其他模塊開放,這樣就可以在運行期使用深層反射訪問該程序包中的所有成員類型。
4 總結(jié)
因此解決的辦法是添加如下兩個JVM參數(shù):
--illegal-access=deny --add-opens java.base/java.lang=ALL-UNNAMED
IDEA可以在運行配置中的VM options中添加:

如果使用Maven打包的時候還是會出現(xiàn)警告,可以在IDEA中的Maven配置中添加全局的Maven參數(shù):

另外,如果使用Gradle而不是Maven作為管理工具,Gradle測試的時候還是會顯示警告,盡管Gradle運行配置里面有VM Options選項:

但在這里添加是沒用的,正確的做法是在build.gradle中添加:
test {
useJUnitPlatform()
jvmArgs('--illegal-access=deny')
jvmArgs('--add-opens', 'java.base/java.lang.invoke=ALL-UNNAMED')
}
這樣Gradle測試也沒有問題了。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring @Value 設(shè)置默認值的實現(xiàn)
這篇文章主要介紹了Spring @Value 設(shè)置默認值的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09
詳解SpringBoot實現(xiàn)JPA的save方法不更新null屬性
直接調(diào)用原生Save方法會導致null屬性覆蓋到數(shù)據(jù)庫,使用起來十分不方便。本文詳細的介紹了如何解決這個問題,非常具有實用價值,需要的朋友可以參考下2018-12-12
Spring boot2基于Mybatis實現(xiàn)多表關(guān)聯(lián)查詢
這篇文章主要介紹了Spring boot2基于Mybatis實現(xiàn)多表關(guān)聯(lián)查詢,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-04-04
Spring中三種常見Bean的初始化參數(shù)機制你了解嗎
在Spring框架中,Bean的實例化與初始化是一個復雜的過程,本文我們主要來聊一聊它的常見的三種機制:InitializingBean接口、BeanDefinitionRegistryPostProcessor接口和EnvironmentAware接口,感興趣的小伙伴可以了解下2023-11-11
解決RestTemplate加@Autowired注入不了的問題
這篇文章主要介紹了解決RestTemplate加@Autowired注入不了的問題,具有很好的參考價值,希望對大家有所幫助。2021-08-08

