Skip to content

java

Generating PDF with Apache FOP and Maven. An example and some tricks.

This January (and, actually, February) I worked on generating PDF files. During the investigation process, we’ve chosen Apache FOP as a free powerful tool for this task.

Firstly I wanted to write a step by step guide on how to generate a PDF file from a Java object. But eventually, I decided to keep it short, as the original documentation contains almost all you need.

So in this blog I’ll describe some interesting moments that I met during the development phase.

Also, I’ve prepared an example project, feel free to clone and play around:
https://github.com/savva-k/apache-fop-example

Adding custom fonts to FOP

Adding fonts is pretty simple. I used an XML config, so I will show how to do that in XML:

<?xml version="1.0"?>
<fop version="1.0">
    <!-- Simple FOP XML config -->
    
    <base>.</base>
    <strict-validation>false</strict-validation>
    <strict-configuration>false</strict-configuration>
    <source-resolution>72</source-resolution>
    <target-resolution>72</target-resolution>
    <default-page-settings height="11.00in" width="8.50in"/>
    <renderers>
        <renderer mime="application/pdf">
            <fonts>
                <font kerning="yes" embed-url="path/to/Roboto-Regular.ttf" embedding-mode="subset">
                    <font-triplet name="Roboto" style="normal" weight="normal"/>
                </font>
                <font kerning="yes" embed-url="path/to/Roboto-Bold.ttf" embedding-mode="subset">
                    <font-triplet name="Roboto" style="normal" weight="Bold"/>
                </font>
            </fonts>
        </renderer>
    </renderers>
</fop>

Then we can use the font by setting the font-family attribute:

<fo:root font-family="Roboto">
    <someContent>
        This font is regular.
        <fo:inline font-weight="bold">This font is bold.</fo:inline>
    </someContent>
</fo:root>

How to use WOFF fonts with Apache FOP?

I didn’t find the answer to this question. But I’ve found a good WOFF to OTF conversion tool! Here it is: https://github.com/hanikesn/woff2otf
OTF fonts work fine with FOP.

How to access fonts from resources in a JAR?

At some time I realized that all the fonts are placed in a JAR file and other resources like images from external servers are not. To solve this problem I have created a custom ResourceResolver implementation:

    public final class CustomPathResolver implements ResourceResolver {
        private static final String FONTS_FOLDER = "/fonts/";

        private ResourceResolver defaultResourceResolver = ResourceResolverFactory.createDefaultResourceResolver();

        @Override
        public Resource getResource(URI uri) throws IOException {
            if (uri.toString().contains(FONTS_FOLDER)) {
                return new Resource(PdfGenerator.class.getResourceAsStream(FONTS_FOLDER + FilenameUtils.getName(uri.toString())));
            } else {
                return new Resource(uri.toURL().openStream());
            }
        }

        @Override
        public OutputStream getOutputStream(URI uri) throws IOException {
            return defaultResourceResolver.getOutputStream(uri);
        }
    }

This ResourceResolver checks whether the requested resource is in the “fonts” folder and if so, we are looking for a resource in the classpath.
To use this ResourceResolver we should manually specify it during the FopFactoryBuilder creation.

DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
try {
    Configuration config = cfgBuilder.build(PdfGenerator.class.getResourceAsStream(CONFIG_FOP_XML));
    FopFactoryBuilder factoryBuilder = new FopFactoryBuilder(new File(CURRENT_DIR).toURI(), new CustomPathResolver()).setConfiguration(config);
    fopFactory = factoryBuilder.build();
} catch (Exception e) {
    // handling the error
}

Apache FOP cannot load images via HTTPS

In my case, the root cause was the SSLHandshakeException. My server didn’t trust the server that hosted the image. I wouldn’t do that neither!

This problem has at least three solutions: the best, a good one and the one I had to use.

The best solution: use a certificate issued by a well known CA on the server that hosts your images.

A good solution: add the server’s certificate to your keystore.

The last solution is to disable checking certificate validity at all. This is not recommended, as you become vulnerable to man-in-the-middle attacks.
To do this, you should implement a new TrustManager and a HostnameVerifier, initialize an SSLContext and set the HostnameVerifier to the HttpsURLConnection (which is used internally by Apache FOP).

static {
    TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
        public void checkClientTrusted(X509Certificate[] certs, String authType) {
        }
        public void checkServerTrusted(X509Certificate[] certs, String authType) {
        }
        }
    };

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}

