Docker: java.lang.NoClassDefFoundError: sun.awt.X11FontManager
Posted 琦彦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker: java.lang.NoClassDefFoundError: sun.awt.X11FontManager相关的知识,希望对你有一定的参考价值。
目录
问题现象
Dockerfile基础镜像从 java:8
更换为 adoptopenjdk/openjdk8-openj9:alpine-slim 后
登录页面的验证码无法加载,并报错
2021-08-24 01:30:25.763 ERROR 1 --- [or-http-epoll-4] reactor.netty.http.server.HttpServer : [id: 0xf73ab911, L:/172.23.0.4:8081 - R:/10.0.159.222:52873]
java.lang.NoClassDefFoundError: sun.awt.X11FontManager (initialization failure)
at java.lang.J9VMInternals.initializationAlreadyFailed(Unknown Source) ~[na:1.8.0_302]
at java.lang.Class.forNameImpl(Native Method) ~[na:1.8.0_302]
at java.lang.Class.forName(Unknown Source) ~[na:1.8.0_302]
at sun.font.FontManagerFactory$1.run(Unknown Source) ~[na:1.8.0_302]
at java.security.AccessController.doPrivileged(Unknown Source) ~[na:1.8.0_302]
at sun.font.FontManagerFactory.getInstance(Unknown Source) ~[na:1.8.0_302]
at java.awt.Font.getFont2D(Unknown Source) ~[na:1.8.0_302]
at java.awt.Font.access$000(Unknown Source) ~[na:1.8.0_302]
at java.awt.Font$FontAccessImpl.getFont2D(Unknown Source) ~[na:1.8.0_302]
at sun.font.FontUtilities.getFont2D(Unknown Source) ~[na:1.8.0_302]
at com.google.code.kaptcha.text.impl.DefaultWordRenderer.renderWord(DefaultWordRenderer.java:66) ~[kaptcha-2.3.2.jar!/:2.3.2]
at com.google.code.kaptcha.impl.DefaultKaptcha.createImage(DefaultKaptcha.java:43) ~[kaptcha-2.3.2.jar!/:2.3.2]
at com.jiean.gateway.service.impl.ValidateCodeServiceImpl.createCapcha(ValidateCodeServiceImpl.java:61) ~[classes!/:na]
at com.jiean.gateway.handler.ValidateCodeHandler.handle(ValidateCodeHandler.java:33) ~[classes!/:na]
at
at java.lang.Thread.run(Unknown Source) [na:1.8.0_302]
Caused by: java.lang.UnsatisfiedLinkError: fontmanager (libfreetype.so.6: cannot open shared object file: No such file or directory)
问题原因:
这种一般是出现在 docker部署,且使用了精简版的基础镜像,有多精简呢?精简到把字体都阉割掉了,好狠…
如果你的项目有字体相关操作,比如导出 excel,验证码,就会报上述异常。
对于一个Java服务器来说经常要处理一些图形元素,例如地图的创建或者图形和图表等。这些API基本上总是需要运行一个X-server以便能使用AWT(Abstract Window Toolkit,抽象窗口工具集)。
问题解决:
容器环境下
换个东西全一点的镜像;
FROM java:8
在构建镜像时安装字体,dockerfile增加命令:
RUN yum install dejavu-sans-fonts fontconfig -y
如果 container已经启动,又不想换,那就直接进到 container,安装字体:
yum install dejavu-sans-fonts fontconfig -y
非容器环境下
从代码层面手工设置了 System.setProperty("java.awt.headless","true"); 解决问题。
@SpringBootApplication
public class EbootApplication {
public static void main(String[] args) {
System.setProperty("java.awt.headless", "true");
SpringApplication.run(EbootApplication.class, args);
}
}
什么是Headless mode?Headless模式是系统的一种配置模式。在该模式下,系统缺少了显示设备、键盘或鼠标。
一般是在程序开始激活headless模式,告诉程序,现在你要工作在Headless mode下,就不要指望硬件帮忙了,自力更生并依靠系统的计算能力模拟出这些特性来。
以上是关于Docker: java.lang.NoClassDefFoundError: sun.awt.X11FontManager的主要内容,如果未能解决你的问题,请参考以下文章
Docker学习__docker命令[docker version 和 docker info]