Unable to load verification code libfreetype.so.6: cannot open shared object file: No such file or directory

Recently, the containerized deployment of the learning project module was started , and the problem of the verification code being unable to be loaded in the gateway module (gate-way) was encountered. The process was a bit complicated, so I recorded it so that I can quickly solve the same problem next time.

To install and configure docker and docker-compose in CentOS7, you can refer to my article about installing and configuring docker and docker-compose based on CentOS7.

1. Error messages and solutions

1.1 Error messages

2023-08-23 00:52:16 [reactor-http-epoll-1] ERROR reactor.netty.http.server.HttpServer
2023-08-22T16:52:16.162476048Z  - [a88e488c-1, L:/192.168.1.16:8080 - R:/192.168.1.12:4910] 
2023-08-22T16:52:16.162478312Z java.lang.NoClassDefFoundError: Could not initialize class sun.font.SunFontManager

Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.UnsatisfiedLinkError: /usr/local/java/jdk-11.0.19/lib/libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory [in thread "reactor-http-epoll-2"]
2023-08-22T16:52:16.162718578Z     at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)

Main error :
java.lang.NoClassDefFoundError: Could not initialize class sun.font.SunFontManager - That is, the SunFontManager class cannot be initialized and /usr/local/java/jdk-11.0.19/lib/libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory [in thread “reactor-http-epoll-2”] , -that is, the libfontmanager.so: libfreetype.so.6 file or directory cannot be found

Summary :就是JDK里缺少了字体相关的包和文件,而验证码模块需要使用这些,所以导致无法生成并加载验证码。

The JDK image source used in the containerized deployment of the project module was manually built by myself using the dockerfile file and the docker build command . For the detailed construction process, please refer to my article: Using dockerfile to manually build the JDK11 image, run the container and verify it .

1.2 Solution 1-Modify the dockerfile for manually building JDK (add font support and Chinese support) and then manually build the JDK image source again

解决思路1:
1、修改手动构建JDK的dockerfile文件,在dockerfile文件添加安装字体和支持中文的配置。

2、重新docker build构建(添加了安装字体和支持中文的配置)新的JDK镜像源。

3、在项目模块的dockerfile中配置新构建的JDK的源。

4、注意:如果你是在Windows或者mac的IDEA本地环境中修改了dockerfile,记得要将修改后的dockerfile同步到服务器中,否则对dockerfile文件所做的修改是不会生效的。

5、删除(配置旧JDK:没有添加安装字体和支持中文)容器化的项目模块镜像和容器。

//删除镜像
docker rmi 镜像标识 (镜像名或者ID)

//强制删除镜像
docker rmi -f 镜像标识 (镜像名或者ID)

//删除容器
docker rm 容器标识(容器名或ID)

6、重新将项目模块容器化(在项目模块的dockerfile中配置新构建的JDK的源后,重新构建镜像和启动容器(此处直接使用deploy.sh脚本启动,脚本里配置了docker-compose命令,结合docker-compose.yml文件一起使用,docker-compose命令可以同时多个构建项目模块镜像,并基于该镜像启动该项目容器))。
    a、deploy.sh脚本启动,脚本里配置了docker-compose命令。
    b、docker-compose命令结合docker-compose.yml文件一起使用。
    c、docker-compose.yml文件中配置了docker-compose命令的build参数和项目模块dockerfile文件的位置。
    d、docker-compose命令可以同时构建多个项目模块镜像,并基于该镜像启动该项目容器。
    


//deploy.sh脚本 文件部分内容
# 启动程序模块(必须)
services(){
    
    
	docker-compose up -d ruoyi-gateway ruoyi-auth ruoyi-system
}

==============================================================================================================

