windows下idea执行maven compile中文乱码问题简单分析

网上有很多说出了解决办法的文章,却没有分析原因,解决方法是idea的settings

VM Options中加入-Dfile.encoding=GBK或者GB2312,这样乱码就会是正确的汉字, BUT!!!,为什么呢?

原因分析

- idea与maven怎么交互的
C:\Java\jdk1.8.0_162\bin\java.exe -Dmaven.multiModuleProjectDirectory=C:\projects\testweb 
"-Dmaven.home=C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.3\plugins\maven\lib\maven3" 
"-Dclassworlds.conf=C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.3\plugins\maven\lib\maven3\bin\m2.conf" 
"-Dmaven.ext.class.path=C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.3\plugins\maven\lib\maven-event-listener.jar" 
"-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.3\lib\idea_rt.jar=2669:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.3\bin" 
-Dfile.encoding=UTF-8 
-classpath "C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.3\plugins\maven\lib\maven3\boot\plexus-classworlds-2.6.0.jar" org.codehaus.classworlds.Launcher -Didea.version2019.3.3 compile

为了看清楚我加了换行,-D参数有空格的,都会使用双引号包起来。 这是个java进程,入口是org.codehaus.classworlds.Launcher

- Launcher分析

org.codehaus.plexus.classworlds.launcher.Launcher.main( args );
String CLASSWORLDS_CONF = "classworlds.conf";
注意上面命令行有对应配置,是m2.conf,内容如下:

main is org.apache.maven.cli.MavenCli from plexus.core

set maven.conf default ${maven.home}/conf

[plexus.core]
load       ${maven.conf}/logging
optionally ${maven.home}/lib/ext/*.jar
load       ${maven.home}/lib/*.jar

其实就是调用到MavenCli,参数同样传递过去,compile

- Maven怎么编译代码的?

使用Apache Maven Compiler Plugin插件编译

The Compiler Plugin is used to compile the sources of your project. Since 3.0, the default compiler is javax.tools.JavaCompiler (if you are using java 1.6) and is used to compile Java sources. If you want to force the plugin using javac, you must configure the plugin option forceJavacCompilerUse.

- javac的问题

我们用javac,其实也是用javax.tools.JavaCompiler,那么在windows下,本地的编码是GBK,默认输出的汉语信息编码就是GBK,如何强制设为UTF-8呢?

用法: javac <options> <source files>
其中, 可能的选项包括:
  @<filename>                  从文件读取选项和文件名
  -Akey[=value]                传递给注释处理程序的选项
  --add-modules <模块>(,<模块>)*
        除了初始模块之外要解析的根模块; 如果 <module>
                为 ALL-MODULE-PATH, 则为模块路径中的所有模块。
  --boot-class-path <path>, -bootclasspath <path>
        覆盖引导类文件的位置
  --class-path <path>, -classpath <path>, -cp <path>
        指定查找用户类文件和注释处理程序的位置
  -d <directory>               指定放置生成的类文件的位置
  -deprecation                 输出使用已过时的 API 的源位置
  --enable-preview             启用预览语言功能。要与 -source 或 --release 一起使用。
  -encoding <encoding>         指定源文件使用的字符编码
  -endorseddirs <dirs>         覆盖签名的标准路径的位置
  -extdirs <dirs>              覆盖所安装扩展的位置
  -g                           生成所有调试信息
  -g:{lines,vars,source}       只生成某些调试信息
  -g:none                      不生成任何调试信息
  -h <directory>               指定放置生成的本机标头文件的位置
  --help, -help, -?            输出此帮助消息
  --help-extra, -X             输出额外选项的帮助
  -implicit:{none,class}       指定是否为隐式引用文件生成类文件
  -J<flag>                     直接将 <标记> 传递给运行时系统
  --limit-modules <模块>(,<模块>)*
        限制可观察模块的领域
  --module <module-name>, -m <module-name>

注意有一个-J<flag>参数,我们可以-J-Dfile.encoding=UTF-8,这样,javac输出的信息就是UTF-8编码了

- 能不能给maven compiler plugin传参?
<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-compiler-plugin</artifactId>
	<configuration>
		<fork>true</fork>
		<compilerArgs>
			<arg>-J-Dfile.encoding=UTF-8</arg>
		</compilerArgs>
	</configuration>
</plugin>
- -Dfile.encoding解析

大家都知道这个参数,在jvm内存中,无论是英文字符还是中文字符,其实就是一个char,char是一个两个字节的数字,可以代表一个字符(java9之后字符串有变化,字符串不再是char数组了),当我们要把这个char写出去的时候,无论是写出到文件,还是socket,还是命令行,就要给它编码,这时候就用到这个参数了,指定写出的编码方案,同样,当jvm加载类读取字符串的时候,其实就是一个读取解码的过程,class文件用unicode编码,所以javac中有个选项-encoding,指定 源文件的编码方案 ,无论源文件用什么字符集,到class文件里都是unicode,可以用支持16进制的文本编辑器打开class文件分析一下。
当从jvm写出东西的时候,我们也可以指定编码, getBytes(Charset.forName("UTF-8"));

This property is used for the default encoding in Java, all readers and writers would default to use this property. “file.encoding” is set to the default locale of Windows operationg system since Java 1.4.2. System.getProperty(“file.encoding”) can be used to access this property.

感兴趣可以分析一下maven compiler plugin的源码,或者使用别的编译器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值