Java9 or 10 で、Google guice 使用の実行で、
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1
to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
と警告メッセージが出る!
Java 9 (JDK-9) support for guice · Issue #1085 · google/guice · GitHub
で、取り上げられてこの課題は close したけど、
https://github.com/google/guice/issues/1133
。。。やはりまだ解決してなかった。
Java 9 以降、深いリフレクションは使用してはいけない方針だからか。。。
プログラム実行時に、JVM引数として、
--illegal-access=deny
を付ければ、警告は収まるんだけど、
いや、JVM引数じゃなくて、他の方法があった!
System.err.close(); System.setErr(System.out);
を実行するメソッドを用意して実行しておくというのがあるけど、これは何か例外発生時停止する場合に
期待どおりに標準エラー出力されない危険がある。何しろ、System.err.close(); 実行だからだ。
StackOverFlow にもっと良い方法が載ってた。。
How to hide warning "Illegal reflective access" in java 9 without JVM argument? - Stack Overflow
public static void disableModileAccessWarning() { try{ Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); Unsafe u = (Unsafe) theUnsafe.get(null); Class cls = Class.forName("jdk.internal.module.IllegalAccessLogger"); Field logger = cls.getDeclaredField("logger"); u.putObjectVolatile(cls, u.staticFieldOffset(logger), null); }catch(Exception e){ // ignore } }
これを、Guice 使用の前に実行する。
なるほど、警告ログを出すところを抑え込んでしまうのか。。
前提として、Guice のバージョン 4.2.0 以上を使ってこれ以前の対応は必要。
どうせ、昔とちがって、そうそうリフレクションをするコードを書く機会は減ったし
もう、module の IllegalAccess をわざわざ起こすような危険なコードは、Guice 使用以外で
書くこともないだろう。