//docker-compose.yml文件中部分内容

  ruoyi-gateway:
    image: ruoyi/ruoyi-gateway:1.7.0
    container_name: ruoyi-gateway

    build:
      context: ./ruoyi2023731/gateway
      #dockerfile的文件名称
      dockerfile: dockerfile


    environment:
      # 时区上海
      TZ: Asia/Shanghai
    ports:
      - "8080:8080"
    volumes:
      # 配置文件
      - /docker/ruoyi-gateway/logs/:/ruoyi/gateway/logs
      # skywalking 探针
      - /docker/skywalking/agent/:/ruoyi/skywalking/agent
    privileged: true
    network_mode: "host"

  ruoyi-auth:
    image: ruoyi/ruoyi-auth:1.7.0
    container_name: ruoyi-auth

    build:
      context: ./ruoyi2023731/auth
      #dockerfile的文件名称
      dockerfile: dockerfile


    environment:
      # 时区上海
      TZ: Asia/Shanghai
    ports:
      - "9210:9210"
    volumes:
      # 配置文件
      - /docker/ruoyi-auth/logs/:/ruoyi/auth/logs
      # skywalking 探针
      - /docker/skywalking/agent/:/ruoyi/skywalking/agent
    privileged: true
    network_mode: "host"

  ruoyi-system:
    # 镜像名 : 仓库/标签:版本
    image: ruoyi/ruoyi-system:1.7.0
    container_name: ruoyi-system

      #djc构建镜像-images的命令  2023-8-3 18:11:13
      # 指定dockerfile的上下文路径(相对当前docker-compose.yml的位置)
    # 包含Dockerfile文件的目录路径,或者是git仓库的URL
    #当提供的值是相对路径时,它被解释为相对于当前compose文件的位置。
    #该目录也是发送到Docker守护程序构建镜像的上下文。
    build:
      context: ./ruoyi2023731/system
      #dockerfile的文件名称
      dockerfile: dockerfile
    #本来这里有个ports的,但显示与下面的ports冲突,可能只要配置一个就可以了,对位置没有太多要求

    #  depends_on: 依赖(以指定顺序启动)

    # links也可以起到和depends_on相似的功能,即定义服务之间的依赖关系,从而确定服务启动的顺序



    environment:
      # 时区上海
      TZ: Asia/Shanghai
    ports:
      - "9201:9201"
    volumes:
      # 配置文件
      - /docker/ruoyi-system/logs/:/ruoyi/system/logs
      # skywalking 探针
      - /docker/skywalking/agent/:/ruoyi/skywalking/agent
    privileged: true
    network_mode: "host"

==============================================================================================================

缺点:如果自己使用dockerfile手动构建的JDK11镜像,添加了安装字体和支持中文的配置后,能解决现在的问题。不能保证后面这个
手动构建的JDK后面会不会发生其他问题。如果发生了其他错误,又要重新修改手动构建的JDK的dockerfile,删除手动构建的JDK的旧镜像和容器,重新执行脚本构建新的JDK,着实麻烦。

1.3 Solution 2-Use Huawei’s JDK image source directly

2. Modify the dockerfile for manually building JDK (add font support and Chinese support) and then manually build the JDK image source again.

2.1 Manually build JDK dockerfile before modification

# 建立一个新的镜像文件,配置模板:新建立的镜像是以centos为基础模板
# 因为jdk必须运行在操作系统之上
#每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
#第一条FROM,指定使用哪个镜像源

FROM centos:7.9.2009

#维护者 作者 邮箱
MAINTAINER djcking <djc**4*****@qq.com>

#RUN 指令告诉docker 在镜像内执行命令,安装了什么
#创建一个新目录来存储jdk文件
RUN  mkdir "/usr/local/java"

#将jdk压缩文件复制到镜像中,它将自动解压缩tar文件
ADD jdk-11.0.19_linux-x64_bin.tar.gz   /usr/local/java

# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime


# 设置环境变量
ENV JAVA_HOME /usr/local/java/jdk-11.0.19
ENV PATH $JAVA_HOME/bin:$PATH


# VOLUME 指定了临时文件目录为/tmp
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp

2.2 Modified dockerfile for manually building JDK

Added configurations for installing supported fonts and setting Chinese support .

# 建立一个新的镜像文件,配置模板:新建立的镜像是以centos为基础模板
# 因为jdk必须运行在操作系统之上
#每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
#第一条FROM,指定使用哪个镜像源

