Docker使用OpenJDK镜像导致验证码错误:java.lang.NullPointerException at sun.awt.FontConfiguration.getVersion

简介: Docker使用OpenJDK镜像导致验证码错误:java.lang.NullPointerException at sun.awt.FontConfiguration.getVersion

     

问题

使用Docker部署Jar包,登录的时候发现生成验证码失败,但是本地却没有问题。查看日志,报错:

java.lang.NullPointerException: null
  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.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

image.png

/usr/share 下多出 fontconfigfonts 目录。

2、安装字体 ttf-dejavu

image.png

  • 刷新字体:fc-cache --force , 刷新完成之后可以使用 fc-list 查看安装的字体

image.png

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 字体

image.png

4、重启容器

最后重启容器:

docker restart [容器id]


OK,问题解决。👏👏👏


目录
相关文章
|
5月前
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
715 6
|
6月前
|
缓存 安全 Linux
优化Docker镜像大小的多阶段构建实践
优化Docker镜像大小的多阶段构建实践
463 99
|
6月前
|
Java Docker 容器
使用Docker多阶段构建优化镜像大小
使用Docker多阶段构建优化镜像大小
311 8
|
6月前
|
缓存 Docker 容器
优化Docker镜像大小的五个实用技巧
优化Docker镜像大小的五个实用技巧
639 98
|
6月前
|
JavaScript Docker 容器
使用Docker多阶段构建优化镜像大小
使用Docker多阶段构建优化镜像大小
489 100
|
6月前
|
安全 Go Docker
使用Docker多阶段构建优化镜像大小
使用Docker多阶段构建优化镜像大小
|
7月前
|
缓存 Ubuntu Docker
Ubuntu环境下删除Docker镜像与容器、配置静态IP地址教程。
如果遇见问题或者想回滚改动, 可以重启系统.
502 16
|
7月前
|
运维 关系型数据库 数据库
应用官方 Docker 镜像已成熟,团队为何转向 Websoft9 而不再依赖 Bitnami
随着云原生发展,部署工具从 Bitnami 转向 Websoft9。后者基于官方镜像,提供多应用编排与统一运维,提升部署效率与维护能力,适合多系统协同场景。
应用官方 Docker 镜像已成熟,团队为何转向 Websoft9 而不再依赖 Bitnami
|
7月前
|
Ubuntu 网络安全 PHP
如何使用vscode的Docker插件管理ubuntu 拉取服务器的镜像以及创建容器
本测试镜像旨在记录使用vscode的Docker插件拉取病创建Dockerfile,以及拉取镜像。
|
8月前
|
存储 缓存 Serverless
【Azure Container App】如何在Consumption类型的容器应用环境中缓存Docker镜像
在 Azure 容器应用的 Consumption 模式下,容器每次启动均需重新拉取镜像,导致冷启动延迟。本文分析该机制,并提出优化方案:使用 ACR 区域复制加速镜像拉取、优化镜像体积、设置最小副本数减少冷启动频率,或切换至 Dedicated 模式实现镜像缓存,以提升容器启动效率和应用响应速度。
336 0