Linux运行Java程序中文日志乱码
前言
最近在开发一个Java程序的时候,打包好后丢上阿里云上运行,日志中的中文死活都报乱码,看了网上好多文章发现说的都不全面,因此在这里记录一下最后的解决方案。
一、问题分析
首先分析一下Java代码是怎么从源代码阶段一直到在Linux上部署运行然后跑起来的。
如图可见jar包的运行是会经历以上三个阶段的,而这三个阶段中都会有不同的方法来指定编码集,只有三个阶段的编码集相同才不会导致中文乱码问题,下面来分析以下这三个阶段做了什么。
1、Java源代码->Java字节码
在编译阶段,使用javac命令将java源文件编译成.class字节码文件,编译编码默认采用系统编码,而windows平台一般是GBK,这就是为什么网上有些文章下面有人留言自己把后续运行jar编码集换成gbk就能正常显示的原因。
2、JAVA字节码->JVM->操作系统
在程序执行阶段JVM加载字节码文件,然后把类元数据信息存放到方法区中,实际执行的时候JVM会执行方法区中的代码,当然前提是操作系统需要有Java环境,这一步使用java -jar指令来运行,执行时可以指定jar包运行编码集。
3、操作系统->显示设备
最后我们查看程序的执行情况,主要是通过查看日志的方式,这是要求我们的操作系统能够正常显示中文,即安装了中文字体,且编码集与上述步骤相同。
二、解决方案
下面以utf-8字符集为例来一个一个问题解决
1、Java源代码->Java字节码指定编码集
这里要分为两种情况,分为使用Maven打包以及使用javac生成字节码文件
-
Maven打包,pom文件加入如下配置
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
-
javac生成字节码文件
javac -encoding utf-8 xxx.java
2、JAVA字节码->JVM->操作系统
-
java -jar运行jar包时加入如下配置
java -Dfile.encoding=utf-8 -jar xxx.jar
-
tomcat启动
# 假如使用tomcat启动,需要去修改对应启动脚本的配置 # 在daemon.sh和catalina.sh中加入以下代码 JAVA_OPTS="$JAVA_OPTS -Djavax.servlet.request.encoding=utf-8 -Dfile.encoding=utf-8 -Duser.language=zh_CN -Dsun.jnu.encoding=utf-8"
3、操作系统->显示设备
-
前提检测
我们在发现linux中程序日志乱码的时候首先要确定是服务器的问题还是上述步骤的问题,验证方法也很简单,创建一个中文名称的文件,然后使用
ll
命令查看文件名是否正常显示,显示正常则本地编码集能显示中文(但是还存在与上述设定编码集不一致问题),如果不行则需要切换系统编码集。# 创建文件 touch 测试 ## 查看文件信息 ll
如上图所示,这里直接不能显示中文,则需要切换系统编码集
-
系统编码集切换
这里以utf-8为例,首先查看当前系统的编码集
locale
-
下一步查看系统中是否有安装中文utf-8编码集
locale -a | grep zh_CN.utf8
我们能看到这里系统安装了,因此直接使用即可,如果没有执行以下指令安装
yum install kde-l10n-Chinese
-
更换本地编码集配置
# 打开locale配置文件 vi /etc/locale.conf # 替换里面的编码集设置 LANG="zh_CN.utf8" # 配置文件生效 source /etc/locale.conf
-
最后还需要考虑一下是否连接工具的终端编码有问题
-
Xshell
文件->打开->选中会话->右键->属性->终端
将编码改为 UTF-8 保存
-
MobaXterm
选择sessions窗口中对应的连接右键->Edit session->Terminal settings->Terminal font settings
将charset改成UTF-8 保存
-
-
至此日志文件便能正常显示。
三、总结
在解决这一问题的时候可以对上述提到的三个环节进行分析,查看字符集是否一致。此外,在解决其他问题时也一样,将问题拆解开来,逐个排查,问题便迎刃而解了。