8u111-jdk-alpine在java开发中的NullPointerException错误解决方案
问题描述
在部署一个验证码服务的容器服务时遇到了一个空指针错误,错误代码为:
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) at nl.captcha.text.renderer.DefaultWordRenderer.render(Unknown Source) at nl.captcha.Captcha$Builder.addText(Unknown Source) at com.liferay.portal.captcha.simplecaptcha.SimpleCaptchaImpl.getSimpleCaptcha(SimpleCaptchaImpl.java:243) at com.liferay.portal.captcha.simplecaptcha.SimpleCaptchaImpl.serveImage(SimpleCaptchaImpl.java:159) at com.liferay.portal.captcha.CaptchaImpl.serveImage(CaptchaImpl.java:100) at com.liferay.portal.kernel.captcha.CaptchaUtil.serveImage(CaptchaUtil.java:78) at com.liferay.portal.captcha.CaptchaPortletAction.serveResource(CaptchaPortletAction.java:42)
在仔细搜索了一番后,发现github上的一个描述比较相似:
https://github.com/docker-library/openjdk/issues/73
解决方法
经过了解,知道是因为alpine中缺少FontConfiguration,那么就考虑安装ttf-dejavu这个软件。
在http://blog.csdn.net/freewebsys/article/details/53816615找到了解决办法。
在服务器适当位置位置创建一个Dockerfile,内容为:
FROM java:8-jre-alpine # Install cURL RUN echo -e "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main\n\ https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/community" > /etc/apk/repositories RUN apk --update add curl bash ttf-dejavu && \ rm -rf /var/cache/apk/*
docker build -t docker.io/java-font:8-jre-alpine . REPOSITORY IMAGE ID CREATED SIZE docker.io/java-font 8-jre-alpine dc7703ec6f07 31 hours ago 131.5 MB
fontconfig
之前开发的应用都是基于OracleJDK 1.8来做的,图片验证码显示正常,但是更换成OpenJDK1.8后,验证码无法显示,后台代码抛出异常,异常内容如下,java.lang.NullPointerException at sun.awt.FontConfiguration.getVersion(FontConfiguration.java 1264)
可以看到,猜测是因为验证码的API用到了AWT的东西,但是Openjdk少了些啥。经过不断的折腾,发现后续的OpenJDK同样存在这些问题,在网上找了很多办法也没有用,后来发现需要在操作系统层面安装FontConfig组件。本人环境使用的是Centos 7.3 于是直接安装FontConfig即可,如果你使用的docker容器环境,需要在镜像中进行安装,并执行fc-ache --force(必须执行)
yum install fontconfig fc-cache --force
links:https://www.jianshu.com/p/e39ee0cad05b
https://blog.csdn.net/crystonesc/article/details/86305466