FROM centos:7.9.2009

#维护者 作者 邮箱
MAINTAINER djcking <djc**4*****@qq.com>

#RUN 指令告诉docker 在镜像内执行命令,安装了什么
#创建一个新目录来存储jdk文件
RUN  mkdir "/usr/local/java"

#将jdk压缩文件复制到镜像中,它将自动解压缩tar文件
ADD jdk-11.0.19_linux-x64_bin.tar.gz   /usr/local/java

# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime


# 安装支持的字体 【修改处1RUN yum install fontconfig -y

# 设置中文支持 【修改处2
# setup language 解决中文乱码
ENV  LANG C.UTF-8


# 设置环境变量
ENV JAVA_HOME /usr/local/java/jdk-11.0.19
ENV PATH $JAVA_HOME/bin:$PATH


# VOLUME 指定了临时文件目录为/tmp
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp

1.3 Upload the modified JDK dockerfile and jdk compressed package files

Upload the dockerfile and jdk image files to the **/home/mydockerfile2** file
Insert image description here

2.4 Build JDK image

Note that there is a dot at the end, which means using the Dockerfile of the current path to build.

docker build -t djcjdk202395:11 .

2.5 Configure your own djcjdk202395-11 in the dockerfile of gateway

# 基础镜像
#FROM  anapsix/alpine-java:8_server-jre_unlimited
#FROM   openjdk:11-jre
#FROM  anapsix/alpine-java:11_server-jre_unlimited
#配置自己的djcjdk202395:11  2023-9-5 00:36:42
#FROM  djcjdk202395:11



# author
MAINTAINER djc 

# 挂载目录
VOLUME /home/ruoyi202381
# 创建目录
RUN mkdir -p /home/ruoyi202381
# 指定路径
WORKDIR /home/ruoyi202381
# 复制jar文件到路径
COPY ./jar/gateway.jar /home/ruoyi202381/gateway.jar
# 启动用户服务    网关服务
ENTRYPOINT ["java","-jar","gateway.jar"]

Insert image description here

2.6 Delete old gateway images and containers (no Chinese support or font support)

To delete images and containers, please refer to my article on basic Docker operations: Deleting containers Container and deleting images IMAGE
//Delete images
docker rmi image identification (image name or ID)

//Forcibly delete the image
docker rmi -f image identification (image name or ID)

//Delete container
docker rm container identification (container name or ID)

2.7 Rebuild the gateway module

cd /opt/docker-compose/ruoyicloudplus/docker/ruoyi2023731/gateway
docker-compose up -d ruoyi-gateway 

Insert image description here
Build failed

Exception in thread "main" java.lang.UnsupportedClassVersionError: com/ruoyi/gateway/RuoYiGatewayApplication has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
2023-09-05T00:50:49.629236904Z 	at java.lang.ClassLoader.defineClass1(Native Method)
说明JDK有问题,这个问题之前遇到过。

Insert image description here

3. Directly use Huawei’s JDK image source

3.1 Obtain the image source

//1-拉取华为JDK镜像源
docker pull swr.ap-southeast-3.myhuaweicloud.com/oracle/jdk:11

//2-给镜像源打标签
docker tag 457a2c8597a1  hw-oracle/jdk:11

Insert image description here

3.2 Delete the old images and containers of the three major modules

gateway (gateway) , auth (authentication and authorization center) , system (system module)
to delete images and containers, please refer to my article on basic Docker operations: deleting container Container and deleting image IMAGE

//删除镜像
docker rmi 镜像标识 (镜像名或者ID)

//强制删除镜像
docker rmi -f 镜像标识 (镜像名或者ID)

//删除容器
docker rm 容器标识(容器名或ID)

Insert image description here

Insert image description here

3.3 Configure and use Huawei’s image source in the three major modules

3.3.1 Gateway’s dockerfile configuration uses Huawei’s JDK image source

# 基础镜像
#FROM  anapsix/alpine-java:8_server-jre_unlimited
#FROM   openjdk:11-jre
#FROM  anapsix/alpine-java:11_server-jre_unlimited
#配置自己的djcjdk202395:11  2023-9-5 00:36:42
#FROM  djcjdk202395:11

