JRE8のS3入力ストリームからフォントを読み込めません。システムにJRE7、JDK 7、さらにはJDK8がインストールされていても問題はありません。
val fontInputStream = s3Client.getObject(bucketName, objectKey).getObjectContent
val customFont = Font.createFont(Font.TRUETYPE_FONT, fontInputStream).deriveFont(Font.TRUETYPE_FONT, 20F)
私が得たエラーは
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)
入力ストリームを一時ファイルにロードしようとしましたが、役に立ちません。また、ローカルファイルから直接フォントを読み込もうとしましたが、フォントメタデータの取得で別のエラーが発生しました。これがエラーログです。
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)
したがって、これはinputstreamの問題ではなく、JRE8でのフォント自体のロードの問題です。
これは、JRE8フォントのバグのようです。
画像に文字列を描画するために使用するフォントを読み込んでいます。私のコードは、Java:7-jre(ok)、Java:7-jdk(ok)、Java:8-jre(fail)、Java:8-jdk(ok)のイメージを使用してDockerコンテナーで実行されます。
これはopenjdk-8-jre-headless
インストールの問題であることが判明しました。これは、Java 8JREのDockerイメージへのインストールです。openjdk-8-jre
(ヘッドレスなし)をインストールするだけで、問題は解決します。
エラーログを見ると、フォントのロードにはawt X11が必要ですが、これはJREのheadless
バージョンにはありません。
Openjdk:8-jre-Alpineでも同じエラーが発生しました。 openjdk:8-jreへの切り替えも役立ちました。 (apt-get行は必要ないようです)
--- FROM openjdk:8-jre-Alpine
+++ FROM openjdk:8-jre
+++ RUN apt-get install -y libfontconfig
また、Tomcat:8.0.38-jre8-Alpineを使用しているときにもこのエラーが発生しました。その画像にはfontconfigがありません。別のイメージに切り替える代わりに、ttf-dejavu
パッケージをインストールすることもできます。
apk add --update ttf-dejavu
Alpineとopenjdkの場合:RUN apk --update add fontconfig ttf-dejavu
を使用してください。
CentOSでは、ヘッドレスJREにfontconfig
依存関係がありません。
yum install fontconfig
また、少なくとも1つのフォント(dejavu
、liberation
など)をインストールする必要がある場合もあります。
私にとって、この解決された問題:
apt-get install -y libfontconfig1