使用jira-javamelody-1.57.1.jar生成PDF时出现Stack Overflow Error求助
这个问题我之前也碰到过!你遇到的StackOverflowError本质是无限递归调用导致的,咱们来拆解下原因和解决办法:
你在ProductRequestPage2的onEndPage方法里添加表格的操作,触发了死循环调用链:
- 当你调用
document.add(table)时,如果表格内容刚好需要创建新页面,会触发PdfDocument.newPage() - 而
newPage()会自动调用onEndPage事件方法 - 这又会再次执行
document.add(table),循环往复直到栈内存耗尽
从你的堆栈跟踪也能清晰看到这个循环链路:
Caused by: java.lang.StackOverflowError
at com.lowagie.text.pdf.events.PdfPageEventForwarder.onEndPage(Unknown Source) ~[itext-2.1.7.jar:?]
at com.lowagie.text.pdf.PdfDocument.newPage(Unknown Source) ~[itext-2.1.7.jar:?]
at com.lowagie.text.pdf.PdfDocument.carriageReturn(Unknown Source) ~[itext-2.1.7.jar:?]
at com.lowagie.text.pdf.PdfDocument.add(Unknown Source) ~[itext-2.1.7.jar:?]
at com.ocr.pcs.action.ProductRequestPdf$ProductRequestPage2.onEndPage(ProductRequestPdf.java:1675) ~[?:?]
at com.lowagie.text.pdf.events.PdfPageEventForwarder.onEndPage(Unknown Source) ~[itext-2.1.7.jar:?]
...
1. 把内容移到onStartPage方法
如果这个表格是页眉类的固定内容,更适合放在onStartPage里——这个方法是在页面刚创建时触发,不会因为添加内容触发分页而递归调用:
class ProductRequestPage2 extends PdfPageEventHelper { public void onStartPage(PdfWriter writer, Document document) { // 这里添加你的表格代码 Table table = new Table(1); table.setWidth(100); table.setTableFitsPage(true); table.setBorderWidth(0); table.setBorder(0); table.getDefaultCell().setBorder(0); table.setOffset(5); Cell secondCell = new Cell(new Phrase("", new Font(bf2, 9))); table.addCell(secondCell); secondCell = new Cell(new Phrase("Global Export Control ", new Font(bf2, 9))); secondCell.setBackgroundColor(new Color(0xC1, 0xC0, 0xC0)); secondCell.setHorizontalAlignment(Element.ALIGN_LEFT); secondCell.setVerticalAlignment(Element.ALIGN_MIDDLE); secondCell.setLeading(9); table.addCell(secondCell); document.add(table); } public void onEndPage(PdfWriter writer, Document document) { // 只保留不会触发分页的简单操作,比如设置页码等 } }
2. 强制onEndPage中的内容不触发分页
如果必须在onEndPage添加内容,要确保它绝对不会超出当前页面剩余空间:
- 给表格设置固定高度,比如
table.setFixedHeight(20);(根据你的字体大小调整) - 关闭
table.setTableFitsPage(true);,避免它自动触发分页 - 提前计算页面剩余高度,确保表格高度小于剩余高度
3. 调整内容添加时机
把这个表格的添加逻辑移到主文档内容的处理流程中,而不是放在页面事件里,从根源上避免事件递归的问题。
核心原则就是不要在onEndPage事件中执行会触发分页的内容添加操作——onEndPage本身就是分页完成时的回调,再触发分页就会形成无限循环。
内容的提问来源于stack exchange,提问作者vishnu

