Docker openjdk-alpine 无法使用字体控件(fontconfig)的坑 – 记忆角落

Docker openjdk-alpine 无法使用字体控件(fontconfig)的坑

/ 0评 / 0

Docker openjdk-alpine 无法使用字体控件(fontconfig)的坑

问题背景

因为最近公司的java微服务都到容器运行~某些服务使用了hutool工具类提供Excel生成功能,今天测试在测试环境灰度测试时候,发现了空指针的错误:

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:774)
    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.FcFontManager.<init>(FcFontManager.java:35)
    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:423)
    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.getFont2D(Font.java:491)
    at java.awt.Font.access$000(Font.java:224)
    at java.awt.Font$FontAccessImpl.getFont2D(Font.java:228)
    at sun.font.FontUtilities.getFont2D(FontUtilities.java:180)
    at sun.font.StandardGlyphVector.initFontData(StandardGlyphVector.java:1126)
    at sun.font.StandardGlyphVector.init(StandardGlyphVector.java:1115)
    at sun.font.StandardGlyphVector.<init>(StandardGlyphVector.java:167)
    at java.awt.Font.createGlyphVector(Font.java:2545)

而正常的开发环境暂时还是在宿主机用oralce jdk跑服务,未出现此问题。

问题分析及解决

问题分析

因为Java服务现在都是用openjdk:8-jdk-alpine为基础镜像进行构建的,再通过看具体错误和经过一些google,可以确定两个问题:

1.openjdk不包括sum.awt的字体控件

2.alpine linux的基础镜像也未安装有fontconfigttf-dejavu字体。

解决

  1. openjdk:8-jdk-alpine更换成oraclejdk或者使用openjdk:8-jdk。但考虑到商业授权的问题,因此不更换,仍使用openjdk,但又因为alpine基础镜像已经是最小了,所以折中继续使用openjdk:8-jdk-alpine
  2. dockerfile构建文件中,安装fontconfig 和 ttf-dejavu字体
FROM openjdk:8-jdk-alpine

# 安装 fontconfig 和 ttf-dejavu字体
RUN apk add fontconfig && apk add --update ttf-dejavu && fc-cache --force

最终方案是openjdk:8-jdk-alpine基础镜像中再封装私有的镜像

原因是Jenkins流水线上每次打包构建镜像都要 apk fontconfig和ttf-dejavu,构建过程非常慢!!!!

最终镜像Dockerfile

FROM openjdk:8-jdk-alpine

ENV TIME_ZONE="Asia/Shanghai" 
RUN apk add fontconfig && apk add --update ttf-dejavu && fc-cache --force
RUN ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && \
echo $TIME_ZONE > /etc/timezone && \
addgroup -g 2888 xinsec && \
adduser -u 2888 -G xinsec -h /home/xinsec -D xinsec

发表评论

您的电子邮箱地址不会被公开。