itext Java 11:com.itextpdf.io.source.ByteBufferRandomAccessSource $ 1的非法反射访问

时间:2018-11-14 13:17:31

标签: java itext itext7 java-11

最近升级到Java 11,并开始执行回归检查。当前尝试调用com.itextpdf.text.pdf.PdfReader.close时收到非法的反射访问错误。当前在Itext版本5.5.13上,但在itext 7.0.0上也尝试过,并且存在相同的问题。

有人对如何解决Java-11与Itext之间的兼容性问题有任何建议吗?

  

警告:发生了非法的反射访问操作警告:   非法反射访问者   com.itextpdf.io.source.ByteBufferRandomAccessSource $ 1   (文件:... repository / com / itextpdf / io / 7.0.0 / io-7.0.0.jar)转换为方法   java.nio.DirectByteBuffer.cleaner()警告:请考虑报告   这对维护者   com.itextpdf.io.source.ByteBufferRandomAccessSource $ 1警告:使用   --illegal-access =警告启用进一步的非法反射访问操作的警告警告:所有非法访问操作都将   在以后的版本中被拒绝

2 个答案:

答案 0 :(得分:1)

虽然我赞同第二条评论,鼓励您调试代码并找到根本原因(然后提交拉取请求),或者如果您是拥有支持合同的客户,则在iText Jira中创建问题(这会提高优先级)问题),这是一种变通方法建议(我尚未测试,但很可能会起作用):

使用分别接受PdfReaderPdfWriter的{​​{1}}和InputStream构造函数。在这种情况下,不应调用导致问题的代码。对于iText与文件系统交互的所有其他情况,这都是相同的-将所有内容包装到OutputStream / InputStream中,或处理OutputStream数组。

所以这行:

byte[]

成为这个:

new PdfDocument(new PdfReader(inFilePath), new PdfWriter(outFilePath))

您可能还希望将流包装到new PdfDocument(new PdfReader(new FileInputStream(inFilePath)), new PdfWriter(new FileOutputStream(outFilePath))) / BufferedInputStream中。

类似地,在处理BufferedOutputStream时,请使用接受PdfFontFactory而不是代表文件路径的byte[]等方法。

答案 1 :(得分:0)

如果您想知道“非法反射访问”的全部含义,请访问此处:what is an illegal reflective access

此特殊警告来自此类:

https://github.com/itext/itext7/blob/develop/io/src/main/java/com/itextpdf/io/source/ByteBufferRandomAccessSource.java

通过这种特定方法:

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

    Boolean b = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
        public Boolean run() {
            Boolean success = Boolean.FALSE;
            try {
                // java 9
                if (UNMAP_SUPPORTED)
                    CLEANER.freeBuffer(buffer.toString(), buffer);
                // java 8 and lower
                else {
                    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
                Logger logger = LoggerFactory.getLogger(ByteBufferRandomAccessSource.class);
                logger.debug(e.getMessage());
            }
            return success;
        }
    });

    return b;
}

此行正好:

getCleanerMethod.setAccessible(true);

只要此警告不会阻止iText正常工作,我认为您最好的办法是向iText团队提交问题/ PR,并等待适当的修复程序可用。