I think that’s it and I hope this helps. 🙂

Passed the Oracle 1Z0-808 certification

Good news, everyone!

Even though this is the first blog in 2018, I’m still alive and I’m happy to say that I have passed the Oracle Certified Associate exam with 94% of correct answers (I still can’t believe it 😱).

It took about a month to prepare and I was spending all my free the time after work to read a book and write and test code examples.

While preparing, I have made more than a hundred of small notes, and I hope to find time and motivation in the next two months to post them here.

See you in 2019 🙂🎄

Using StringBuilder instead of usual concatenation. When is it appropriate?

You might know that using string concatenation in Java is not a good practice as it might affect performance. In this short article, I will try to describe when it is necessary to use StringBuilder and when we can afford using concatenation (+ sign).

Let’s start with a simple example:

package com.imsavva;

public class ConcatenationTestApp {

    public static void main(String[] args) {
        String str = "abc";
        str = str + "def";
        str += "12" + "34" + str;

        System.out.println(str);
    }
}

To see how it works under the hood, let’s compile and decompile it. I tried this using Java 6 and Java 8.

Compiling the code:

javac src/com/imsavva/ConcatenationTestApp.java

Decompiling the class:

javap -c src/com/imsavva/ConcatenationTestApp

Continue reading to see what happens next.

Read More →

UnhandledExceptionHandler in Java: how to catch uncaught exceptions

UncaughtExceptionHandler in Java

In this short tutorial, I’m going to describe how to handle uncaught exceptions in threads. This can be done by:

  • Using threadInstance.setUncaughtExceptionHandler() ─ for a specific thread
  • Overriding ThreadGroup’s uncaughtException() method ─ for a thread group
  • Using Thread.setDefaultUncaughtExceptionHandler() ─ for all threads

If you’re interested in how to implement this, press “read more”, I’ve prepared an example.

Read More →

Parsing a date string to ISO8601 with Joda Time

Recently, I faced a date conversion task: convert a string date “yyyy-MM-ddZ” (i.e. “1983-09-15+03:00”) to the ISO8601 standard “yyyy-MM-dd’T’HH:mm:ss.SSSZ” (i.e. “1983-09-15T03:00:00.000+03:00”).

I used Apache Joda time to convert date. First, add a Maven dependency in pom.xml

<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.9.4</version>
</dependency>

Read More →

Achievement unlocked. Sololearn Java certificate.

Sololearn Java course

Yesterday I finished a Java course with the Sololearn iPhone appilcation. Just for fun. I had some free time and decided, why not to study Java on my mobile phone, so that’s how I found this app. What can I say about it? It gives very little knowledge about Java.

There are 6 sections in this course: basic concepts, conditionals and loops, arrays, classes and objects, more on classes, and the last one, exceptions, lists, threads and files. Each section contain a small piece of theory and some ordinary practical tasks. I wonder, how have developers decided to combine such large themes as collections and threads (and exceptions and files)?

I don’t know what’s the target audience of this app. If you’re a beginner, you probably shouldn’t download it, because it’d be better to read some good Java books. The application can’t give you even 1/10 of needed knowledge. If you have some Java experience, you probably won’t discover anything new.

My mark: ❤️❤️❤️💙💙💙💙💙💙💙

How to create an ATG pipeline processor?

I’m currently studying Oracle ATG. Kinda big monstrous eCommerce platform. Today I had to create a commerce pipeline processor. So, I started googling and found this great tutorial by Oracle: Creating processors. Well, that’s not bad. But it’s a bit poor. For example, I’d like to know, what is the Object pParam? What is the PipelineResult pResult? Actually, there’s the third (unanswered) question: why all parameters starts with “p”?

Ok, I’ve found some answers to my questions. Let’s see.

Read More →

Observer pattern

Observer is a software design pattern, that is used when some objects create events and other objects should be notified when these events occur.

The main idea is that we have two types of instances: one that produces events and one that consumes them. Events producer must have three methods:

  1. addObserver(Observer observer)
  2. removeObserver(Observer observer)
  3. notifyObservers(…)

The first two methods are used to add and delete observers from a collection. The third method must iterate that collection and call notify(…) method of the Observer instance.

Java has its own Observer interface and Observable class, but sometimes we don’t want to extend from a class, or we want to adjust the API, you can create your own interfaces, as I’ve done in the following example:

Read More →