Eclipse MAT, HeapHero are all popular java tools to analyze large size heap dumps. Recently we ran in to an interesting problem when trying to analyze a heap dump file in Eclipse MAT. Tool was crashing because of missing font 😊. We thought we will share with you what we found out.
ArrayIndexOutOfBoundsException in CompositeStrike.getStrikeForSlot()
Here is our environment:
Eclipse MAT 1.9
Java 8
Linux 3.10.0-862.34.2.el7.x86_64
When we uploaded our heap dump file to Eclipse MAT, it failed with following error:
<<start: code>> java.lang.ArrayIndexOutOfBoundsException: 0 at sun.font.CompositeStrike.getStrikeForSlot(CompositeStrike.java:75) at sun.font.CompositeStrike.getFontMetrics(CompositeStrike.java:93) at sun.font.FontDesignMetrics.initMatrixAndMetrics(FontDesignMetrics.java:359) at sun.font.FontDesignMetrics.<init>(FontDesignMetrics.java:350) at sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:302) at sun.java2d.SunGraphics2D.getFontMetrics(SunGraphics2D.java:863) at org.eclipse.birt.chart.device.swing.SwingTextMetrics.reuse(SwingTextMetrics.java:123) at org.eclipse.birt.chart.device.TextAdapter.reuse(TextAdapter.java:36) at org.eclipse.birt.chart.device.swing.SwingTextMetrics.<init>(SwingTextMetrics.java:86) at org.eclipse.birt.chart.device.swing.SwingDisplayServer.getTextMetrics(SwingDisplayServer.java:194) at org.eclipse.birt.chart.device.DisplayAdapter.getTextMetrics(DisplayAdapter.java:138) at org.eclipse.birt.chart.computation.BIRTChartComputation.getTextMetrics(BIRTChartComputation.java:36) at org.eclipse.birt.chart.computation.LegendBuilder$LegendData.<init>(LegendBuilder.java:108) at org.eclipse.birt.chart.computation.LegendBuilder.compute(LegendBuilder.java:493) at org.eclipse.birt.chart.model.layout.impl.LegendImpl.getPreferredSize(LegendImpl.java:2059) at org.eclipse.birt.chart.internal.layout.LayoutManager$ChartLayout.<init>(LayoutManager.java:126) at org.eclipse.birt.chart.internal.layout.LayoutManager.doLayout_tmp(LayoutManager.java:1145) : : : <<start: code>>
Quick search in Google god revealed this interesting StackOverflow thread. Here is synopsis of this thread. Java searches monospaced, SansSerif and serif fonts using linux's fontconfig feature. Linux fontconfig is designed to locate fonts within the system and select them according to requirements specified by applications. If any of the above font are missing, then it would result in above exception.
If you also encounter this type of problem, there are 3 potential solutions to address this problem:
1. Install missing font
2. Upgrade JDK
3. Edit OS Font config
Lets discuss the solutions in detail.
1. Install missing font
You can try installing the missing font by issuing below command:
<<code:start>> yum install dejavu-serif-fonts <<code:end>>
2. Upgrade JDK
This is a known JDK bug, tracked in OpenJDK, Oracle and IBM JDK bug databases:
https://bugs.openjdk.java.net/browse/JDK-8188030
https://bugs.java.com/bugdatabase/vi...id=JDK-8188030
IBM IJ16655: AWT JAVA APPS FAIL TO START WHEN STIX-FONTS IS USED AS DEFAULT FOR MISSING SANSSERIF FONT IN RHEL7.4
This bug has been fixed since following releases:
Open JDK 8u192
Oracle JDK 8u192
IBM JDK 8 SR5 FP37 (8.0.5.37)
You can upgrade to latest JDK version to resolve the problem.
3. Edit OS Font config
Create a file name /etc/fonts/local.conf. In this file force back Utopia as the default font, used by java.
<?xml version='1.0'?> <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> <fontconfig> <alias> <family>serif</family> <prefer><family>Utopia</family></prefer> </alias> <alias> <family>sans-serif</family> <prefer><family>Utopia</family></prefer> </alias> <alias> <family>monospace</family> <prefer><family>Utopia</family></prefer> </alias> <alias> <family>dialog</family> <prefer><family>Utopia</family></prefer> </alias> <alias> <family>dialoginput</family> <prefer><family>Utopia</family></prefer> </alias> </fontconfig>