Gradle Garbled code

package com.stu;

public class Main {

    public static void main(String[] args) {
        Main main = new Main();
        main.test00();
    }

    public void test00() {
        System.out.println("中文测试");
        System.out.println("sun.stdout.encoding = " + System.getProperty("sun.stdout.encoding"));
        System.out.println("sun.stderr.encoding = " + System.getProperty("sun.stderr.encoding"));
        System.out.println("    native.encoding = " + System.getProperty("native.encoding"));
    }
}
/*
 * This file was generated by the Gradle 'init' task.
 *
 * This is a general purpose Gradle build.
 * To learn more about Gradle by exploring our Samples at https://docs.gradle.org/8.5/samples
 */

plugins {
    id("java")
}

tasks.register("runCode", JavaExec::class) {
    mainClass = "com.stu.Main"
    classpath = sourceSets["main"].runtimeClasspath

    group = "Exec"
    description = "运行指定代码"
}

tasks.register("runStu") {
    for (sourceSetContainer in sourceSets) {
        println(sourceSetContainer)
    }

    println(sourceSets)
}
PS D:\Workspeace\Temp-speace\test> ./gradlew runCode                                                                                
                                                                                                                                    
> Configure project :
[-Dsun.stdout.encoding=UTF-8, -Dsun.stderr.encoding=UTF-8, -Dfile.encoding=UTF-8, -Dnative.encoding=UTF-8]

> Task :runCode
涓枃娴嬭瘯
sun.stdout.encoding = UTF-8
sun.stderr.encoding = UTF-8
    native.encoding = GBK

BUILD SUCCESSFUL in 696ms
2 actionable tasks: 1 executed, 1 up-to-date
PS D:\Workspeace\Temp-speace\test>     

This text is garbled, how can I solve it

What is garbled where?

If you mean the first println in your test00, make sure that the encoding you save your source file in matches the encoding that is told to the compiler.
If you for example save your file in UTF-8, but do not specify an explicit encoding, the system default encoding might be used by the Java compiler, “garbling” the text by reading your source file in the wrong encoding if the system default encoding is not UTF-8.

If that is your problem, either make sure that all compilers you might use (Gradle, IDE, …) are configured to use the encoding that you also use to save your files in, or restrict yourself to a charset in your source files that is the same in all relevant encodings, using Unicode escape sequences \u.... for all other characters.

Is there a tutorial on how to set up UTF-8 for Gradle?

In the Windows environment, using PowerShell to execute Gradle is garbled. I set up PowerShell chcp 65001

It depends on which tasks you are using.
You can for example configure encoding for Javadoc task, for Java files during joint Groovy compilation on GroovyCompile task, for Groovy files on GroovyCompile task, on Java files in JavaCompile tasks, …

For configuring UTF-8 for all JavaCompile tasks in a project you can simply do

tasks.withType<JavaCompile>().configureEach {
    options.encoding = utf8
}

test.zip (111.3 KB)
I sent a copy of my actual code

The environment I am using is

openjdk version "21.0.2" 2024-01-16
OpenJDK Runtime Environment (build 21.0.2+13-58)
OpenJDK 64-Bit Server VM (build 21.0.2+13-58, mixed mode, sharing)



------------------------------------------------------------
Gradle 8.5
------------------------------------------------------------

Build time:   2023-11-29 14:08:57 UTC
Revision:     28aca86a7180baa17117e0e5ba01d8ea9feca598

Kotlin:       1.9.20
Groovy:       3.0.17
Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM:          21.0.2 (Oracle Corporation 21.0.2+13-58)
OS:           Windows 11 10.0 amd64

After I added it, the code was still garbled

tasks.withType<JavaCompile>().configureEach {
    options.encoding = "UTF-8"
}
PS D:\Workspeace\Temp-speace\test> gradle runCode

> Task :runCode
涓枃娴嬭瘯
sun.stdout.encoding = UTF-8
sun.stderr.encoding = UTF-8
    native.encoding = GBK

BUILD SUCCESSFUL in 1s
2 actionable tasks: 1 executed, 1 up-to-date

Hm, what about if you do <path to java 21>\bin\java -cp build\classes\java\main com.stu.Main?

PS D:\Workspeace\Temp-speace\test\build\classes\java\main> java com.stu.Main
中文测试
sun.stdout.encoding = null
sun.stderr.encoding = null
    native.encoding = GBK


Active code page: 65001
PS D:\Workspeace\Temp-speace\test\build\classes\java\main> java com.stu.Main
涓枃娴嬭瘯
sun.stdout.encoding = null
sun.stderr.encoding = null
    native.encoding = GBK

I switched to chcp 65001 and this garbled code appeared

