我有一个在java 1.8.0_171 64 bit上使用itext 5.5.6的遗留应用程序,它在Websphere application server ND 9.0.5.13和Windows server 216 standard version 1607 64 bit上运行,我正在使用它将html转换为pdf. 我遇到了一个问题,终端用户输入了一个非常长的单词(最多30000个字符),比如:
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....till 3万个字符
它使IText挂起在以下行中,并且不引发任何异常:
document.add(myPdfPTable)
此行为不会在Tomcat服务器上发生
下面是我的代码:
public Document generatePDF(String fontPath,String html) throws Exception {
com.itextpdf.text.Document document = new com.itextpdf.text.Document(PageSize.A4, 20, 20, 100, 50);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pdfWriter = PdfWriter.getInstance(document, baos);
pdfWriter.setPageEvent(ppaHeaderFooter);
pdfWriter.setViewerPreferences(PdfWriter.PageModeUseOC);
pdfWriter.setPdfVersion(PdfWriter.VERSION_1_5);
document.open();
document.addAuthor(authorName);
document.addCreator(authorName);
document.addSubject(filename);
document.addCreationDate();
document.addTitle(filename);
Font arabicFont = FontFactory.getFont(fontPath, BaseFont.IDENTITY_H, 14);
FontFactory.register(fontPath);
Font bold = FontFactory.getFont(fontPath, BaseFont.IDENTITY_H, 14f, Font.BOLD);
Font regularfont = FontFactory.getFont(fontPath, BaseFont.IDENTITY_H, 10);
List<Element> pdfElements = getElementsFromHtml(html, fontPath);
PdfPTable contentTable = new PdfPTable(1);
contentTable.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
contentTable.setSplitLate(false);
contentTable.setWidthPercentage(90);
contentTable.setExtendLastRow(true);
for (Element element : pdfElements) {
PdfPCell cell = new PdfPCell();
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_CENTER);
cell.setBorder(Rectangle.NO_BORDER);
cell.setArabicOptions(ColumnText.DIGITS_EN2AN);
cell.addElement(element);
contentTable.addCell(cell);
}
document.add(contentTable);
return document;
}
public ArrayList<Element> getElementsFromHtml(final String html, String fontPath) throws IOException {
final ElementList elements = new ElementList();
StringBuilder stylefile = new StringBuilder();
stylefile.append("body {font-size: 14pt;font-family:MyCustomFont;line-height: 1.5;dir:rtl}");
stylefile.append("table{padding: 0px;border-spacing: 0px;font-size: 14pt;}");
stylefile.append("td{height:30px;}");
CSSResolver cssResolver = new StyleAttrCSSResolver();
CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(stylefile.toString().getBytes()));
cssResolver.addCss(cssFile);
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register(fontPath, "MyCustomFont");
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
final ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
final HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, end);
final CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
final XMLWorker worker = new XMLWorker(cssPipeline, true);
final XMLParser p = new XMLParser(worker, Charset.forName("UTF-8"));
final String resolvedHtml = "<body>" + html + "</body>";
p.parse(new ByteArrayInputStream(resolvedHtml.getBytes(Charset.forName("UTF-8"))), Charset.forName("UTF-8"));
return new ArrayList<Element>(elements);
}
UPDATE1 在websphere中启用挂起线程检测后,我能够找到挂起线程的原因:
ThreadMonitor W WSVR0605W: Thread "WebContainer : 4" (00003bed) has been active for 672628 milliseconds and may be hung. There is/are 1 thread(s) in total in the server that may be hung.
at com.ibm.tivoli.itcam.gdc.data.GDCInstanceDataManager.resetProvisional(GDCInstanceDataManager.java:489)
at com.ibm.tivoli.itcam.gdc.GDCMethodProbePoint.customProbeEndEvent(GDCMethodProbePoint.java:1691)
at com.ibm.tivoli.itcam.toolkit.ai.boot.callbacks.generic.CustomProbeCallback.customProbeAfterCallbackInstance(CustomProbeCallback.java:450)
at com.ibm.tivoli.itcam.toolkit.ai.boot.callbacks.generic.CustomProbeCallback.customProbeAfterCallback(CustomProbeCallback.java:409)
at com.itextpdf.text.pdf.PdfFont.width(PdfFont.java:138)
at com.itextpdf.text.pdf.PdfChunk.getCharWidth(PdfChunk.java:961)
at com.itextpdf.text.pdf.BidiLine.processLine(BidiLine.java:383)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:1068)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:990)
at com.itextpdf.text.pdf.ColumnText.goComposite(ColumnText.java:1523)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:996)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:990)
at com.itextpdf.text.pdf.PdfPCell.getMaxHeight(PdfPCell.java:1044)
at com.itextpdf.text.pdf.PdfPTable.getFittingRows(PdfPTable.java:2141)
at com.itextpdf.text.pdf.ColumnText.goComposite(ColumnText.java:1753)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:996)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:990)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:978)
at com.itextpdf.text.pdf.PdfDocument.addPTable(PdfDocument.java:2673)
at com.itextpdf.text.pdf.PdfDocument.add(PdfDocument.java:750)
at com.itextpdf.text.Document.add(Document.java:278)
UPDATE2:发现文件最终被创建了,但它需要大约15分钟才能创建,而文件大小只有350 KB,但它由280页组成,而在Tomcat 9 Java 8上,同样的请求需要30秒才能完成,所以这似乎是一个Websphere问题.
UPDATE3:根据下面的 comments ,它可能是监控问题,所以我禁用了性能监控基础设施(PMI),但仍然面临相同的问题,所以它可能是JVM参数配置问题,所以以下是我的JVM参数:
-Dcom.ibm.jsse2.overrideDefaultProtocol=TLSv12
-Dcom.ibm.jsse2.overrideDefaultTLS=true
-DFileNet.WSI.AutoDetectLTPAToken=true
-Dcom.filenet.authentication.token.userid=sso:ltpa
-Dam.wasserver=server1
-Dam.wasnode=MyNode01
-Dam.wasprofile=AppSrv01
-Dam.wascell=MyNode01Cell
-Dcom.ibm.tivoli.itcam.ai.runtimebuilder.inputs=${ITCAMDCHOME}/runtime/AppSrv01.MyNode01Cell.MyNode01.server1.DCManualInput.txt
-Dws.bundle.metadata=${ITCAMDCHOME}/runtime/wsBundleMetaData
-Djava.security.policy=${ITCAMDCHOME}/itcamdc/etc/datacollector.policy
-Xbootclasspath/p:${ITCAMDCHOME}/toolkit/lib/bcm-bootstrap.jar
-Dsun.rmi.transport.connectionTimeout=300000
-Dsun.rmi.dgc.server.gcInterval=3600000
-Dsun.rmi.dgc.client.gcInterval=3600000-verbosegc -Xgc:allocationSamplingGranularity=10000
-Xhealthcenter:transport=jrmp,level=inprocess
-agentlib:am_ibm_16=${WAS_SERVER_NAME}
-Djava.net.preferIPv6Addresses=false
-Djava.net.preferIPv4Stack=true
-Dcom.ibm.cacheLocalHost=true
-Djaxws.payload.highFidelity=true
-Djava.security.auth.login.config=C:\FileNet\AE\config\jaas.conf.WebSphere -agentlib:getClasses
JVM Custom Properties:个