背景        

        使用 kaptcha 等工具实现的验证码是使用了awt包下的方法生成图片,而awt包是依赖了操作系统的一些图形界面功能。在Windows环境下调用通常是正常的,因为Windows系统中的类库基本是齐全的,但是Linux环境下运行可能会出现调用报错,原因是该Linux环境中缺少一些依赖类库。特别对于一些精简版系统,例如docker基础镜像 alpine 版本,通常不会额外附带这些类库。导致初始化FontManagerFactory工厂初始化失败,所以解决方法是安装glibc等必要类库。

pom依赖示例

<!--kaptcha 验证码 -->
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

集成后报错信息

java.lang.UnsatisfiedLinkError: /root/home/jdk1.8.0_341/jre/lib/amd64/libfontmanager.so:         
    libgcc_s.so.1: cannot open shared object file: No such file or directory
    java.lang.ClassLoader$NativeLibrary.load(Native Method)
    java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1937)
    java.lang.ClassLoader.loadLibrary(ClassLoader.java:1841)
    java.lang.Runtime.loadLibrary0(Runtime.java:871)
    java.lang.System.loadLibrary(System.java:1122)
    sun.font.FontManagerNativeLibrary$1.run(FontManagerNativeLibrary.java:61)
    java.security.AccessController.doPrivileged(Native Method)
    sun.font.FontManagerNativeLibrary.<clinit>(FontManagerNativeLibrary.java:32)
    sun.font.SunFontManager$1.run(SunFontManager.java:346)
    java.security.AccessController.doPrivileged(Native Method)
    sun.font.SunFontManager.<clinit>(SunFontManager.java:342)
    java.lang.Class.forName0(Native Method)
    java.lang.Class.forName(Class.java:348)
    sun.font.FontManagerFactory$1.run(FontManagerFactory.java:82)
    java.security.AccessController.doPrivileged(Native Method)
    sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
    java.awt.Font.getFont2D(Font.java:491)
    java.awt.Font.access$000(Font.java:224)
    java.awt.Font$FontAccessImpl.getFont2D(Font.java:228)
    sun.font.FontUtilities.getFont2D(FontUtilities.java:199)
    sun.font.StandardGlyphVector.initFontData(StandardGlyphVector.java:1126)
    sun.font.StandardGlyphVector.init(StandardGlyphVector.java:1115)
    sun.font.StandardGlyphVector.<init>(StandardGlyphVector.java:167)
    java.awt.Font.createGlyphVector(Font.java:2549)
    com.google.code.kaptcha.text.impl.DefaultWordRenderer.renderWord(DefaultWordRenderer.java:66)
    com.google.code.kaptcha.impl.DefaultKaptcha.createImage(DefaultKaptcha.java:43)
    com.google.code.kaptcha.servlet.KaptchaServlet.doGet(KaptchaServlet.java:95)

java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager
	java.lang.Class.forName0(Native Method)
	java.lang.Class.forName(Class.java:348)
	sun.font.FontManagerFactory$1.run(FontManagerFactory.java:82)
	java.security.AccessController.doPrivileged(Native Method)
	sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
	java.awt.Font.getFont2D(Font.java:491)
	java.awt.Font.access$000(Font.java:224)
	java.awt.Font$FontAccessImpl.getFont2D(Font.java:228)
	sun.font.FontUtilities.getFont2D(FontUtilities.java:199)
	sun.font.StandardGlyphVector.initFontData(StandardGlyphVector.java:1126)
	sun.font.StandardGlyphVector.init(StandardGlyphVector.java:1115)
	sun.font.StandardGlyphVector.<init>(StandardGlyphVector.java:167)
	java.awt.Font.createGlyphVector(Font.java:2549)
	com.google.code.kaptcha.text.impl.DefaultWordRenderer.renderWord(DefaultWordRenderer.java:66)
	com.google.code.kaptcha.impl.DefaultKaptcha.createImage(DefaultKaptcha.java:43)
	com.google.code.kaptcha.servlet.KaptchaServlet.doGet(KaptchaServlet.java:95)

解决方法

1、使用tomcat启动项目方式,可以在tomcat/bin/catalina.sh里加入下面这段代码

JAVA_OPTS="$JAVA_OPTS -Djava.awt.headless=true"

2、springboot启动可以在启动命令上加入 -Djava.awt.headless=true ,如:

java -jar -Djava.awt.headless=true test.jar

3、如果以上方法都不生效那便要安装相应类库,安装命令如下:

#假设bash wget功能正常,否则还需要安装bash wget,命令如下 
#apk --no-cache add libstdc++ ca-certificates bash wget 
apk --no-cache add libstdc++ ca-certificates 
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub 
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-2.30-r0.apk 
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-bin-2.30-r0.apk 
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-i18n-2.30-r0.apk 
apk add glibc-2.30-r0.apk && apk add glibc-bin-2.30-r0.apk && apk add glibc-i18n-2.30-r0.apk

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