javapdfitextwebspherewebsphere-9

iText hangs in adding element to document in WebSphere


I have a legacy application that uses itext 5.5.6 on java 1.8.0_171 64 bit which runs on Websphere application server ND 9.0.5.13 and Windows server 216 standard version 1607 64 bit and I am using it to convert html to pdf I am facing an issue when there's a very large word (till 30 thousand character) entered from the end user like:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....till 30 thousand character

it makes Itext hangs in the following line and not throwing any exceptions:

document.add(myPdfPTable)

This behavior doesn't happen on tomcat server

below is my code:

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 After enabling hung thread detection in websphere I was able to find the Hung thread cause:

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: found out that finally the file is created but it takes around 15 minutes to be created while the file size is only 350 KB but it consists of 280 pages, while same request on tomcat 9 java 8 takes 30 seconds to complete so it's seems to be a Websphere issue.

UPDATE3: Based on comments below it maybe a monitoring issue so I disabled Performance Monitoring Infrastructure (PMI) but still facing same issue, so it maybe a JVM args config issue, so here's my JVM Args:

-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:

enter image description here


Solution

  • Judging by the stacktrace:

    at com.ibm.tivoli.itcam...
    

    you have ITCAM enabled on your WebSphere server. ITCAM is a monitoring tool and it seems to be causing your issue.

    If you want to disable it, see this page.

    Or removing the following JVM arguments:

    -Dcom.ibm.tivoli.itcam.ai.runtimebuilder.inputs=${ITCAMDCHOME}/runtime/AppSrv01.Ry1vFnicnStg01Node01Cell.Ry1vFnicnStg01Node01.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