#配置使用华为的JDK镜像源  2023-9-5 01:12:48
FROM hw-oracle/jdk:11

# author
MAINTAINER djc djc****@qq.com

# 挂载目录
VOLUME /home/ruoyi202381
# 创建目录
RUN mkdir -p /home/ruoyi202381
# 指定路径
WORKDIR /home/ruoyi202381
# 复制jar文件到路径
COPY ./jar/gateway.jar /home/ruoyi202381/gateway.jar
# 启动用户服务    网关服务
ENTRYPOINT ["java","-jar","gateway.jar"]

3.3.2 Auth’s dockerfile configuration uses Huawei’s JDK image source

# 基础镜像
#FROM  anapsix/alpine-java:8_server-jre_unlimited
#FROM   openjdk:11-jre
#FROM  anapsix/alpine-java:11_server-jre_unlimited

#配置使用华为的JDK镜像源  2023-9-5 01:12:48
FROM hw-oracle/jdk:11

# author
MAINTAINER djc  <djc**4*****@qq.com>

# 挂载目录
VOLUME /home/ruoyi202381
# 创建目录
RUN mkdir -p /home/ruoyi202381
# 指定路径
WORKDIR /home/ruoyi202381
# 复制jar文件到路径
COPY ./jar/auth.jar /home/ruoyi202381/auth.jar
# 启动用户服务    认证授权中心服务
ENTRYPOINT ["java","-jar","auth.jar"]

3.3.3 The dockerfile configuration of the system module uses Huawei’s JDK image source

# 基础镜像
#FROM  anapsix/alpine-java:8_server-jre_unlimited
#FROM   openjdk:11-jre
#FROM  anapsix/alpine-java:11_server-jre_unlimited

#配置使用华为的JDK镜像源  2023-9-5 01:12:48
FROM hw-oracle/jdk:11

# author
MAINTAINER djc  <djc**4*****@qq.com>

# 挂载目录
VOLUME /home/ruoyi202381
# 创建目录
RUN mkdir -p /home/ruoyi202381
# 指定路径
WORKDIR /home/ruoyi202381
# 复制jar文件到路径
COPY ./jar/system.jar /home/ruoyi202381/system.jar
# 启动用户服务  系统模块服务
ENTRYPOINT ["java","-jar","system.jar"]

3.4 Rebuild the three major module images and start the three major module containers

3.4.1 Front-end dist package and installation configuration nginx (nginx.conf)

Solve the 404 problem and the deployment project backend cannot accept the request.
Modify the VUE_APP_BASE_API in ruoyi-ui/.env.production and
configure the VUE_APP_BASE_API in ruoyi-ui/.env.production to: VUE_APP_BASE_API='http://192.168.1.16:8080 '
The ip must be configured as a public network ip, and the port number must be consistent with the backend.

Modify vue.config.js
target: http://localhost:8080 to target: http://192.168.1.16:8080

3.4.2 Start the three major backend module images (gateway-auth-system)

Key points :
1. Pay attention to the firewall settings and open several service ports .
Set the firewall to open ruoyigateway8080, ruoyi-system9201, ruoyi-auth9210,
mysql3306, redis6379, nacos8848, seata-server8091 ports.
Insert image description here

2. Execute the script command sh deploy.sh base . When starting nacos in the basic environment, a No dataset source error may be reported . This is because the background configuration file of nacos is stored in mysql , and nacos has already been started before mysql is fully started. , causing the configuration file to fail to load . In other words, mysql must be started successfully before nacos can be loaded into the configuration file and fully started successfully.

3. After starting the back-end basic environment and the three major service modules , check whether the container starts normally and successfully . (Use the docker ps command to check whether the running container contains four back-end basic environments and three major service modules, a total of seven images and seven containers.)

//1-进入登录脚本文件所在的文件夹
cd /opt/docker-compose/ruoyicloudplus/docker/sh2023731

