Java 10中的非法反射访问操作警告

时间:2018-09-08 07:01:14

标签: java reflection openpdf

我希望提供一些帮助来重写一些使用反射的Java代码,以消除Java 10上编译器的警告:

这是有问题的Java方法:

public static boolean clean(final java.nio.ByteBuffer buffer) {
    if (buffer == null || !buffer.isDirect())
        return false;

    Boolean b = (Boolean) AccessController.doPrivileged(new PrivilegedAction() {
        public Object run() {
            Boolean success = Boolean.FALSE;
            try {
                Method getCleanerMethod = buffer.getClass().getMethod("cleaner", (Class[])null);
                getCleanerMethod.setAccessible(true);
                Object cleaner = getCleanerMethod.invoke(buffer, (Object[])null);
                Method clean = cleaner.getClass().getMethod("clean", (Class[])null);
                clean.invoke(cleaner, (Object[])null);
                success = Boolean.TRUE;
            } catch (Exception e) {
                // This really is a show stopper on windows
                //e.printStackTrace();
            }
            return success;
        }
    });

    return b.booleanValue();
}

这是GitHub上有问题的代码:https://github.com/LibrePDF/OpenPDF/blob/master/openpdf/src/main/java/com/lowagie/text/pdf/MappedRandomAccessFile.java#L199

这是我在Java 10上编译时得到的警告:

  

警告:发生了非法的反射访问操作   警告:com.lowagie.text.pdf.MappedRandomAccessFile $ 1(文件:/ [从此处删除本地路径] /openpdf.jar)对方法java.nio.DirectByteBuffer.cleaner()的非法反射访问   警告:请考虑将此报告给com.lowagie.text.pdf.MappedRandomAccessFile $ 1的维护者   警告:使用--illegal-access = warn启用有关进一步非法反射访问操作的警告   警告:在将来的版本中,所有非法访问操作都将被拒绝

可以在以下位置找到该库:https://github.com/LibrePDF/OpenPDF

有关如何正确解决此问题的帮助吗?应该将代码重写为不使用反射吗?我可以在支持的Java库中用一些类似的代码替换MappedRandomAccessFile类吗?

(我是OpenPDF的维护者之一,在这方面需要一些帮助)

谢谢!

1 个答案:

答案 0 :(得分:3)

我看到这个问题已经报告给图书馆的维护者了; 参见https://github.com/LibrePDF/OpenPDF/issues/101

现在,您可以忽略该消息,因为它只是一个警告。

  

我可以用受支持的Java库中的类似代码替换MappedRandomAccessFile类吗?

没有人会阻止您:-)但是,如果您要提出建议,那是不合时宜的。

您的另一种选择是等待LibrePDF维护人员对其进行修复。

但是,我怀疑他们不会...因为他们不能。您应该查看一下2005年未解决的Java Bug报告:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4724038。我认为这意味着MappedRandomAccessFile只能通过修复Java错误来解决,这将使对cleaner()的非法调用变得不必要。


经过进一步的挖掘,我发现了这一点:

这描述了一个问题,GC调用清洁器可能无法“保持”,从而导致OOME过早。此问题已在Java 9中得到修复,并且该修复已回补至Java 8和7。

您需要做的是检查代码库的历史记录和问题,并尝试弄清楚为什么MappedRandomAccessFile类中包含“更干净的”代码。如果主要是要解决JDK-6857566的问题,那么您应该现在可以将其删除。