Rion Halili
Rion Halili

Reputation: 11

Upgrading to 11.4.6 causes java.lang.NoClassDefFoundError: Could not initialize class org.docx4j.fonts.IdentityPlusMapper

Case: Writing a docx as pdf using WordprocessingMLPackage and setting the fontMapper using IdentityPlusMapper() from org.docx4j.fonts to map the fonts in the document we receive:

java.lang.NoClassDefFoundError: Could not initialize class org.docx4j.fonts.IdentityPlusMapper

at: getFontMapper()

This happens after upgrading from docx4j 11.2.8 to 11.4.6.

Dependencies in usage are:

org.docx4j:docx4j-core:11.4.6
org.docx4j:docx4j-export-fo:11.4.6
org.docx4j:docx4j-JAXB-ReferenceImpl:11.4.6

Is this a known issue already?

Looking forward to a possible reply!

Thanks in advance.

Upvotes: 1

Views: 1421

Answers (3)

Sachin Verma
Sachin Verma

Reputation: 81

I have fixed the same by setting regex for fonts available in Mac which's recommened by PhysicalFonts class set regex method as well.

           PhysicalFonts.regex = ".*(Courier New|Arial|Times New Roman|Comic Sans|Georgia|Impact|Lucida Console|Lucida Sans Unicode|Palatino Linotype|Tahoma|Trebuchet|Verdana|Symbol|Webdings|Wingdings|MS Sans Serif|MS Serif).*"

Upvotes: 0

Anirban Chakraborty
Anirban Chakraborty

Reputation: 11

This assertion error is appearing from the static block of the IdentityPlusMapper or the BestMatchingMapper whatever we use. The exact line is:

PhysicalFonts.discoverPhysicalFonts();

The fix of the problem is to restrict fonts loading before the static block using font selection regex as stated in the javadoc of:

PhysicalFonts.setRegex()

The following way quickly solved the problem along with that it reduces memory utilization and the static block's execution time:

WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
                            .load(new ByteArrayInputStream(os.toByteArray()));
String fontRegex = ".*(Courier New|Arial|Times New Roman|Comic Sans|Georgia|Impact|Lucida Console|Lucida Sans Unicode|Palatino Linotype|Tahoma|Trebuchet|Verdana|Symbol|Webdings|Wingdings|MS Sans Serif|MS Serif).*";
                    
if(System.getProperty("os.name").startsWith("Windows")) {
  fontRegex = ".*(calibri|cour|arial|times|comic|georgia|impact|LSANS|pala|tahoma|trebuc|verdana|symbol|webdings|wingding).*";
}
PhysicalFonts.setRegex(fontRegex);
wordMLPackage.setFontMapper(new BestMatchingMapper());
Docx4J.toPDF(wordMLPackage, outputStream);

Upvotes: 1

Georg Berky
Georg Berky

Reputation: 1

This seems to be a font loading problem. I'm on a Mac (latest Monterey) and I'm getting the same exception in the contructor call:

java.lang.AssertionError: 
Expecting code not to raise a throwable but caught
  java.lang.AssertionError
    at org.docx4j.fonts.fop.complexscripts.fonts.GlyphPositioningTable$DeviceTable.<init>(GlyphPositioningTable.java:1778)
    at org.docx4j.fonts.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader.readPosDeviceTable(OTFAdvancedTypographicTableReader.java:1729)
    at org.docx4j.fonts.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader.readPosAnchor(OTFAdvancedTypographicTableReader.java:2053)
    at org.docx4j.fonts.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader.readMarkToLigaturePosTableFormat1(OTFAdvancedTypographicTableReader.java:2347)
    at org.docx4j.fonts.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader.readMarkToLigaturePosTable(OTFAdvancedTypographicTableReader.java:2373)
    at org.docx4j.fonts.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader.readGPOSSubtable(OTFAdvancedTypographicTableReader.java:3124)
    at org.docx4j.fonts.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader.readLookupTable(OTFAdvancedTypographicTableReader.java:3193)
    at org.docx4j.fonts.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader.readLookupList(OTFAdvancedTypographicTableReader.java:3220)
    at org.docx4j.fonts.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader.readCommonLayoutTables(OTFAdvancedTypographicTableReader.java:3241)
    at org.docx4j.fonts.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader.readGPOS(OTFAdvancedTypographicTableReader.java:3501)
    at org.docx4j.fonts.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader.readAll(OTFAdvancedTypographicTableReader.java:88)
    at org.docx4j.fonts.fop.fonts.truetype.OpenFont.handleCharacterSpacing(OpenFont.java:895)
    at org.docx4j.fonts.fop.fonts.truetype.OpenFont.readFont(OpenFont.java:867)
    at org.docx4j.fonts.fop.fonts.truetype.OFFontLoader.read(OFFontLoader.java:121)
    at org.docx4j.fonts.fop.fonts.truetype.OFFontLoader.read(OFFontLoader.java:105)
    at org.docx4j.fonts.fop.fonts.FontLoader.getFont(FontLoader.java:130)
    at org.docx4j.fonts.fop.fonts.FontLoader.loadFont(FontLoader.java:114)
    at org.docx4j.fonts.fop.fonts.autodetect.FontInfoFinder.find(FontInfoFinder.java:262)
    at org.docx4j.fonts.PhysicalFonts.getPhysicalFont(PhysicalFonts.java:307)
    at org.docx4j.fonts.PhysicalFonts.addPhysicalFonts(PhysicalFonts.java:246)
    at org.docx4j.fonts.PhysicalFonts.addPhysicalFont(PhysicalFonts.java:236)
    at org.docx4j.fonts.PhysicalFonts.discoverPhysicalFonts(PhysicalFonts.java:183)
    at org.docx4j.fonts.IdentityPlusMapper.<clinit>(IdentityPlusMapper.java:74)
    at foo(...)

open fun foo(...) {
    ...
    val mlPackage = WordprocessingMLPackage.load(ByteArrayInputStream(input))
    mlPackage.fontMapper = IdentityPlusMapper() //<-- boom
}

Update (August 29th 2022): I fixed the issue by upgrading Docx4j to 11.4.7 . Additionally I had to add the following code before the call to Docx4J.toFO(...):

val fopFactoryBuilder: FopFactoryBuilder = FORendererApacheFOP.getFopFactoryBuilder(foSettings)
FORendererApacheFOP.getFOUserAgent(foSettings, fopFactoryBuilder.build())

Upvotes: 0

Related Questions