Java 6を引き続きサポートするように構築されたプロジェクトを取得しました。以下のコードは、コンパイラ準拠で構築されたjarファイルの中にありますレベル1.6修飾子 "public"を持つjava.nio.DirectByteBufferクラスのメンバーにアクセスできません
jarファイルは、Java 6以降で作成されたJavaアプリケーションから呼び出す必要があります。 Java 8でもうまく動作します。
は今Java9で、私はnio.DirectByteBufferで問題を取得し、私はリフレクションを使用して、このようにそれを解決しようとした:
@SuppressWarnings("unchecked")
static void cleanDirectBuffer(sun.nio.ch.DirectBuffer buffer) {
if (JAVA_VERSION < 1.9) {
sun.misc.Cleaner cleaner = buffer.cleaner();
if (cleaner != null) cleaner.clean();
} else {
// For java9 do it the reflection way
@SuppressWarnings("rawtypes")
Class B = buffer.getClass();
// will be a java.nio.DirectBuffer, which is unknown if compiled in 1.6 compliance mode
try {
java.lang.reflect.Method CleanerMethod = B.getMethod("cleaner");
CleanerMethod.setAccessible(true); // fails here !
Object cleaner = CleanerMethod.invoke(buffer);
if (cleaner == null) return;
@SuppressWarnings("rawtypes")
Class C = cleaner.getClass();
java.lang.reflect.Method CleanMethod = C.getMethod("clean");
CleanMethod.invoke(cleaner);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception other) {
other.printStackTrace();
}
}
}
次に、java_version検出が細かく、バージョン私の呼び出しに応じて、きれいに切り替えコードが使用しています。 jre6からjre8環境ではsun.misc.Cleanerパスがうまく使えますが、java9ではうまく動作しません。
私はjava.reflectionの専門家ではないでしょう。 は推測では、私は.setAccessible(true);
とランス-Javaの答えを見つけました(ありがとう今のところ)ビットを助けた:
バージョン2:
Class B = buffer.getClass();
try {
java.lang.reflect.Method CleanerMethod = B.getDeclaredMethod("cleaner");
CleanerMethod.setAccessible(true);
Object cleaner = CleanerMethod.invoke(buffer);
if (cleaner == null) return;
@SuppressWarnings("rawtypes")
Class C = cleaner.getClass();
java.lang.reflect.Method CleanMethod = C.getDeclaredMethod("clean");
CleanMethod.setAccessible(true); // Now it fails here !
CleanMethod.invoke(cleaner);
} catch (InaccessibleObjectException e) {
// ** causes: Unable to make public void jdk.internal.ref.Cleaner.clean() accessible: module java.base does not "exports jdk.internal.ref" to unnamed module **
}
最初CleanerMethod.setAccessible(true)
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by my.package.MyClass (file:/xyz.jar) to method java.nio.DirectByteBuffer.cleaner()
...
WARNING: All illegal access operations will be denied in a future release
...あまりにも健康的に聞こえませんか?しかし、悲しいかな、それは警告のみです:)
私の欠点は何ですか、あるいは私の問題とは異なる/より良いアプローチがありますか?
ですが、メソッドcleaner() 'is' public? – datafiddler