Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PDFBox: Disable Font Cache or change its location

Tags:

java

pdfbox

When I call PDField.setValue to set the value for a form field, I get the following stacktrace:

FileSystemFontProvider.saveDiskCache(349) | Could not write to font cache
java.io.FileNotFoundException: /.pdfbox.cache (Permission denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
at java.io.FileOutputStream.<init>(FileOutputStream.java:145)
at java.io.FileWriter.<init>(FileWriter.java:73)
at org.apache.pdfbox.pdmodel.font.FileSystemFontProvider.saveDiskCache(FileSystemFontProvider.java:290)
at org.apache.pdfbox.pdmodel.font.FileSystemFontProvider.<init>(FileSystemFontProvider.java:226)
at org.apache.pdfbox.pdmodel.font.FontMapperImpl$DefaultFontProvider.<clinit>(FontMapperImpl.java:130)
at org.apache.pdfbox.pdmodel.font.FontMapperImpl.getProvider(FontMapperImpl.java:149)
at org.apache.pdfbox.pdmodel.font.FontMapperImpl.findFont(FontMapperImpl.java:413)
at org.apache.pdfbox.pdmodel.font.FontMapperImpl.findFontBoxFont(FontMapperImpl.java:376)
at org.apache.pdfbox.pdmodel.font.FontMapperImpl.getFontBoxFont(FontMapperImpl.java:350)
at org.apache.pdfbox.pdmodel.font.PDType1Font.<init>(PDType1Font.java:145)
at org.apache.pdfbox.pdmodel.font.PDType1Font.<clinit>(PDType1Font.java:79)
at org.apache.pdfbox.pdmodel.font.PDFontFactory.createFont(PDFontFactory.java:62)
at org.apache.pdfbox.pdmodel.PDResources.getFont(PDResources.java:143)
at org.apache.pdfbox.pdmodel.interactive.form.PDDefaultAppearanceString.processSetFont(PDDefaultAppearanceString.java:164)
at org.apache.pdfbox.pdmodel.interactive.form.PDDefaultAppearanceString.processOperator(PDDefaultAppearanceString.java:131)
at org.apache.pdfbox.pdmodel.interactive.form.PDDefaultAppearanceString.processAppearanceStringOperators(PDDefaultAppearanceString.java:107)
at org.apache.pdfbox.pdmodel.interactive.form.PDDefaultAppearanceString.<init>(PDDefaultAppearanceString.java:85)
at org.apache.pdfbox.pdmodel.interactive.form.PDVariableText.getDefaultAppearanceString(PDVariableText.java:93)
at org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.<init>(AppearanceGeneratorHelper.java:94)
at org.apache.pdfbox.pdmodel.interactive.form.PDTextField.constructAppearances(PDTextField.java:262)
at org.apache.pdfbox.pdmodel.interactive.form.PDTerminalField.applyChange(PDTerminalField.java:228)
at org.apache.pdfbox.pdmodel.interactive.form.PDTextField.setValue(PDTextField.java:218)

I am running PDFBox 2.0.4 which is the newest version. My webserver most likely does not have access to write to .pdfbox.cache in the default location (which seems to be the JVM property user.home). Is there any way to disable the disk caching or change the location of the cache file?

I did notice that I can set a JVM wide system property called pdfbox.fontcache, but my webapp shares a jvm with other applications so this isn't an optimal solution. I also tried using that solution and setting the pdfbox.fontcache to /tmp, but it didn't actually create a file (although it now only throws the stacktrace once per boot).

I looked into the code in the FileSystemFontProvider and the problematic code seems to be in the saveDiskCache method. In that method, it first tries to write the file, but a FileNotFoundException is thrown instead of a SecurityException. FileNotFoundException inherits from IOException.

File file = getDiskCacheFile();
try
{
     writer = new BufferedWriter(new FileWriter(file));
}
catch (SecurityException e)
{
     return;
}
like image 646
user7335428 Avatar asked Dec 23 '16 16:12

user7335428


1 Answers

When you set pdfbox.fontcache with a temporary folder like /tmp where your JVM can write new file inside then a cache file called .pdfbox.cache can be created when you generate PDF with PDFBox (I also use PDFBox 2.0.4).

Maybe your JVM cannot create a new file inside your /tmp directory? To check this try to create a new file with the user running your JVM with an interactive command prompt (shell).

With the command ls -lA /tmp you should see a .pdfbox.cache file in the temporary folder that you configure (example with a tomcat JVM and user):

-rw-r--r-- 1 tomcat tomcat 2050 Dec 29 16:13 .pdfbox.cache

It's not an optimal solution because you can't set multiple pdfbox.fontcache system property on a single JVM.

like image 51
Sylvain Bugat Avatar answered Oct 16 '22 14:10

Sylvain Bugat