Enterprise Java

Apache FOP Integration with Eclipse and OSGi

Apache FOP is an open source print processor driven by XSL formatting objects (XSL-FO). It can be quite useful to transform data objects into a PDF for example. However it turned out to be somewhat cumbersome to get it integrated into PDE and finally up and running as OSGi Service.

Because of this I provided a P2 repository that contains the necessary bundles within a single feature. This way PDE target setup got much easier. The following sections explain how to use it.

Apache FOP

As stated by the documentation Apache FOP ‘is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. Output formats currently supported include PDF, PS, PCL, AFP, XML (area tree representation), Print, AWT and PNG, and to a lesser extent, RTF and TXT. The primary output target is PDF’.

Of course it is possible to embed the processor into a Java program. Based on on JAXP, Apache FOP relies on SAX events to receive the XSL-FO input document. A basic usage snippet looks somewhat like this:

InputStream in = ... // the fo tree to process
  OutputStream out = ... // pdf destination
  FopFactory fopFactory = FopFactory.newInstance();
  try {
    Fop fop = fopFactory.newFop( MimeConstants.MIME_PDF, out );
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer();
    Source source = new StreamSource( in );
    Result result = new SAXResult( fop.getDefaultHandler() );
    transformer.transform( source, result );
  } finally {
    out.flush();
  }

For a detailed explanation of Apache FOP embedded usage please refer to the online documentation.

Dependency Hell

While the snippet looks straight forward, integration in Eclipse/OSGi was not that easy. Maybe I behaved stupidly, but it took me almost two days to assemble a target definition, which eventually did the trick.

To avoid this problem in the future and give others who may run into the same trap a better start, I created the P2 repository mentioned at the beginning. In order to use it simply add the repository location as Software Site to your Eclipse target definition:

fop-target-integration

Now define the dependencies of the bundle that should contain the processor. These dependencies are org.apache.servicemix.bundles.fop and org.apache.servicemix.bundles.xmlgraphics-commons:

fop-dependencies

Once those are in place the code above compiles. It is easy to develope a service class having a format method for PDF generation with a signature as shown here:

public class FopService {
  
  private final FopFactory fopFactory;

  public FopService() {
    this.fopFactory = FopFactory.newInstance();
  }
  
  public void format(
    InputStream input, OutputStream output, InputStream stylesheet )
  {
    [...] // similar transformation code like above
  }
}

I knitted a simple usage example project that provides more details. The project contains an example.target that already integrates Apache FOP. After importing the project, resolve and set its target definition in your Eclipse workspace. Run the ‘FOP example’ launch configuration. Last but not least open a browser and go to the URL http://localhost:10080/services/pdf.

A freshly created PDF should be ready for download:

pdf-download

The xml and xsl documents used to generate the PDF are the same as those processed by the ExampleXML2PDF class of the embedding Apache FOP examples. The PDF contains a simple listing of members of a fictive development team.

resulting-pdf

Be aware that ‘Apache FOP may currently not be completely thread safe’ (see the Multithreading FOP section, of the
Apache FOP: Embedding). Naturally a real world scenario must take this into account, in particular if running in a multithreaded server environment.

Wrap Up

Although the road was a bit bumpy at the beginning the Apache FOP integration works fine now. So if you want to checkout the example by yourself, it is located at https://github.com/fappel/FOP

The P2 repository is hosted at http://fappel.github.io/FOP/

In case you run into a problem or have any questions or suggestions you might add an issue at the GitHub project or leave a comment in the section below.

Reference: Apache FOP Integration with Eclipse and OSGi from our JCG partner Frank Appel at the Code Affine blog.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button