简体   繁体   中英

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

When compiling, running tests, or running a main class, gradle launches java with an explicit file.encoding , for example:

/usr/bin/java -Dfile.encoding=ISO-8859-1 -Duser.country=GB -Duser.language=en
              -Duser.variant -cp … com.foo.MyMainClass

How does gradle select this default file encoding (which is ISO-8859-1 for me)? To switch to UTF-8, I have to add the following to my gradle build script:

allprojects {
    tasks.withType(JavaCompile) {
        options.encoding = 'UTF-8'
    }

    tasks.withType(Test) {
        systemProperty 'file.encoding', 'UTF-8'
    }

    tasks.withType(JavaExec) {
        systemProperty 'file.encoding', 'UTF-8'
    }
}

which sets -Dfile.encoding=UTF-8 .

Update #1

rzwitserloot noted that gradle is likely using the default encoding, which appears to be true.

PrintCharset.java

import java.nio.charset.Charset;

public class PrintCharset {
    public static void main(String[] args) {
        System.out.println("Default: " + Charset.defaultCharset());
    }
}

Then, javac PrintCharset.java && java PrintCharset prints

Default: ISO-8859-1

Interestingly, running from IntelliJ (without gradle) executes:

/usr/bin/java -javaagent:… -Dfile.encoding=UTF-8 -classpath … PrintCharset

which, of course, prints Default: UTF-8 .

Update #2

Digging a little deeper out of curiosity, the default charset in OpenJDK on linux is 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);
}

Then, gcc -o printlang printlang.c && ./printlang prints ISO-8859-1 .

TL;DR: Who knows, but probably Charset.defaultEncoding.

With some more information:

Presumably, it's your platform default. There's a long chain that gradle goes through. First there's the explicit override on the task itself, then there's the ability to override this value for all such tasks (which is what your snippet of gradle does), then there's the GRADLE_OPTS=-Dfile.encoding=.... option which gradle would look at if the task itself doesn't explicitly pick one. The docs more or less end there, but presumably it'll then fall back to whatever Charset.defaultEncoding() returns (you can write a 1-liner java app and print that, have a look), and it's simpler for gradle to just retrieve the name of this charset and then apply it everywhere it sets encoding (be it java -Dfile.encoding or javac -encoding ) instead of writing a ton of if statements to avoid sending -Dfile.encoding or -encoding when no explicit encoding was set at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM