Configuration and deployment of PDF printing in APEX 4.1.1 using GlassFish 3.1.2 and Apache FOP

Environment: Oracle database 11.2.0.3, APEX 4.1.1, GlassFish 3.1.2 Open Source Edition (Web Profile), Oracle Linux 6.2

Update: Apache FOP support has been deprecated in ORDS 19.2. So please don’t upgrade to ORDS 19.2 (or higher) if you still rely on Apache FOP for PDF generation.

Apache FOP (XSL-FO Processor) can be used together with APEX to allow PDF printing of classic or interactive reports. In this blog post, I will explain how you can deploy and configure FOP in APEX 4.1.1 with GlassFish 3.1.2.

Apache FOP can be installed on a Java application server by deploying the fop.war web archive, which can be found in the /utilities/fop folder inside the APEX installation files. However, the fop.war file does not work out of the box on GlassFish 3.1.2.

I faced two different kind of errors in my installation:

1) package oracle.xml.parser.v2 does not exist: this is because GlassFish can’t find the xmlparserv2.jar file which can be found in $ORACLE_HOME/lib.

2) java.lang.IllegalStateException: getOutputStream() has already been called: this has something to do with getOutputStream() being used more than once; I’m far from a Java specialist, but I found a workaround for this problem on the internet.

This is the solution:

First, we need to extract the original fop.war file (I used the jar utility from my Java 6 JDK installation):

$ /u01/app/java/java6/bin/jar -xf fop.war

You should see the following:

$ ls -la

-rw-r–r– 1 oracle oinstall 1792 May 4 12:44 apex_fop.jsp
-rw-r–r– 1 oracle oinstall 7016135 May 4 12:44 fop.war
drwxr-xr-x 4 oracle oinstall 4096 May 4 14:00 WEB-INF

Next, copy the xmlparserv2.jar file from $ORACLE_HOME/lib into the WEB-INF/lib folder:

$ cp -p /u01/app/oracle/product/11.2.0/db_1/lib/xmlparserv2.jar WEB-INF/lib

Now we need to modify the two apex_fop.jsp files in the top folder and under WEB-INF/classes. Add the following 2 lines just before the final “driver.run();” call:

out.clear();
out = pageContext.pushBody();

The full apex_fop.jsp file should look like this:










Now we are going to recreate the fop.war file:

$ /u01/app/java/java6/bin/jar -cvf fop.war apex_fop.jsp WEB-INF

We are now ready to deploy the fop.war file in GlassFish:

– start up the GlassFish admin console (default: port 4848)

– click on Standalone Instances -> your instance

– click on Applications -> Deploy -> local packaged file… and browse to the “fop.war” file (see screenshot below)

– click on OK; “fop” should now appear in the list of Deployed Applications

After this, you can already test your Apache FOP deployment by opening http://<servername&gt;:<port>/fop/apex_fop.jsp in a web browser. If you see a Java NullPointerException error, things are looking good ;-)

Finally, we need to tell APEX where to find the print server:

– log in to the APEX workspace “internal” with the username “admin”

– click on Manage Instance -> Instance Settings

– fill in the Report Printing part (see screenshot below):

Print Server: External (Apache FOP)
Print Server Host Address: localhost
Print Server Port: (your APEX port)
Print Server Script: /fop/apex_fop.jsp

That’s it! Now try to print a report as PDF in APEX; it should work fine!

 

Matthias