//2-启动后端基础环境mysql redis nacos seata-server
//实际执行docker-compose up -d mysql redis nacos seata-server
sh deploy.sh base

//3-启动服务ruoyi-gateway ruoyi-auth ruoyi-system  
//自动重新构建ruoyi-gateway和ruoyi-auth和ruoyi-system镜像和运行ruoyi-auth和ruoyi-system容器
//实际执行docker-compose up -d ruoyi-gateway ruoyi-auth ruoyi-system
sh  deploy.sh  services

Contents of deploy.sh script in sh2023731

#!/bin/sh

# 使用说明,用来提示输入参数
usage(){
    
    
	echo "Usage: sh 执行脚本.sh [base|services|stop|rm]"
	exit 1
}

# 启动基础环境(必须)
base(){
    
    
	docker-compose up -d mysql redis nacos seata-server
}

# 启动程序模块(必须)
services(){
    
    
	docker-compose up -d ruoyi-gateway ruoyi-auth ruoyi-system
}

# 关闭所有环境/模块
stop(){
    
    
	docker-compose stop
}

# 删除所有环境/模块
rm(){
    
    
	docker-compose rm
}

# 根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"base")
	base
;;
"services")
	services
;;
"stop")
	stop
;;
"rm")
	rm
;;
*)
	usage
;;
esac

3.4.3 Screenshots of the process of rebuilding the three major module images and starting the three major module containers

Insert image description here
Insert image description here
Insert image description here

3.4.4 Successful loading of verification code and resolution of console garbled characters

Note: The verification code does not appear . It may be that a certain module container of the back-end basic environment mysql redis nacos seata-server did not start successfully.

Insert image description here
Insert image description here
After successful login,
Insert image description here
the Dubbo service response and call of the console ruoyi-system
Insert image description here
exit the system.
Insert image description here
Insert image description here

Insert image description here

3.4.5 Close all module containers

Close all module container commands

【关闭所有模块】
//1-进入登录脚本文件所在的文件夹
cd /opt/docker-compose/ruoyicloudplus/docker/sh2023731

//2-启动关闭所有模块的脚本
//实际执行docker-compose stop
sh deploy.sh  stop

#sh2023731中的deploy.sh脚本内容 相关内容
# 关闭所有环境/模块   2023-9-4 23:08:12
stop(){
    
    
	docker-compose stop
}

Close all module container screenshots

Insert image description here
Insert image description here
Close all modules -sh deploy.sh stop - background log
Insert image description here

3.5 The principle of building module images of three major projects through the sh deploy.sh services script command

//3-启动服务ruoyi-gateway ruoyi-auth ruoyi-system  
//自动重新构建ruoyi-gateway和ruoyi-auth和ruoyi-system镜像和运行ruoyi-auth和ruoyi-system容器
//实际执行docker-compose up -d ruoyi-gateway ruoyi-auth ruoyi-system
sh  deploy.sh  services

What is actually executed is the docker-compose command docker-compose up -d ruoyi-gateway ruoyi-auth ruoyi-system . docker-compose can build images and start containers in batches .

To install and configure docker and docker-compose in CentOS7, you can refer to my article about installing and configuring docker and docker-compose based on CentOS7.

1、安装好docker与docker-compose的环境。

2、配置好JDK镜像源。

3、编写三大模块的docker-compose.yml文件。

4、三大模块的docker-compose.yml中build参数用来构建镜像、dockerfile参数用来指定dockerfile
文件的位置。

5Java -jar jar包名称 命令直接在容器中运行模块。
前面三大模块dockerfile中最后一行中出现的gateway.jar、auth.jar、system.jar
实际是后端通过maven打包生成的jar。

关于Java -jar具体看3.5 jar文件和脚本文件的说明

The principle is drawn in a diagram to facilitate your own understanding. (Take the gateway service module as an example, the auth authentication and authorization module, and the system module are the same)

Insert image description here

3.5 Description of jar files and script files

The gateway.jar , auth.jar , and system.jar that appear in the last line of the dockerfile of the previous three modules are actually jars generated by the backend through maven packaging .

3.5.1 Refresh maven dependencies & clean projects