So when switching the cp to 65001 you also get the same garbled output you get when running through Gradle, but the correct output if you do not.
What when run through Gradle in that exact same state where it worked through Java directly?

I tested some situations

Java UTF-8 PowerShell UTF-8

Active code page: 65001

java "-Dfile.encoding=UTF-8" "-Dsun.stdout.encoding=UTF-8" "-Dsun.stderr.encoding=UTF-8" com.stu.Main
涓枃娴嬭瘯
sun.stdout.encoding = UTF-8
sun.stderr.encoding = UTF-8
      file.encoding = UTF-8
    native.encoding = GBK

Java GBK PowerShell UTF-8

Active code page: 65001

java "-Dfile.encoding=GBK" "-Dsun.stdout.encoding=GBK" "-Dsun.stderr.encoding=GBK" com.stu.Main
中文测试
sun.stdout.encoding = GBK
sun.stderr.encoding = GBK
      file.encoding = GBK
    native.encoding = GBK

Gradle no config PowerShell UTF-8

tasks.withType(JavaExec::class.java) {
    val args:List<String> = ArrayList()
    //args.addLast("-Dsun.stdout.encoding=GBK")
    //args.addLast("-Dsun.stderr.encoding=GBK")
    //args.addLast("-Dfile.encoding=GBK")
    //args.addLast("-Dnative.encoding=GBK")
    this.jvmArgs = args
    println(this.jvmArgs)
}
> Task :runCode
锟斤拷锟侥诧拷锟斤拷
sun.stdout.encoding = null
sun.stderr.encoding = null
      file.encoding = UTF-8
    native.encoding = GBK

BUILD SUCCESSFUL in 753ms
2 actionable tasks: 1 executed, 1 up-to-date

Gradle UTF-8 PowerShell UTF-8

tasks.withType(JavaExec::class.java) {
    val args:List<String> = ArrayList()
    args.addLast("-Dsun.stdout.encoding=UTF-8")
    args.addLast("-Dsun.stderr.encoding=UTF-8")
    args.addLast("-Dfile.encoding=UTF-8")
    args.addLast("-Dnative.encoding=UTF-8")
    this.jvmArgs = args
//  val args = this.jvmArgs

//    args?.addLast("-Dsun.stdout.encoding=utf8")
//    args?.addLast("-Dsun.stderr.encoding=utf8")
//    this.jvmArgs = args;
    println(this.jvmArgs)
}
> Task :runCode
涓枃娴嬭瘯
sun.stdout.encoding = UTF-8
sun.stderr.encoding = UTF-8
      file.encoding = UTF-8
    native.encoding = GBK

BUILD SUCCESSFUL in 1s
2 actionable tasks: 1 executed, 1 up-to-date

Gradle GBK PowerShell UTF-8

tasks.withType(JavaExec::class.java) {
    val args:List<String> = ArrayList()
    args.addLast("-Dsun.stdout.encoding=GBK")
    args.addLast("-Dsun.stderr.encoding=GBK")
    args.addLast("-Dfile.encoding=GBK")
    args.addLast("-Dnative.encoding=GBK")
    this.jvmArgs = args
//  val args = this.jvmArgs

//    args?.addLast("-Dsun.stdout.encoding=utf8")
//    args?.addLast("-Dsun.stderr.encoding=utf8")
//    this.jvmArgs = args;
    println(this.jvmArgs)
}
> Task :runCode
锟斤拷锟侥诧拷锟斤拷
sun.stdout.encoding = GBK
sun.stderr.encoding = GBK
      file.encoding = GBK
    native.encoding = GBK

BUILD SUCCESSFUL in 708ms
2 actionable tasks: 1 executed, 1 up-to-date

Java UTF-8 PowerShell GBK

Active code page: 936

java "-Dfile.encoding=UTF-8" "-Dsun.stdout.encoding=UTF-8" "-Dsun.stderr.encoding=UTF-8" com.stu.Main
涓枃娴嬭瘯
sun.stdout.encoding = UTF-8
sun.stderr.encoding = UTF-8
      file.encoding = UTF-8
    native.encoding = GBK

Java GBK PowerShell GBK

Active code page: 936

java "-Dfile.encoding=GBK" "-Dsun.stdout.encoding=GBK" "-Dsun.stderr.encoding=GBK" com.stu.Main
中文测试
sun.stdout.encoding = GBK
sun.stderr.encoding = GBK
      file.encoding = GBK
    native.encoding = GBK

Gradle no config PowerShell GBK

