1.问题描述+分析
本地调试的没问题,使用linux服务器jar包部署的也没问题,使用Docker的OpenJDK8报错了,报错信息如下,百度了一下,大家都说OpenJDK比OracleJDK简化了一些功能,所以后端绘制验证码所要用到Java的AWT组件就被简化了,结果报出空指针。要么换OracleJDK,要么就手动安装中文字库。有的甚至说不要用OpenJDK,对于公司要求OpenJDK的我来说,只能另想办法了,最关键的是我是离线环境,网上很多教程行不通,安一个发现安装工具都没有,安一个没有工具,真按教程来,正事没干,安工具就安废了。我也不可能每部署一个docker都要手动安装一遍中文字库。最后,我想了个办法,在有网的环境下把OpenJDK打包成包含fontconfig和字体 ttf-dejavu的镜像。然后导出镜像,再使用这个打包好的镜像就可以完美解决这个问题了。
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)
2.在有网的服务器上新建Dockerfile文件
内容如下:
From alpine MAINTAINER hjw/openjdk8 RUN echo -e 'https://mirrors.aliyun.com/alpine/v3.6/main/\nhttps://mirrors.aliyun.com/alpine/v3.6/community/' > /etc/apk/repositories && \ apk update && \ apk add openjdk8 curl busybox tzdata && \ apk --no-cache add ttf-dejavu fontconfig &&\ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo Asia/Shanghai > /etc/timezone && \ apk del tzdata && \ rm -rf /tmp/* /var/cache/apk/*
3.打包镜像
docker build -t openjdk8:v1 .
4.导出镜像
这里注意不要用镜像ID,用镜像名称:版本号,否则导入的时候有可能不显示镜像名称和版本号,从而变成了游离镜像。
docker save -o openjdk88.tar openjdk8:v1
5.传到内网服务器上,导入OpenJDK8:v1镜像
docker load -i openjdk88.tar
6.Dockerfile
FROM openjdk8:v1 LABEL name="bob_demo" version="1.0.0" author="hjw" ADD target/*.jar /app.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar","--spring.profiles.active=test","&"]