Itext Java 11: незаконный рефлексивный доступ. Com.itextpdf.io.source.ByteBufferRandomAccessSource$1

Недавно обновился до 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 (file:...repository/com/itextpdf/io/7.0.0/io-7.0.0.jar) to метод java.nio.DirectByteBuffer.cleaner() ПРЕДУПРЕЖДЕНИЕ. Пожалуйста, рассмотрите возможность сообщения об этом сопровождающим com.itextpdf.io.source.ByteBufferRandomAccessSource $ 1. ПРЕДУПРЕЖДЕНИЕ. Используйте --illegal-access=warn, чтобы включить предупреждения о дальнейшем незаконном отражающем доступе. операции ПРЕДУПРЕЖДЕНИЕ. Все незаконные операции доступа будут запрещены в будущем выпуске.

2 ответа

Решение

В то время как я оставляю комментарии, призывающие вас отладить код и найти основную причину (а затем отправить запрос на извлечение), или создать проблему в iText Jira, если вы являетесь клиентом с контрактом на поддержку (что повысит приоритет проблемы).), вот обходное решение (которое я не проверял, но, скорее всего, оно будет работать):

использование PdfReader а также PdfWriter конструкторы, которые принимают InputStream а также OutputStreamсоответственно. В этом случае код, вызывающий проблему, не должен вызываться. То же самое для всех остальных случаев, когда iText взаимодействует с вашей файловой системой - все обернуть в 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[] вместо String представляющий путь к файлу и так далее.

Если вам интересно, что такое нелегальный рефлексивный доступ, пожалуйста, обратитесь сюда: что такое нелегальный рефлексивный доступ?

Это конкретное предупреждение исходит от этого класса:

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 работать должным образом, я думаю, что лучшее, что вы можете сделать, - это отправить вопрос /PR команде iText и подождать, пока будет доступно правильное исправление.

Другие вопросы по тегам