问题描述
在编译,运行测试或运行主类时,gradle使用显式file.encoding
启动Java,例如:
/usr/bin/java -Dfile.encoding=ISO-8859-1 -Duser.country=GB -Duser.language=en
-Duser.variant -cp … com.foo.MyMainClass
gradle如何选择此默认文件编码(对我来说是ISO-8859-1)?要切换到UTF-8,我必须在gradle构建脚本中添加以下内容:
allprojects {
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
tasks.withType(Test) {
systemProperty 'file.encoding','UTF-8'
}
tasks.withType(JavaExec) {
systemProperty 'file.encoding','UTF-8'
}
}
设置-Dfile.encoding=UTF-8
。
更新#1
rzwitserloot指出gradle可能使用默认编码,这似乎是正确的。
PrintCharset.java
import java.nio.charset.Charset;
public class PrintCharset {
public static void main(String[] args) {
System.out.println("Default: " + Charset.defaultCharset());
}
}
然后,javac PrintCharset.java && java PrintCharset
打印
Default: ISO-8859-1
有趣的是,从IntelliJ(无gradle)运行会执行:
/usr/bin/java -javaagent:… -Dfile.encoding=UTF-8 -classpath … PrintCharset
它当然会打印Default: UTF-8
。
更新#2
出于好奇,我在Linux上的OpenJDK中将默认字符集设置为ultimately determined by nl_langinfo()
:
printlang.c
#include <langinfo.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
setlocale(LC_ALL,"");
printf("%s\n",nl_langinfo(CODESET));
exit(EXIT_SUCCESS);
}
然后,gcc -o printlang printlang.c && ./printlang
打印ISO-8859-1
。
解决方法
TL; DR:谁知道,但可能是Charset.defaultEncoding。
更多信息,
大概是您平台的默认设置。 gradle需要经过很长的链。首先,在任务本身上有明确的覆盖,然后对于所有此类任务都可以覆盖此值(这是您的gradle片段所执行的操作),然后是GRADLE_OPTS=-Dfile.encoding=....
选项,gradle将在任务执行时查看本身没有明确选择一个。文档或多或少都到此为止了,但是大概它会退回到Charset.defaultEncoding()
返回的值上(您可以编写一个1-liner Java应用程序并打印出来,看看),并且gradle更加简单检索此字符集的名称,然后将其应用于设置编码的所有位置(是java -Dfile.encoding
或javac -encoding
),而不是编写大量的if
语句以避免发送-Dfile.encoding
或-encoding
,如果根本没有设置任何显式编码。