解決JDK9以上的非法反射訪問警告
阿新 • • 發佈:2020-09-19
1 問題描述
JDK9
以上很多庫都有這種非法反射訪問的警告,比如protostuff
:
解決方法兩個:
JDK
降級新增JVM
引數
2 原因
降到JDK8
能解決以上問題。
但是這不是本文的重點。
先說一下出現該警告的原因,筆者使用的JDK
為OpenJDK 11
,JDK9
以上模組不能使用反射去訪問非公有的成員/成員方法以及構造方法,除非模組標識為opens
去允許反射訪問。舊JDK
製作的庫(JDK8
及以下)執行在JDK9
上會自動被標識為未命名模組
,為了處理該警告,JDK9
以上提出了一個新的JVM
引數:--illegal-access
。
3 --illegal-access
該引數有四個可選值:
permit
:預設值,允許通過反射訪問,因此會提示像上面一樣的警告,這個是首次非法訪問警告,後續不警告warn
:每次非法訪問都會警告debug
:在warn
的基礎上加入了類似e.printStackTrace()
的功能deny
:禁止所有的非法訪問除了使用特別的命令列引數排除的模組,比如使用--add-opens
排除某些模組使其能夠通過非法反射訪問
因此解決的辦法很簡單,將其設定為deny
,並新增--add-opens
開啟對應的允許非法反射訪問的模組即可。
可以通過先設定為debug
找到對應的非法訪問的程式碼,比如protostuff
中的非法反射訪問程式碼段如下:
這都是JDK
基本模組的程式碼,因此,新增--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
--add-opens
可以使模組中的包對其他模組開放,這樣就可以在執行期使用深層反射訪問該程式包中的所有成員型別。
4 總結
因此解決的辦法是新增如下兩個JVM
引數:
--illegal-access=deny --add-opens java.base/java.lang=ALL-UNNAMED
IDEA
可以在執行配置中的VM options
中新增:
如果使用Maven
打包的時候還是會出現警告,可以在IDEA
中的Maven
配置中新增全域性的Maven
引數:
另外,如果使用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
測試也沒有問題了。