はじめに
Java 18 からJEP 400: UTF-8 by Defaultにより、デフォルトのエンコーディングが UTF-8 に統一されたため、Windows 環境での文字化けが頻出する。
対策としては、全て UTF-8 に統一してやるのが良い。
- ソースコードを UTF-8 とする
- システムプロパティ
file.encoding
を UTF-8 とする - システムプロパティ
sun.stdout.encoding
とsun.stderr.encoding
を UTF-8 とする - ターミナルを UTF-8 とする
システムプロパティの設定
システムプロパティの値は以下で確認できる。
public static void main(String[] args) { System.out.println("Java Runtime version :" + System.getProperty("java.runtime.version")); System.out.println("Charset.defaultCharset() :" + Charset.defaultCharset()); System.out.println("----------------------------------------------"); System.out.println("\"file.encoding\" = " + System.getProperty("file.encoding")); System.out.println("\"native.encoding\" = " + System.getProperty("native.encoding")); System.out.println("\"sun.jnu.encoding\" = " + System.getProperty("sun.jnu.encoding")); 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("----------------------------------------------"); System.out.println("あいうえお"); }
Windows10 環境において、Gradle で作成したアプリケーションプロジェクトを、特別な設定無く ./gradlew run
した場合以下の出力となる。
Java Runtime version :21+35-LTS Charset.defaultCharset() :UTF-8 ---------------------------------------------- "file.encoding" = UTF-8 "native.encoding" = MS932 "sun.jnu.encoding" = MS932 "sun.stdout.encoding" = null "sun.stderr.encoding" = null ---------------------------------------------- ・ス・ス・ス・ス・ス・ス・ス・ス・ス・ス
sun.stdout.encoding
と sun.stderr.encoding
は、設定が無い場合は native.encoding
の値がそのまま使われる。
Windows Terminal(PowerShell)では、以下のように JAVA_TOOL_OPTIONS
を設定できる。
$ENV:JAVA_TOOL_OPTIONS = '-Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8'
システムプロパティで native.encoding
は上書き設定できなかったので、sun.*
は非公式オプションだが、こちらを設定。
この状態で実行ると以下の様になる。
> ./gradlew run Picked up JAVA_TOOL_OPTIONS: -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 Java Runtime version :21+35-LTS Charset.defaultCharset() :UTF-8 ---------------------------------------------- "file.encoding" = UTF-8 "native.encoding" = MS932 "sun.jnu.encoding" = MS932 "sun.stdout.encoding" = UTF-8 "sun.stderr.encoding" = UTF-8 ---------------------------------------------- 縺ゅ>縺・∴縺・
なお、Gradle アプリケーションの場合は以下のように指定することもできる。
application { mainClass.set("xxx") applicationDefaultJvmArgs = listOf("-Dsun.stdout.encoding=UTF-8", "-Dsun.stderr.encoding=UTF-8") }
ターミナルの設定
ターミナルのコード ページが MS932 となっている場合、
> chcp 現在のコード ページ: 932
UTF-8
に変更する。
> chcp 65001 Active code page: 65001
実行すれば「あいうえお」が表示される。
> ./gradlew run Picked up JAVA_TOOL_OPTIONS: -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 Java Runtime version :21+35-LTS Charset.defaultCharset() :UTF-8 ---------------------------------------------- "file.encoding" = UTF-8 "native.encoding" = MS932 "sun.jnu.encoding" = MS932 "sun.stdout.encoding" = UTF-8 "sun.stderr.encoding" = UTF-8 ---------------------------------------------- あいうえお
file.encoding=COMPAT
JEP 400: UTF-8 by Default により、file.encoding=COMPAT
とすることで従来互換となる。
ソースファイルは UTF-8 とし、コンパイル時のエンコーディングは以下のように指定し、
tasks.withType<JavaCompile> {
options.encoding = Charsets.UTF_8.name()
}
以下の指定とすることで、
> $ENV:JAVA_TOOL_OPTIONS = '-Dfile.encoding=COMPAT' > chcp 932
以下のように実行することもできる。
> ./gradlew run Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=COMPAT Java Runtime version :21+35-LTS Charset.defaultCharset() :windows-31j ---------------------------------------------- "file.encoding" = windows-31j "native.encoding" = MS932 "sun.jnu.encoding" = MS932 "sun.stdout.encoding" = null "sun.stderr.encoding" = null ---------------------------------------------- あいうえお
まとめ
Java 18 からは、デフォルトのエンコーディングが UTF-8 となったことで、Windows 環境では文字化けが発生しがちである。
全て UTF-8 に統一しておくのが吉である。
> $ENV:JAVA_TOOL_OPTIONS = '-Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8' > chcp 65001 > ./gradlew run