I have an App Engine Java Maven project, configured with the following dependencies
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.9</version>
<exclusions>
<exclusion>
<artifactId>itextpdf</artifactId>
<groupId>com.itextpdf</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextg</artifactId>
<version>5.5.9</version>
</dependency>
I'm using an exclusion strategy to ignore the main iText release and use the iTextG version, specific for Android/App Engine
My project is configured to receive an html input, a css file and some font files in order to make a PDF file.
Here the partial code related to the font loading
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
for (java.io.File fontFile : fontFiles) {
fontProvider.register(fontFile.getAbsolutePath());
}
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
...
In the localhost environment there are no problem, the PDF is correctly generated. In the online environment I get this error
java.lang.NoClassDefFoundError: java.nio.MappedByteBuffer is a restricted class. Please see the Google App Engine developer's guide for more details.
at com.google.apphosting.runtime.security.shared.stub.java.nio.channels.FileChannel_.map(FileChannel.java)
at com.itextpdf.text.io.MappedChannelRandomAccessSource.open(MappedChannelRandomAccessSource.java:105)
at com.itextpdf.text.io.FileChannelRandomAccessSource.<init>(FileChannelRandomAccessSource.java:74)
at com.itextpdf.text.io.RandomAccessSourceFactory.createBestSource(RandomAccessSourceFactory.java:240)
at com.itextpdf.text.io.RandomAccessSourceFactory.createBestSource(RandomAccessSourceFactory.java:224)
at com.itextpdf.text.io.RandomAccessSourceFactory.createBestSource(RandomAccessSourceFactory.java:191)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.<init>(RandomAccessFileOrArray.java:151)
at com.itextpdf.text.pdf.TrueTypeFont.process(TrueTypeFont.java:800)
at com.itextpdf.text.pdf.TrueTypeFont.<init>(TrueTypeFont.java:499)
at com.itextpdf.text.pdf.BaseFont.getAllFontNames(BaseFont.java:1233)
at com.itextpdf.text.FontFactoryImp.register(FontFactoryImp.java:452)
at com.itextpdf.text.FontFactoryImp.register(FontFactoryImp.java:439)
From the searches I already done, I found two important notes:
To avoid this kind of problem I need to use a Font
object, created directly from the font bytes. This is a code example
The blacklisted classes (java.nio.MappedByteBuffer) cannot be removed in the G version of the library because it is used in other contexts
The problem here is I cannot register a Font
object inside the XMLWorkerFontProvider
, it seems that the Font object can be used directly with the main API of iText but not with the XMLWorker tool.
Are there any solutions to this kind of problem? Is it really not possible to use custom font inside an html work, running inside App Engine?