2017-12-19 5 views
0

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 

...あまりにも健康的に聞こえませんか?しかし、悲しいかな、それは警告のみです:)

私の欠点は何ですか、あるいは私の問題とは異なる/より良いアプローチがありますか?

答えて

0

Class.getMethod()およびClass.getField()などは、パブリックメソッド/フィールドのみを返します。私はClass.getDeclaredMethod()が必要だと思います。

+0

ですが、メソッドcleaner() 'is' public? – datafiddler

関連する問題