tasks.withType(JavaExec::class.java) {
    val args:List<String> = ArrayList()
    //args.addLast("-Dsun.stdout.encoding=GBK")
    //args.addLast("-Dsun.stderr.encoding=GBK")
    //args.addLast("-Dfile.encoding=GBK")
    //args.addLast("-Dnative.encoding=GBK")
    this.jvmArgs = args
    println(this.jvmArgs)
}
> Task :runCode
锟斤拷锟侥诧拷锟斤拷
sun.stdout.encoding = null
sun.stderr.encoding = null
      file.encoding = UTF-8
    native.encoding = GBK

BUILD SUCCESSFUL in 1s
2 actionable tasks: 1 executed, 1 up-to-date

Gradle UTF-8 PowerShell GBK

tasks.withType(JavaExec::class.java) {
    val args:List<String> = ArrayList()
    args.addLast("-Dsun.stdout.encoding=UTF-8")
    args.addLast("-Dsun.stderr.encoding=UTF-8")
    args.addLast("-Dfile.encoding=UTF-8")
    args.addLast("-Dnative.encoding=UTF-8")
    this.jvmArgs = args
//  val args = this.jvmArgs

//    args?.addLast("-Dsun.stdout.encoding=utf8")
//    args?.addLast("-Dsun.stderr.encoding=utf8")
//    this.jvmArgs = args;
    println(this.jvmArgs)
}
> Task :runCode
涓枃娴嬭瘯
sun.stdout.encoding = UTF-8
sun.stderr.encoding = UTF-8
      file.encoding = UTF-8
    native.encoding = GBK

BUILD SUCCESSFUL in 687ms
2 actionable tasks: 1 executed, 1 up-to-date

Gradle GBK PowerShell GBK

tasks.withType(JavaExec::class.java) {
    val args:List<String> = ArrayList()
    args.addLast("-Dsun.stdout.encoding=GBK")
    args.addLast("-Dsun.stderr.encoding=GBK")
    args.addLast("-Dfile.encoding=GBK")
    args.addLast("-Dnative.encoding=GBK")
    this.jvmArgs = args
//  val args = this.jvmArgs

//    args?.addLast("-Dsun.stdout.encoding=utf8")
//    args?.addLast("-Dsun.stderr.encoding=utf8")
//    this.jvmArgs = args;
    println(this.jvmArgs)
}
> Task :runCode
锟斤拷锟侥诧拷锟斤拷
sun.stdout.encoding = GBK
sun.stderr.encoding = GBK
      file.encoding = GBK
    native.encoding = GBK

BUILD SUCCESSFUL in 693ms
2 actionable tasks: 1 executed, 1 up-to-date

So “Java GBK PowerShell GBK” and “Java GBK PowerShell UTF-8” worked properly.
With Gradle you only considered one of two Javas, the one that is used to execute your app.
Maybe it works if you set it for the Java Gradle runs with, for example via org.gradle.jvmargs.
Maybe that is even the only one you need to set.

Use Gradle GBK PowerShell GBK still garbled code,I think this should be a correct parameter, but it’s still garbled. Is there anything else I can offer you, or other solutions, or can we find the core of the problem

It seems you need different properties at different places for it to work nicely together.
With

  • chcp 936
  • -Dfile.encoding=GBK for the Gradle daemon
  • -Dsun.stdout.encoding=GBK for the JavaExec task it works as expected

To test, I added also some output like in Main to the build script.
One caveat seems, that setting file.encoding in gradle.properties or als via -D as org.gradle.jvmargs is not working as needed.
But I used the JAVA_TOOL_OPTIONS to set the file.encoding and then to test whether it has an influence another value for the JavaExec so that not GBK is used.

The output is the expected:

> Task :runCode
from build script: 中文测试
from build script: sun.stdout.encoding = null
from build script: sun.stderr.encoding = null
from build script:       file.encoding = GBK
from build script:      defaultCharset = GBK
from build script:     native.encoding = Cp1252
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=GBK
from main: 中文测试
from main: sun.stdout.encoding = GBK
from main: sun.stderr.encoding = null
from main:       file.encoding = ISO-8859-1
from main:      defaultCharset = ISO-8859-1
from main:     native.encoding = Cp1252

The same also works for setting all three relevant places to UTF-8.
Then the problem is just - at least for me - that the font that PowerShell uses does not have the necessary characters available.
You can see that with a correct output shown and doing chcp 65001 which at least for me changes the font and makes the characters unreadable unless switched back to chcp 936.
But I guess just selecting a font that is capable to display those characters would then also work.

Is this the configuration?·

java -version
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=GBK -Dsun.stdout.encoding=GBK -Dsun.stderr.encoding=GBK
java version "21.0.2" 2024-01-16 LTS
Java(TM) SE Runtime Environment (build 21.0.2+13-LTS-58)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.2+13-LTS-58, mixed mode, sharing)

