gradle如何决定file.encodingJVM系统属性?

How does gradle decide the file.encoding JVM system property?

编译时,运行 测试,或 运行 主程序 class,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 select 这个默认文件编码(对我来说是 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

出于好奇深入挖掘,OpenJDK 在 linux 上的默认字符集是 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() returns (你可以写一个 1-liner java 应用程序并打印它,看看) ,对于 gradle 来说更简单的是只检索这个字符集的名称,然后在它设置编码的任何地方应用它(无论是 java -Dfile.encoding 还是 javac -encoding)而不是写一大堆 if 语句以避免在根本没有设置显式编码时发送 -Dfile.encoding-encoding