I'm using JDK 21, that has the file.encoding
automatically to UTF-8 but, even adding it explicitly as a command argument, nothing changes. I checked the property in the code and it is indeed UTF-8.
I've set sun.stdout.encoding
to UTF-8 manually too. It changes the output, but still unreadable.
Printing the emoji 🤣 on System.out with the sun.stdout
the result is -fñú and without it, it just shows a ?
On another post I saw people suggesting to change the terminal code page or use the System.console().writer
instead of System.out
, but neither worked for me
The source is being encoded with UTF-8 properly too
After several days of research, I found two ways to enable UTF-8 support in Java console applications:
JLine is a library designed to enhance the terminal experience in Java, providing support for features that previously required native code. One of the cases where this applies is UTF-8 support.
The JLine library includes a class called Terminal
, which provides a PrintWriter
accessible through the writer()
method. This implementation automatically supports UTF-8
for any terminal compatible with the library, making it the best solution I found.
To use JLine on Windows, you may need to include the JNI dependency. For those using Maven, here are the dependencies I'm using on pom.xml
, but the most import are jline-terminal
and jline-terminal-jni
:
<!-- https://mvnrepository.com/artifact/org.jline/jline-terminal -->
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline-terminal</artifactId>
<version>${jline.bundle.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jline/jline-terminal-jni -->
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline-terminal-jni</artifactId>
<version>${jline.bundle.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jline/jline-native -->
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline-native</artifactId>
<version>${jline.bundle.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jline/jline-console -->
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline-console</artifactId>
<version>${jline.bundle.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jline/jline-style -->
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline-style</artifactId>
<version>${jline.bundle.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jline/jline-reader -->
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline-reader</artifactId>
<version>${jline.bundle.version}</version>
</dependency>
Depending on the terminal you are using, there are different commands you can execute before starting your application to enable UTF-8 support on Windows. For example, as mentioned by some users in the comments:
[Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
chcp 65001
By using these methods, you can ensure that your Java console application handles UTF-8 characters correctly.
If it doesn't work, in older versions of Java the file.encoding
flag wasn't set to UTF-8
by default, so you can try running your application setting it to UTF-8
and checking if it gives you the correct result:
java -Dfile.encoding=UTF-8 MyApp