Total Pageviews

2016/07/04

[PDFBox] Building on-disk font cache, this may take a while

Problem
I am using PDFBox to convert PDF file to TIF files. 
It works in Windows platform, but fail to execute in AIX platformt. 

We can see the warning message in System.out.log:
1
2
[WARN][WebContainer : 11][Line:444][org.apache.pdfbox.pdmodel.font.FileSystemFontProvider.loadDiskCache]New fonts found, font cache will be re-built
[WARN][WebContainer : 11][Line:224][org.apache.pdfbox.pdmodel.font.FileSystemFontProvider.<init>]Building on-disk font cache, this may take a while

This warning message is printed from here:
https://github.com/apache/pdfbox/blob/04292e421e9531616aa2856b908fbdb05b381af7/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FileSystemFontProvider.java#L224-L226

But it is difficult to judge the root causes why it spend lots of time to load font files
https://github.com/apache/pdfbox/blob/04292e421e9531616aa2856b908fbdb05b381af7/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FileSystemFontProvider.java#L237-L277


Solution
In FontMapperImpl, we can see it add lots of fonts substitutes. It may be the reason:
https://github.com/apache/pdfbox/blob/04292e421e9531616aa2856b908fbdb05b381af7/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FontMapperImpl.java#L55-L127


Hence, we write a PdfBoxInitiazlier class to set empty collection to FontMapperImpl:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package org.apache.pdfbox.pdmodel.font;

import java.util.Collections;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.stereotype.Component;

@Component
public class PdfBoxInitiazlier {
    @PostConstruct
    public void setUpPdfBox() {
        FontMapperImpl mapper = new FontMapperImpl();
        FontProvider provider = new EmptyFontProvider();
        mapper.setProvider(provider);
        org.apache.pdfbox.pdmodel.font.FontMappers.set(mapper);
    }

    private static class EmptyFontProvider extends FontProvider {
        public String toDebugString() {
            return "EmptyFontProvider"; 
        }
        public List<? extends FontInfo> getFontInfo() {
            return Collections.emptyList();
        }
    }
}


Owing to our project use Spring boot, then PdfBoxInitiazlier component will be scanned and overwrited it.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import lombok.extern.slf4j.Slf4j;

import org.apache.pdfbox.pdmodel.font.PdfBoxInitiazlier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;

import com.cht.compost.context.web.CompostServletInitializer;
import com.yuantalife.ecp.manage.common.EcpManageConfiguration;
import com.yuantalife.ecp.member.EcpManageMemberConfiguration;

@Slf4j
@SpringBootApplication
@ComponentScan({ "com.xxx.ecp" })
@Import({ EcpManageConfiguration.class, EcpManageMemberConfiguration.class })
public class Application extends CompostServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public PdfBoxInitiazlier pdfBoxInitializer() {
        log.info("enter pdfBoxInitializer");
        return new PdfBoxInitiazlier();
    }
}

It is a workaround solution to fix "Building on-disk font cache, this may take a while" warning problem. 
Although it is just a warning message, it result in my function cannot be executed successfully.




No comments: