Apache PDFBox已关闭PDDocument仍报未关闭PDF文档警告问题求助
警告触发原因
- 异常路径资源未关闭:你当前的
close()方法全部写在正常业务逻辑的末尾,只要执行过程中任意一步抛出IOException(比如图片读取失败、PDF保存失败、临时文件创建失败等),后续的close()逻辑都会跳过,未被关闭的PDDocument实例就会触发该警告。 - 关闭时机顺序问题:你代码中
InputStream的关闭放在了doc.save()之后,虽然不是该警告的直接诱因,但也存在异常场景下流泄漏的风险。 - PDFBox版本bug:2.0.x系列的早期版本存在资源计数器误判的已知问题,即使显式关闭了
PDDocument,也可能误报该警告。 - 其他调用链路漏关:该警告是全局统计的,可能是其他调用
PDDocument的代码片段存在漏关,并非你当前这段代码导致。
排查解决方法
- 优先使用try-with-resources自动管理所有可关闭资源,无需手动编写
close()逻辑,无论是否出现异常都会自动释放资源,修改后代码示例如下:
private File imageToPDDocument(Path mergeDirectory, File file) throws IOException { File pdfFile = Files.createTempFile(mergeDirectory, String.valueOf(System.currentTimeMillis()), ".tmp").toFile(); // 所有实现AutoCloseable的资源都放在try括号中,执行完成自动关闭 try ( PDDocument doc = new PDDocument(); InputStream in = new FileInputStream(file); ) { BufferedImage bimg = ImageIO.read(in); float width = bimg.getWidth(); float height = bimg.getHeight(); PDPage page = new PDPage(new PDRectangle(width, height)); doc.addPage(page); PDImageXObject img = PDImageXObject.createFromFileByContent(file, doc); try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) { contentStream.drawImage(img, 0, 0); } doc.save(pdfFile); } return pdfFile; }
- 升级Apache PDFBox到最新稳定版(建议2.0.32及以上版本),修复版本自带的资源计数误判问题。
- 开启PDFBox调试日志定位漏关实例:将日志框架中
org.apache.pdfbox的日志级别调整为DEBUG,日志会打印每个PDDocument实例创建时的堆栈信息,对照堆栈即可定位到未正常关闭的文档实例所属的代码位置。 - 若确认所有资源都已正常关闭,也可通过调整日志级别屏蔽警告:将
org.apache.pdfbox.cos.COSDocument的日志级别设置为ERROR,即可屏蔽该警告输出(仅建议临时调试使用,不推荐作为最终解决方案)。
内容的提问来源于stack exchange,提问作者Leah
相关产品推荐
相关产品推荐

