Itext Java 11:com.itextpdf.io.source.ByteBufferRandomAccessSource$1 的非法反射访问
Itext Java 11: Illegal reflective access by com.itextpdf.io.source.ByteBufferRandomAccessSource$1
最近升级到 Java11 并开始执行回归检查。目前在尝试调用 com.itextpdf.text.pdf.PdfReader.close
时遇到非法反射访问错误。目前在 itext 版本 5.5.13 上,但也尝试在 itext 7.0.0 上遇到同样的问题。
有没有人对如何解决 Java-11 和 Itext 之间的兼容性问题有任何建议?
WARNING: An illegal reflective access operation has occurred WARNING:
Illegal reflective access by
com.itextpdf.io.source.ByteBufferRandomAccessSource
(file:...repository/com/itextpdf/io/7.0.0/io-7.0.0.jar) to method
java.nio.DirectByteBuffer.cleaner() WARNING: Please consider reporting
this to the maintainers of
com.itextpdf.io.source.ByteBufferRandomAccessSource WARNING: Use
--illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be
denied in a future release
如果你想知道非法反射访问是什么,请参考这里:
此特定警告来自此 class:
来自这个特定的方法:
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 团队提交 issue/PR 并等待适当的修复可用。
虽然我支持鼓励您调试代码并找到根本原因(然后提交拉取请求)或在 iText Jira 中创建问题的评论,如果您是具有支持合同的客户(这会引发问题的优先级),这是一个解决方法建议(我还没有测试过,但我很可能会奏效):
使用分别接受InputStream
和OutputStream
的PdfReader
和PdfWriter
构造函数。在这种情况下,不应调用引起问题的代码。对于 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
表示文件路径等。
最近升级到 Java11 并开始执行回归检查。目前在尝试调用 com.itextpdf.text.pdf.PdfReader.close
时遇到非法反射访问错误。目前在 itext 版本 5.5.13 上,但也尝试在 itext 7.0.0 上遇到同样的问题。
有没有人对如何解决 Java-11 和 Itext 之间的兼容性问题有任何建议?
WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by com.itextpdf.io.source.ByteBufferRandomAccessSource (file:...repository/com/itextpdf/io/7.0.0/io-7.0.0.jar) to method java.nio.DirectByteBuffer.cleaner() WARNING: Please consider reporting this to the maintainers of com.itextpdf.io.source.ByteBufferRandomAccessSource WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release
如果你想知道非法反射访问是什么,请参考这里:
此特定警告来自此 class:
来自这个特定的方法:
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 团队提交 issue/PR 并等待适当的修复可用。
虽然我支持鼓励您调试代码并找到根本原因(然后提交拉取请求)或在 iText Jira 中创建问题的评论,如果您是具有支持合同的客户(这会引发问题的优先级),这是一个解决方法建议(我还没有测试过,但我很可能会奏效):
使用分别接受InputStream
和OutputStream
的PdfReader
和PdfWriter
构造函数。在这种情况下,不应调用引起问题的代码。对于 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
表示文件路径等。