Docker Unbuntu18 OpenJDK9 NPE FontConfiguration.getVersion (awt 字体库问题)

java.lang.NullPointerException: null
	at java.desktop/sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1288)
        .....

在使用Docker容器运行springboot程序时,验证码请求需要使用到字体库,本机运行没有问题,放到服务器上在容器中运行出现NPE问题,由于openjdk9中默认不带有awt字体库,所以获取字体出现NPE.

docker容器环环境openjdk9, Unbuntu18.04 , 解决方式就是安装fontconfig字体库,Dockerfile如下:

FROM adoptopenjdk/openjdk9
LABEL manitainer="tm<t0m999@xxx.com>"
LABEL description="This is demo service."

ARG APP_HOME=/app/
ARG APP_NAME=demo-srv
ARG APP_BOOT=${APP_NAME}-boot

VOLUME /tmp

ADD ${APP_BOOT}.tar $APP_HOME

# for openjdk awt font solution  安装fontconfig库,处理NPE问题
RUN apt update && apt install fontconfig -y && apt install --fix-broken -y

RUN mkdir -p ${APP_HOME}log/ \
        && mv ${APP_HOME}${APP_BOOT}/bin/${APP_NAME} ${APP_HOME}${APP_BOOT}/bin/start \
        && mv ${APP_HOME}${APP_BOOT}/* ${APP_HOME} && rm -rf ${APP_HOME}${APP_BOOT}


ENV BOOT_ARG -Djava.security.e
### FontConfiguration.getVersion NullPointerException 解决方案 在 Docker 环境中运行 OpenJDK 时,如果遇到 `java.lang.NullPointerException` 异常,通常是因为使用了精简版的 JDK(如 jdk-slim)。这些版本为了减少体积,移除了部分字体资源和相关依赖。当应用程序需要访问这些字体资源时,就会抛出空指针异常[^2]。 #### 问题分析 1. **字体资源缺失**:精简版 JDK 中缺少必要的字体文件,导致 `FontConfiguration.getVersion` 方法无法正常工作。 2. **环境差异**:即使两台服务器使用相同的镜像和配置,也可能因为基础操作系统或字体安装的不同而导致问题发生[^3]。 #### 解决方法 ##### 方法一:使用完整版 JDK 将 Docker 镜像中的 jdk-slim 替换为完整版 JDK。完整版 JDK 包含所有必要的字体文件和依赖项,可以避免此类问题。例如,在 Dockerfile 中指定完整版 JDK: ```dockerfile FROM openjdk:8-jdk ``` ##### 方法二:添加字体文件 如果必须使用精简版 JDK,可以通过手动添加字体文件来解决该问题。以下是具体步骤: 1. 下载包含字体资源的完整版 JDK。 2. 将完整版 JDK 的字体目录复制到容器中。例如,将 `/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/fonts` 复制到容器内的相同路径。 3.Dockerfile 中添加以下内容: ```dockerfile # 添加字体文件 COPY --from=openjdk:8-jdk /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/fonts/ /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/fonts/ ``` ##### 方法三:安装系统字体 某些情况下,应用程序会尝试从操作系统加载字体。可以在 Docker 镜像中安装额外的字体包。例如,对于基于 Debian 的镜像,可以安装 `fonts-dejavu`: ```dockerfile RUN apt-get update && apt-get install -y fonts-dejavu ``` ##### 方法四:禁用 AWT 字体检查 如果应用程序对字体的需求不高,可以尝试通过设置 JVM 参数禁用 AWT 字体检查。例如,在启动命令中添加以下参数: ```bash -Dsun.java2d.font.DisableFontFallback=true ``` 此方法可能会导致部分功能不可用,需根据实际需求权衡利弊。 ##### 方法五:升级 JDK 版本 部分旧版本 JDK 存在已知的字体相关问题。如果可能,建议升级到更高版本的 JDK(如 JDK 11 或 JDK 17),这些问题在新版本中可能已被修复[^4]。 ### 示例代码 以下是一个完整的 Dockerfile 示例,结合了上述解决方案: ```dockerfile # 使用官方 OpenJDK 镜像 FROM openjdk:8-jdk-alpine # 安装必要字体 RUN apk add --no-cache msttcorefonts-installer fontconfig && \ update-ms-fonts && \ fc-cache -f # 设置 JVM 参数 ENV JAVA_OPTS="-Dsun.java2d.font.DisableFontFallback=true" # 复制应用文件 COPY . /app WORKDIR /app # 启动应用 CMD ["java", "${JAVA_OPTS}", "-jar", "app.jar"] ``` #### 注意事项 - 如果问题仍然存在,建议检查服务器之间的环境差异,确保字体文件和依赖项一致。 - 在生产环境中测试解决方案时,务必进行全面的功能验证,以确保不会引入其他问题
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值