Converting xml to pdf with fop 1.1

Hi everybody

I’m trying to use fop 1.1 library to covert a xml file to pdf with the fop library on Webmethods 8.0.
The code I am using is quite basic, it’s actually the sample code from the fop home page except I have the xml data in a string rather than reading it from a file. I put all the jars file in the package/code/jars folder.

I keep getting the the following error:

The code is as follows:

IDataCursor idc = pipeline.getCursor();
String xmlString = IDataUtil.getString( idc, "xmlData" );
String xsltString = IDataUtil.getString ( idc, "xsltData" );
ByteArrayOutputStream out = new ByteArrayOutputStream();
FopFactory fopFactory = FopFactory.newInstance();
TransformerFactory tFactory = TransformerFactory.newInstance();
Source xml = new StreamSource( new StringReader( xmlString ) );
Source xslt = new StreamSource( new StringReader( xsltString ) );
try{
	FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
	foUserAgent.getRendererOptions();
	Fop fop = fopFactory.newFop( MimeConstants.MIME_PDF, foUserAgent, out );
	Transformer transformer = tFactory.newTransformer( xslt );
	Result res = new SAXResult( fop.getDefaultHandler() );
	transformer.transform( xml, res );
}
catch( FOPException e ){
	IDataUtil.put( idc, "errorMessage", e.getMessage() );
}
finally{
idc.destroy();
}

Does anybody have any experience with using the fop 1.1 library on a Webmethods server and could perhaps let me know where my problem lies.

thanks

Can you provide the value of xmlData and xsltData, so I can try it in my environment.

Here is the xml:

<?xml version="1.0" encoding="iso-8859-1"?>
<root>
<name>shyam</name>
<friend>
	<name>Abc</name>
	<phNo>90909090909</phNo>
</friend>
<friend>
	<name>Xyz</name>
	<phNo>32323232323</phNo>
</friend>
</root>

and this is the xslt:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.1"
	xmlns:xsl=http://www.w3.org/1999/XSL/Transform 
		xmlns:fo="http://www.w3.org/1999/XSL/Format"
	exclude-result-prefixes="fo">
<xsl:template match="root">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:layout-master-set>
    <fo:simple-page-master master-name="my-page">
      <fo:region-body margin="1in"/>
    </fo:simple-page-master>
  </fo:layout-master-set>

  <fo:page-sequence master-reference="my-page">
    <fo:flow flow-name="xsl-region-body">
      <fo:block>Hello, <xsl:value-of select="name" />!</fo:block>
      <fo:block>
      	<fo:table>
      		 <fo:table-body>
      		 	<fo:table-row>
                	<fo:table-cell border="solid 1px black" 
			text-align="center" font-weight="bold">
                		<fo:block>
                    		No.
                  		</fo:block>
                	</fo:table-cell>
                	<fo:table-cell border="solid 1px black" 
			text-align="center" font-weight="bold">
                		<fo:block>
                    		Name
                  		</fo:block>
                	</fo:table-cell>
                	<fo:table-cell border="solid 1px black" 
			text-align="center" font-weight="bold">
                		<fo:block>
                    		Phone Number
                  		</fo:block>
                	</fo:table-cell>
                </fo:table-row>
                <xsl:for-each select="./friend">
                	<fo:table-row>
                	<fo:table-cell border="solid 1px black" text-align="center">
                		<fo:block>
                    		<xsl:value-of select="position()" />
                  		</fo:block>
                	</fo:table-cell>
                	<fo:table-cell border="solid 1px black" text-align="center">
                		<fo:block>
                    		<xsl:value-of select="name" />
                  		</fo:block>
                	</fo:table-cell>
                	<fo:table-cell border="solid 1px black" text-align="center">
                		<fo:block>
                    		<xsl:value-of select="phNo" />
                  		</fo:block>
                	</fo:table-cell>
                </fo:table-row>
                </xsl:for-each>
      		 </fo:table-body>
      	</fo:table>
      </fo:block>
    </fo:flow>
  </fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>

This is just some test data I found online, it doesn’t matter however since I can’t get past the

Fop fop = fopFactory.newFop( MimeConstants.MIME_PDF, foUserAgent, out ); 

line. This line causes the previously mentioned error.

Hi Brynjolfur.

I got the same error.

How did you solved it?

Thanks

I actually haven’t been able to solve this problem yet, I’m still getting the same error. I’m wondering if there is a clash between libraries in server but haven’t been able to verify that yet. There is a older package on the server which uses a older version of Fop, however when I tried using the Fop 1.1 on a newly set up Wm 9.5 server I got the same error so if there is a clash of libraries its between something built into the IS.

I managed to get the transformer to run and produce a pdf file by adding the following code:

PDFRendererConfigurator pdfConfig = new PDFRendererConfigurator( foUserAgent );
PDFDocumentHandlerMaker pdfMaker = new PDFDocumentHandlerMaker();
IFDocumentHandler pdfHandler = pdfMaker.makeIFDocumentHandler( foUserAgent );
pdfConfig.configure( pdfHandler ); 
foUserAgent.setDocumentHandlerOverride( pdfHandler );

but the pdf file is corrupted so this solution doesn’t really work so now I am basically stuck.

This issue has now been resolved by adding the libraries to the Java ClassPath on the server, that is putting them into the
[b][install directory]\IntegrationServer\lib\jars[/b]
folder and restarting the server.

Hi Brynjolfur

Thanks for your quick update.

I’ve just tested and works fine.

Thank you very much.

Glad to hear issue resolved :smiley:

Hi All,

I am trying to convert XML String to PDF using fop library.
fop version: 1.0
wM version 8.2

i have placed the fop-sources.jar in IntegrationServer/lib/jars folder and restarted the server.

but i am not able to compile the code, getting error like.
flow.java:48: cannot find symbol
symbol : class FopFactory

can you please tell me what are the libraries you had imported while developing the code.
i have added java.util.* , java.io.*

Thanks,
Shiva

try to put the fop.jar, not fop-sources.jar to that dir.

Thanks Wang :smiley:
it worked!!!

i was able to write the file into Integration server directory.

but if try to send this file as a mail attachment ,the resulting PDF file seems to be corrupted.
i am passing PDF content as bytes to attachments/content and setting the ContentType =application/pdf.

anything else to be done?

Thanks,
Shiva

try to set: encoding=base64

Thanks Wang it worked :slight_smile:

Guys, I am using fop 2.2. I used following code (very much the same as what Brynjolfur shared above, but I get NullPointerException from the last line "transformer.transform( xml, res ). The xml and res objects are not null. What could be causing this error?


import com.wm.app.b2b.server.ServiceException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.pdf.PDFDocumentHandlerMaker;
import org.apache.fop.render.pdf.PDFRendererConfig;
import org.apache.fop.render.pdf.PDFRendererConfigurator;

		IDataCursor idc = pipeline.getCursor();  
		short linenum = 0;
		String xmlString = IDataUtil.getString( idc, "xmlData" );  
		String xsltString = IDataUtil.getString ( idc, "xsltData" );  
		String errMsg = "";
		
		ByteArrayOutputStream out = new ByteArrayOutputStream(); 
		
		FopFactory fopFactory = null;
		TransformerFactory tFactory = null;  
		Source xml = null;  
		Source xslt = null;  
		
		try{  
			fopFactory = FopFactory.newInstance(new File("./fop-2.2/conf/fop.xconf"));  
			linenum++; // 1
			tFactory = TransformerFactory.newInstance();  
			linenum++; // 2
			xml = new StreamSource( new StringReader( xmlString ) );  
			linenum++; // 3
			xslt = new StreamSource( new StringReader( xsltString ) ); 
			linenum++; // 4
			
		    FOUserAgent foUserAgent = fopFactory.newFOUserAgent();  
		    linenum++; // 5
		    PDFRendererConfigurator pdfConfig = new PDFRendererConfigurator( foUserAgent, new PDFRendererConfig.PDFRendererConfigParser() );  
		    linenum++; // 6
		    PDFDocumentHandlerMaker pdfMaker = new PDFDocumentHandlerMaker();  
		    linenum++; // 7 
		    IFDocumentHandler pdfHandler = pdfMaker.makeIFDocumentHandler( new IFContext(foUserAgent) );  		    
		    linenum++; // 8
		    pdfConfig.configure( pdfHandler );
		    linenum++; // 9
		    foUserAgent.setDocumentHandlerOverride( pdfHandler );
		    		    
		    linenum++; // 10
			foUserAgent.getRendererOptions();  
			linenum++; // 11
			Fop fop = fopFactory.newFop( MimeConstants.MIME_PDF, foUserAgent, out );  
			linenum++; // 12
			Transformer transformer = tFactory.newTransformer( xslt );  
			linenum++; // 13
			Result res = new SAXResult( fop.getDefaultHandler() ); 						
			linenum++; // 14
			transformer.transform( xml, res );
		}  
		catch( Exception e ){
			StringWriter sw = new StringWriter();
			e.printStackTrace(new PrintWriter(sw));
			errMsg = errMsg + "Error at linenum " + linenum + ": " + sw.toString();
		    IDataUtil.put( idc, "errorMessage", errMsg );  
		    throw new ServiceException (errMsg);
		}  
		finally{  
			
			if(out!=null) try {out.close();}catch(Exception e) {};
			idc.destroy();  
		}  

Well, I ended up using the sample from https://netjs.blogspot.com.tr/2015/07/how-to-create-pdf-from-xml-using-apache-fop.html. It worked.

can you provide the full error message