问题描述
最近碰见一个问题项目用docker部署在服务器上时导出Excel时报NullPointerException,刚遇见时感觉莫名其妙,因为报空指针的地方都不是自己的写代码,但是项目在本地导出时又是正常的;后面经过查找问题分析确认是字体导致的
报错示例:
java.lang.NullPointerException: null
2021/8/31 下午3:03:10 at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
2021/8/31 下午3:03:10 at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219)
2021/8/31 下午3:03:10 at sun.awt.FontConfiguration.init(FontConfiguration.java:107)
2021/8/31 下午3:03:10 at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:774)
2021/8/31 下午3:03:10 at sun.font.SunFontManager$2.run(SunFontManager.java:431)
2021/8/31 下午3:03:10 at java.security.AccessController.doPrivileged(Native Method)
2021/8/31 下午3:03:10 at sun.font.SunFontManager.<init>(SunFontManager.java:376)
2021/8/31 下午3:03:10 at sun.awt.FcFontManager.<init>(FcFontManager.java:35)
2021/8/31 下午3:03:10 at sun.awt.X11FontManager.<init>(X11FontManager.java:57)
2021/8/31 下午3:03:10 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
2021/8/31 下午3:03:10 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
2021/8/31 下午3:03:10 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
2021/8/31 下午3:03:10 at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
2021/8/31 下午3:03:10 at java.lang.Class.newInstance(Class.java:442)
2021/8/31 下午3:03:10 at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:83)
2021/8/31 下午3:03:10 at java.security.AccessController.doPrivileged(Native Method)
2021/8/31 下午3:03:10 at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
2021/8/31 下午3:03:10 at java.awt.Font.getFont2D(Font.java:491)
问题解决
在Dockerfile中增加字体包
RUN apk add --update font-adobe-100dpi ttf-dejavu fontconfig
改前
FROM adoptopenjdk/openjdk8-openj9:alpine-slim
MAINTAINER 1007026004@qq.com
RUN mkdir -p /blade
WORKDIR /blade
EXPOSE 8800
ADD ./target/blade-api.jar ./app.jar
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
CMD ["--spring.profiles.active=test"]
改后
FROM adoptopenjdk/openjdk8-openj9:alpine-slim
MAINTAINER 1007026004@qq.com
RUN mkdir -p /blade
WORKDIR /blade
EXPOSE 8800
ADD ./target/blade-api.jar ./app.jar
RUN apk add --update font-adobe-100dpi ttf-dejavu fontconfig
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
CMD ["--spring.profiles.active=test"]
问题总结
导出Excel时需要的特殊字体在系统里是不存在的,因为本地用的sun的JDK是可以调用的,所有没有报错可以导出Excel;而docker部署时openJDK的alpine-slim不行,因此要么添加字体库,要么更换JDK;本文采用的第一种解决方案。第二种方案据说更换JDK为anapsix/alpine-java:8_jdk_unlimited 也能解决,但是该方案没有测试需要自己验证了