#Linux系统使用Kaptcha出现空指针异常&&Linux安装字体

今天出现了一个很奇怪的现象,我自己本机的程序运行正常,线上服务器运行也正常,但测试服务器却一直报错,报空指针,起初我以为代码出错的位置在获取IP没获取到导致的问题,后面才发现并不是,而是在生成验证码图片的时候发生的错误。

于是就去网上大量的搜集资料。发现有很多类似的问题,但并不适用于我,这也是我为什么要单独写一篇的原因之一。 我们用的系统是基于centos的,几番搜索下来,终于功夫不负有心人,问题得到了解决。

空指针异常

2024-11-06 18:18:27.541 ERROR 926971 --- [http-nio-17080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
        at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264) ~[na:1.8.0_402]
        at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219) ~[na:1.8.0_402]
        at sun.awt.FontConfiguration.init(FontConfiguration.java:107) ~[na:1.8.0_402]
        at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:774) ~[na:1.8.0_402]
        at sun.font.SunFontManager$2.run(SunFontManager.java:441) ~[na:1.8.0_402]
        at java.security.AccessController.doPrivileged(AccessController.java:690) ~[na:1.8.0_402]
        at sun.font.SunFontManager.<init>(SunFontManager.java:386) ~[na:1.8.0_402]
        at sun.awt.FcFontManager.<init>(FcFontManager.java:35) ~[na:1.8.0_402]
        at sun.awt.X11FontManager.<init>(X11FontManager.java:57) ~[na:1.8.0_402]
        at java.lang.J9VMInternals.newInstanceImpl(Native Method) ~[na:1.8.0_402]
        at java.lang.Class.newInstance(Class.java:2108) ~[na:1.8.0_402]
        at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:83) ~[na:1.8.0_402]
        at java.security.AccessController.doPrivileged(AccessController.java:690) ~[na:1.8.0_402]
        at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74) ~[na:1.8.0_402]
        at java.awt.Font.getFont2D(Font.java:491) ~[na:1.8.0_402]
        at java.awt.Font.access$000(Font.java:224) ~[na:1.8.0_402]
        at java.awt.Font$FontAccessImpl.getFont2D(Font.java:228) ~[na:1.8.0_402]
        at sun.font.FontUtilities.getFont2D(FontUtilities.java:200) ~[na:1.8.0_402]
        at sun.font.StandardGlyphVector.initFontData(StandardGlyphVector.java:1126) ~[na:1.8.0_402]
        at sun.font.StandardGlyphVector.init(StandardGlyphVector.java:1115) ~[na:1.8.0_402]
        at sun.font.StandardGlyphVector.<init>(StandardGlyphVector.java:167) ~[na:1.8.0_402]
        at java.awt.Font.createGlyphVector(Font.java:2549) ~[na:1.8.0_402]
        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.yeegee.mall.controller.KaptchaController.genImageCode(KaptchaController.java:54) ~[classes!/:1.3.1-RELEASE]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_402]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_402]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_402]
        at java.lang.reflect.Method.invoke(Method.java:503) ~[na:1.8.0_402]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.4.RELEASE.jar!/:5.2.4.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.4.RELEASE.jar!/:5.2.4.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.4.RELEASE.jar!/:5.2.4.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.4.RELEASE.jar!/:5.2.4.RELEASE]

从上面的代码可以看到,问题出现在createImage 这个方法上。 查找问题原因,网上大家都说是由于字体的问题。

大多数博文都说要安装字体,但有很多都是ubatu的系统,不适合centos系统。

于是继续找方法,看怎样才能快速的把字体安装好。

CentOS安装字体

centos的安装字体的方法非常简单,操作如下:

yum install -y fontconfig mkfontscale

我们可以用fc-list 可以查看已经安装好的字体

[root@hcss-ecs-dd6b bin]# fc-list
/usr/share/fonts/dejavu/DejaVuSansCondensed-Oblique.ttf: DejaVu Sans,DejaVu Sans Condensed:style=Condensed Oblique,Oblique
/usr/share/fonts/dejavu/DejaVuSansCondensed-Bold.ttf: DejaVu Sans,DejaVu Sans Condensed:style=Condensed Bold,Bold
/usr/share/fonts/dejavu/DejaVuSans.ttf: DejaVu Sans:style=Book
/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf: DejaVu Sans:style=Bold
/usr/share/fonts/dejavu/DejaVuSansCondensed.ttf: DejaVu Sans,DejaVu Sans Condensed:style=Condensed,Book
/usr/share/fonts/dejavu/DejaVuSans-ExtraLight.ttf: DejaVu Sans,DejaVu Sans Light:style=ExtraLight
/usr/share/fonts/dejavu/DejaVuSansCondensed-BoldOblique.ttf: DejaVu Sans,DejaVu Sans Condensed:style=Condensed Bold Oblique,Bold Oblique
/usr/share/fonts/dejavu/DejaVuSans-Oblique.ttf: DejaVu Sans:style=Oblique
/usr/share/fonts/dejavu/DejaVuSans-BoldOblique.ttf: DejaVu Sans:style=Bold Oblique

字体安装完成后,还需要进行一些操作

cd /usr/share/fonts

mkfontscale

mdfontdir

fc-cache

最后一定要记得重启java程序,才能在项目中看到效果。

结束语

有些时候看似相同的东西,并不完全相同,比如同样是centos,可能有的缺少了一些字体库的支持,要手动安装。 再比如Oracle的JDK和openjdk,同样是支持java程序编译运行,但其中部分细节还是不一样,OpenJDK不包含一些特定的功能组件,如Deployment(部署)功能,包括Browser Plugin、Java Web Start以及Java控制面板等。

总结一下这种问题

  1. 系统环境存在差异导致的报错(例如获取MAC地址,在LINUX上是比较复杂的)
  2. 人为因素(上次出现过一次,我本机运行很好,但在服务器上存在问题,而且还莫名奇妙,最终是由于在MAVEN打包的时候,我只单独打了启动类所在的JAR包,正确的做法是需要在ROOT项目上,进行整个项目的全面打包)

如果还有其他交流的事项,也可以添加微信(yeegee2024)取得联系。

欢迎大家多多关注和支持! 我们一直会保持不定期更新,绝对不会放弃,让我们都遇到更好的自己!