Insert image description here

3.5.2 package-package

Insert image description here

3.5.3 Execute copy.sh

The jar name generated by maven package packaging uses the module name as the name of the jar package by default .
For example, the name of the jar package generated by default when packaging the ruoyi-gateway module is ruoyi-gateway.jar . The name of the jar package generated by default when ruoyi-auth module is packaged is ruoyi-auth.jar . The name of the jar package generated by default when ruoyi-system module is packaged is ruoyi-gateway.jar .

Here, by writing and running the copy.sh script, these three jar files are copied to the corresponding folders and their names are changed and simplified.

#!/bin/bash

# 创建目标目录
#db存放sql源文件
mkdir -p ../mysql2023731/db2023731

#ruoyi-gateway 网关服务  (网关服务(RuoYiGatewayApplication)启动8080)
mkdir -p ../ruoyi2023731/gateway/jar

#ruoyi-auth   认证授权中心          (认证授权中心RuoYiAuthApplication启动9210
mkdir -p ../ruoyi2023731/auth/jar

#系统模块RuoYiSystemApplication启动9201
mkdir -p ../ruoyi2023731/system/jar




# 复制sql文件 到/docker/mysql/db2023731文件夹中
echo "begin copy sql "
cp ../../sql/ry-cloud.sql    ../mysql2023731/db2023731
cp ../../sql/ry-config.sql   ../mysql2023731/db2023731
cp ../../sql/ry-job.sql      ../mysql2023731/db2023731
cp ../../sql/ry-seata.sql    ../mysql2023731/db2023731
cp ../../sql/test.sql        ../mysql2023731/db2023731
echo "end copy sql "


# 复制jar文件
echo "begin copy jar "
cp ../../ruoyi-gateway/target/ruoyi-gateway.jar                ../ruoyi2023731/gateway/jar/gateway.jar
cp ../../ruoyi-auth/target/ruoyi-auth.jar                      ../ruoyi2023731/auth/jar/auth.jar
cp ../../ruoyi-modules/ruoyi-system/target/ruoyi-system.jar    ../ruoyi2023731/system/jar/system.jar
echo "end copy jar "

run copy.sh
Insert image description here
Insert image description here
system.jar
Insert image description here
auth.jar
Insert image description here
gateway.jar
Insert image description here
run copy.sh script command analysis
Insert image description here

3.6 java -jar command to start user service

The last line in the dockerfile of the three major modules is configured with the following line of command.

# 启动用户服务    网关服务
ENTRYPOINT ["java","-jar","gateway.jar"]
# 启动用户服务    认证授权中心服务
ENTRYPOINT ["java","-jar","auth.jar"]
# 启动用户服务  系统模块服务
ENTRYPOINT ["java","-jar","system.jar"]

Here, the SpringBoot project is actually deployed directly as a jar package . For a detailed introduction, please see the official document Creating an Executable Jar 1. First, add the following content to the dependencies in the project's pom.xml file.

Insert image description here
Insert image description here

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Here we take boot3-01-demo as an example
Insert image description here

2. mvn package packages the boot3-01-demo project module

//1-maven打包
mvn package

After executing the maven packaging command mvn package , a jar package will appear in the target directory. The name is
project name-0.0.1-SNAPSHOT.jar , here is boot3-01-demo-1.0-SNAPSHOT.jar .

//2-如果想进一步查看,就执行 jar tvf命令
 jar tvf target/boot3-01-demo-1.0-SNAPSHOT.jar

You should see a much smaller file named boot3-01-demo-1.0-SNAPSHOT.jar.original in the target directory. This is the original jar file created by Maven before Spring Boot repackaging .
Insert image description here

//3-运行
语法:java -jar jar文件名
java -jar boot3-01-demo-1.0-SNAPSHOT.jar

Insert image description here

Insert image description here

//4-停止
按ctrl c

Insert image description here
Here, the SpringBoot project is actually deployed directly as a jar package . For detailed introduction, please see the official document Creating an Executable Jar

Guess you like

Origin blog.csdn.net/qyfx123456/article/details/132673168