gradle如何确定file.encoding JVM系统属性?

问题描述

在编译,运行测试或运行主类时,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.encodingjavac -encoding),而不是编写大量的if语句以避免发送-Dfile.encoding-encoding,如果根本没有设置任何显式编码。