PDFBox:禁用字体缓存或更改其位置

PDFBox: Disable Font Cache or change its location

当我调用 PDField.setValue 设置表单字段的值时,我得到以下堆栈跟踪:

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)

我是运行 PDFBox 2.0.4,这是最新版本。我的网络服务器很可能无法在默认位置(似乎是 JVM 属性 user.home)写入 .pdfbox.cache。有没有办法禁用磁盘缓存或更改缓存文件的位置?

我确实注意到我可以设置一个名为 pdfbox.fontcache 的 JVM 范围系统 属性,但是我的 webapp 与其他应用程序共享一个 jvm,因此这不是最佳解决方案。我也尝试使用该解决方案并将 pdfbox.fontcache 设置为 /tmp,但它实际上并没有创建文件(尽管它现在每次启动只抛出一次堆栈跟踪)。

我查看了 FileSystemFontProvider and the problematic code seems to be in the saveDiskCache 方法中的代码。在该方法中,它首先尝试写入文件,但抛出 FileNotFoundException 而不是 SecurityException。 FileNotFoundException 继承自 IOException.

File file = getDiskCacheFile();
try
{
     writer = new BufferedWriter(new FileWriter(file));
}
catch (SecurityException e)
{
     return;
}

当您设置 pdfbox.fontcache 为临时文件夹,如 /tmp,您的 JVM 可以在其中写入新文件,然后当您使用 PDFBox 生成 PDF 时,可以创建一个名为 .pdfbox.cache 的缓存文件(我也用PDFBox 2.0.4)。

也许您的 JVM 无法在 /tmp 目录中创建新文件?要检查这一点,请尝试使用交互式命令提示符 (shell) 与用户 运行 您的 JVM 创建一个新文件。

使用命令 ls -lA /tmp 您应该会在您配置的临时文件夹中看到一个 .pdfbox.cache 文件(使用 tomcat JVM 和用户的示例):

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

这不是最佳解决方案,因为您无法在单个 JVM 上设置多个 pdfbox.fontcache 系统 属性。