After configuring, I found that the Powershell Gradle runtime interface is not garbled, but the execution result of JavaExec is still garbled

测试CodeUTF-8
[-Dsun.stdout.encoding=UTF-8, -Dsun.stderr.encoding=UTF-8]

> Task :runCode
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=GBK -Dsun.stdout.encoding=GBK -Dsun.stderr.encoding=GBK
娑擃厽鏋冨ù瀣槸
sun.stdout.encoding = UTF-8
sun.stderr.encoding = UTF-8
      file.encoding = UTF-8
    native.encoding = GBK
plugins {
    id("java")
}

tasks.register("runCode", JavaExec::class) {
    defaultCharacterEncoding = "UTF-8"

    println("测试Code" + defaultCharacterEncoding)

    mainClass = "com.stu.Main"
    classpath = sourceSets["main"].runtimeClasspath

    group = "Exec"
    description = "运行指定代码"
}

tasks.register("runStu") {
    for (sourceSetContainer in sourceSets) {
        println(sourceSetContainer)
    }

    println(sourceSets)
}

// tasks.withType<JavaCompile>().configureEach {

// }

tasks.withType(JavaExec::class.java) {
//    val args:List<String> = ArrayList()
//    args.addLast("-Dsun.stdout.encoding=GBK")
//    args.addLast("-Dsun.stderr.encoding=GBK")
//    args.addLast("-Dfile.encoding=GBK")
//    args.addLast("-Dnative.encoding=UTF-8")
//    this.jvmArgs = args
//  val args = this.jvmArgs

//    args?.addLast("-Dsun.stdout.encoding=utf8")
//    args?.addLast("-Dsun.stderr.encoding=utf8")
//    this.jvmArgs = args;
    println(this.jvmArgs)
}

Is there a problem with where I configured it?

The problem is, you follow first and second point, but not the third.
As you can see in your output, the sun.stdout.encoding is not set when running your code.
The JAVA_TOOL_OPTIONS also work for that process, as it works for all processes that are started, but you then overwrite it to UTF-8 by using defaultCharacterEncoding.

It seems that it’s still not very good

gradle runCode                                                                       
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=GBK -Dsun.stdout.encoding=GBK -Dsun.stderr.encoding=GBK                    

> Configure project :
[-Dsun.stdout.encoding=GBK, -Dsun.stderr.encoding=GBK, -Dfile.encoding=GBK]

> Task :runCode
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=GBK -Dsun.stdout.encoding=GBK -Dsun.stderr.encoding=GBK
涓枃娴嬭瘯
sun.stdout.encoding = GBK
sun.stderr.encoding = GBK
      file.encoding = GBK
    native.encoding = GBK
/*
 * This file was generated by the Gradle 'init' task.
 *
 * This is a general purpose Gradle build.
 * To learn more about Gradle by exploring our Samples at https://docs.gradle.org/8.5/samples
 */

plugins {
    id("java")
}

tasks.register("runCode", JavaExec::class) {
    //defaultCharacterEncoding = "GBK"

    // println("测试Code" + defaultCharacterEncoding)

    mainClass = "com.stu.Main"
    classpath = sourceSets["main"].runtimeClasspath

    group = "Exec"
    description = "运行指定代码"
}

// tasks.register("runStu") {
//     for (sourceSetContainer in sourceSets) {
//         println(sourceSetContainer)
//     }

//     println(sourceSets)
// }

// tasks.withType<JavaCompile>().configureEach {

// }

tasks.withType(JavaExec::class.java) {
   val args:List<String> = ArrayList()
   args.addLast("-Dsun.stdout.encoding=GBK")
   args.addLast("-Dsun.stderr.encoding=GBK")
   args.addLast("-Dfile.encoding=GBK")
//    args.addLast("-Dnative.encoding=UTF-8")
    this.jvmArgs = args
//  val args = this.jvmArgs

//    args?.addLast("-Dsun.stdout.encoding=utf8")
//    args?.addLast("-Dsun.stderr.encoding=utf8")
//    this.jvmArgs = args;
    println(this.jvmArgs)
}

Is there any way to debug this issue。。。。。。。

I have no idea.
I can just say it worked here as expected when setting the codepage for PowerShell, the file.encoding for the Gradle daemon and the sun.stdout.encoding for the JavaExec task as I showed with the output.
Maybe also add this outputting of the String in question and the properties to the build script like I did to see what it prints there.
And make sure that did a ./gradlew --stop or used --no-daemon, so that a new process is started which picks up the JAVA_TOOL_OPTIONS, otherwise maybe an existing daemon is reused where it is not set properly.