本文主要是介绍Docker使用OpenJDK镜像导致验证码错误:java.lang.NullPointerException at sun.awt.FontConfiguration.getVersion,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
问题
使用Docker部署Jar包,登录的时候发现生成验证码失败,但是本地却没有问题。查看日志,报错:
java.lang.NullPointerException: nullat 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.java2d.SunGraphics2D.checkFontInfo(SunGraphics2D.java:669)at sun.java2d.SunGraphics2D.getFontInfo(SunGraphics2D.java:830)at sun.java2d.pipe.GlyphListPipe.drawString(GlyphListPipe.java:50)at sun.java2d.SunGraphics2D.drawString(SunGraphics2D.java:2928)………………
分析
这个问题网上答案已经非常多了——
OpenJDK比OracleJDK简化了一些功能,所以后端绘制验证码所要用到Java的AWT组件就被简化了,结果报出空指针。
问题出现了,现在有三种解决思路:
- 1、修改代码,后端只生成验证码内容,具体绘制交给前端
- 2、更换Docker镜像为 OracleJDK
- 3、基于操作系统安装FontConfig组件
综合比较快捷的是第三种方式:
- 1、在centos7系统安装FontConfig
yum install fontconfig
- 2、修改dockerfile ,添加一行,安装字体
ttf-dejavu
RUN apk add --update font-adobe-100dpi ttf-dejavu fontconfig
- 3、重启docker容器
docker restart 容器ID或容器名
但是由于博主的服务器是内网环境,所以没有办法,只能用离线安装的方式。
解决
1、离线安装 fontconfig
-
下载 fontconfig离线包:fontconfig-2.13.0-4.3.el7.x86_64.rpm
-
上传到服务器,执行命令:
rpm -ivh fontconfig-2.13.0-4.3.el7.x86_64.rpm --nodeps --force
在 /usr/share
下多出 fontconfig
和 fonts
目录。
2、安装字体 ttf-dejavu
-
下载字体
ttf-dejavu
: https://packages.msys2.org/package/mingw-w64-x86_64-ttf-dejavu (失效自行查找) -
上传字体:将 字体文件打包上传到服务器
/usr/share/fonts
目录,解压
- 刷新字体:
fc-cache --force
, 刷新完成之后可以使用fc-list
查看安装的字体
3、容器中安装字体
- 将上传的
ttf-dejavu
字体文件夹拷贝到容器/usr/share/fonts
目录中
docker cp -a TTF/ [容器id]:/usr/share/fonts
- 进入容器 ,刷新字体
# 进入容器
docker exec -it [容器id] bash
# 刷新字体
fc-cache --force
fc-list
就可以看到安装的 ttf-dejavu 字体
4、重启容器
最后重启容器:
docker restart [容器id]
OK,问题解决。👏👏👏
参考:
【1】:OpenJDK验证码无法显示(java.lang.NullPointerException at sun.awt.FontConfiguration.getVersion
【2】:docker中OpenJDK验证码无法显示 java.lang.NullPointerException at sun.awt.FontConfiguration.getVersion
【3】:解决Alpine缺少字体的问题
【4】:docker容器安装宋体
【5】:centos7 离线安装字体fontconfig
这篇关于Docker使用OpenJDK镜像导致验证码错误:java.lang.NullPointerException at sun.awt.FontConfiguration.getVersion的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!