2017-12-19 1 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);

을 발견하고 랜스 - 자바의 대답은 (덕분에 지금까지) 조금 도움이 :

버전 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() 메소드가 public입니까? – datafiddler

관련 문제