javafontsawtjava-8

Cannot load font in JRE 8


I cannot load a font from an S3 Inputstream in JRE 8. I do not have issue if a system is installed with JRE 7, JDK 7, or even JDK 8.

val fontInputStream = s3Client.getObject(bucketName, objectKey).getObjectContent

val customFont = Font.createFont(Font.TRUETYPE_FONT, fontInputStream).deriveFont(Font.TRUETYPE_FONT, 20F)

The error that I got is

Exception in thread "main" java.io.IOException: Problem reading font data.
        at java.awt.Font.createFont0(Font.java:1000)
        at java.awt.Font.createFont(Font.java:877)
        at Main$.delayedEndpoint$Main$1(Main.scala:31)
        at Main$delayedInit$body.apply(Main.scala:11)
        at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
        at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
        at scala.App$$anonfun$main$1.apply(App.scala:76)
        at scala.App$$anonfun$main$1.apply(App.scala:76)
        at scala.collection.immutable.List.foreach(List.scala:381)
        at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
        at scala.App$class.main(App.scala:76)
        at Main$.main(Main.scala:11)
        at Main.main(Main.scala)

I tried to load the inputstream to a temp file, but it does not help. I also tried to load a font directly from a local file, but I got a different error with getting font metadata. Here is the error log.

Exception in thread "main" java.lang.NullPointerException
        at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
        at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219)
        at sun.awt.FontConfiguration.init(FontConfiguration.java:107)
        at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:776)
        at sun.font.SunFontManager$2.run(SunFontManager.java:431)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.font.SunFontManager.<init>(SunFontManager.java:376)
        at sun.awt.X11FontManager.<init>(X11FontManager.java:57)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
        at java.lang.Class.newInstance(Class.java:442)
        at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:83)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
        at java.awt.Font.<init>(Font.java:614)
        at java.awt.Font.createFont(Font.java:1056)
        at Main$.delayedEndpoint$Main$1(Main.scala:32)
        at Main$delayedInit$body.apply(Main.scala:11)
        at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
        at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
        at scala.App$$anonfun$main$1.apply(App.scala:76)
        at scala.App$$anonfun$main$1.apply(App.scala:76)
        at scala.collection.immutable.List.foreach(List.scala:381)
        at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
        at scala.App$class.main(App.scala:76)
        at Main$.main(Main.scala:11)
        at Main.main(Main.scala)

So, this is not a problem with inputstream, but rather with the loading of the font itself in JRE 8.

This seems like a bug in JRE 8 Font.

I am loading a font to use to draw a string in a picture. My code is run in a Docker container using images java:7-jre (ok), java:7-jdk (ok), java:8-jre (fail), java:8-jdk (ok).


Solution

  • It turns out that this is a problem with the openjdk-8-jre-headless installation. This is the installation in the Docker image for java 8 JRE. I simply install openjdk-8-jre (without headless) and the problem goes away.

    If you look at the error log, the loading of the font require awt X11, which is missing from headless version of JRE.