NullPointerException during textFragment.getTextState().setFont(defaultFont);

Hi,
When I try to change Font for textFragment I have got NullPointerException. Could you help me with it?
aspose-pdf:18.9
java 1.8.0_101-b13
Red Hat 4.4.7-18

textFragment.getTextState().setFont(defaultFont);

java.lang.NullPointerException: null
at com.aspose.pdf.internal.l15l.I57.l5if(Unknown Source)
at com.aspose.pdf.Copier.lif(Unknown Source)
at com.aspose.pdf.Copier.lif(Unknown Source)
at com.aspose.pdf.Copier.duplicate(Unknown Source)
at com.aspose.pdf.Copier.duplicate(Unknown Source)
at com.aspose.pdf.internal.l134.I07.lif(Unknown Source)
at com.aspose.pdf.TextState.setFont(Unknown Source)
at com.aspose.pdf.TextFragmentState.setFont(Unknown Source)
at processor.PdfToHtmlProcessor.substituteUnavailableFontsWithDefault(PdfToHtmlProcessor.java:175)
at processor.PdfToHtmlProcessor.convertPdfToHtml(PdfToHtmlProcessor.java:112)
at processor.PdfToHtmlProcessor.lambda$1(PdfToHtmlProcessor.java:81)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at processor.PdfToHtmlProcessor.processDocument(PdfToHtmlProcessor.java:81)
at converter.DocumentConverter.convert(DocumentConverter.java:43)
at mapper.CondorSplitterMapper.map(CondorSplitterMapper.java:39)
at mapper.CondorSplitterMapper.map(CondorSplitterMapper.java:1)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:793)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:164)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1917)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)

@JaroslawPigula

Thanks for contacting support.

Would you please make sure that the font you are trying to set, exists/installed in the machine. In case you still face issue with font is present, please share your sample PDF document with complete sample code snippet. We will test the scenario in our environment and address it accordingly.

Hi, Thanks for answer.
Unfortunately I can’t share to you any pdf documents. I have to install font on machine? There is no possible to set this in application? I can’t to install it on all machines. We use MapReduce so we have a lot of it.

private void substituteUnavailableFontsWithDefault(com.aspose.pdf.Document document, Set unavailableFontNames) {
TextFragmentAbsorber absorber = new TextFragmentAbsorber(new TextEditOptions(TextEditOptions.FontReplace.RemoveUnusedFonts));
document.getPages().accept(absorber);
TextFragmentCollection textFragmentCollection = absorber.getTextFragments();

    for (Iterator<TextFragment> iterator = textFragmentCollection.iterator(); iterator.hasNext(); ) {
        TextFragment textFragment = iterator.next();
        String fragmentFontName = textFragment.getTextState().getFont().getFontName();
        if (textFragment.getText().trim().length() > 0 && unavailableFontNames.contains(fragmentFontName)) {
            textFragment.getTextState().setFont(defaultFont);
        }
    }
}

I Attached file with fonts ( defaultFont object).
OpenSans-Regular.zip (113.4 KB)

@JaroslawPigula

Thanks for sharing more details.

In case you want to use a font from FontRepository and embed it into PDF document, it should be installed in the machine. However, in case you are using it from a file in system, you can set it using following line of code:

textFragment.getTextState().setFont(FontRepository.openFont(dataDir + "OpenSans-Regular.ttf"));

In your shared code snippet, font setting method was unclear so we used above line of code in our environment for testing purposes and observed no issue. In the output sample PDF document, the specified font (OpenSans-Regular) was also present. Would you please use above line of code at your side and in case you still face any issue, please share sample console application which is able to replicate the issue. We will again test the scenario in our environment and address it accordingly.

Thanks for response. Below my method to load fonts from stream:

private Font loadDefaultFont() throws IOException {
LOGGER.info(“Loading pdf to html converter’s default font from location [{}]”, DEFAULT_FONT_FILE_PATH);
InputStream fontFileInputStream = getClass().getResourceAsStream(DEFAULT_FONT_FILE_PATH);
return FontRepository.openFont(fontFileInputStream, FontTypes.TTF);

}

I’m using this method to get Fonts.
Summarizing I need to install fonts on whole machine? There is no possible to set these fonts from no default location? And second question. Why there I received NullPointerException without any information. What is wrong with the code?

@JaroslawPigula

Thanks for writing back and sharing more details.

If a font file is present in the system, we can set it using FontRepository.OpenFont() method and font doesn’t need to be installed in system.

We have checked the method which you have shared for loading default font and were able to notice a NullReferenceException NullRef.png (2.4 KB). It seemed that API is not loading font from an input stream. However, when we modified the method as follows, the font was loaded successfully and sample PDF was processed.

private com.aspose.pdf.Font loadDefaultFont() throws IOException {
		return FontRepository.openFont(dataDir + "OpenSans-Regular.ttf");
}

You may please try using method like above in your code and let us know if it resolves the issue. As far as the occurring exception is concerned, we have logged an issue as PDFJAVA-38106 in our issue tracking system for further investigation. We will investigate the issue in details and keep you posted with the status of its correction. Please be patient and spare us little time.

We are sorry for the inconvenience.

@JaroslawPigula

We have further investigated the issue and found that it is not a bug. Please note that the font should be added to resources. If the TTF file is not placed into resources, the class loader cannot find the font and returns null. Also, we can load InputStream without classloader but using direct file path:

private com.aspose.pdf.Font loadDefaultFont(String dataDir) throws Exception {
        InputStream fontFileInputStream = new FileInputStream(dataDir + "OpenSans-Regular.ttf");
// This nullpointer should be handled on your side:
        if (fontFileInputStream == null) {
            throw new Exception("The font is not loaded to stream.");
        }
        return FontRepository.openFont(fontFileInputStream, com.aspose.pdf.text.FontTypes.TTF);
    }