NetBeansのコンソール文字化けの対処方法
柔軟に、エンコーディングを指定できるのが、JDK16以降なのですが、デフォルトのままだと、NetBeansで不整合がおきてしまいます。
JDK16 以降は、以下の非公式のJavaオプションが使えるようになっているそうです。
sun.stdout.encoding=UTF-8
sun.stderr.encoding=UTF-8
これが指定できると、WindowsのコンソールがShift_JIS、NetBeansのコンソールがUTF-8のはずで、個別対応できるということになります。
JDK17では、他に、native.encoding等も増えていますが、
それは、1ユーザーが、気楽に設定することはできない、読み取り専用の値のようです。
デフォルト設定のままだと、Windowsのコンソールも、NetBeansのコンソールも、どちらもnative.encodingに指定されたShift_JISで出力してしまいます。
NetBeansのコンソールはUTF-8しか受け付けないので、文字化けは不可避です。
JDK18以降は、sun.のなくなった、Javaオプションでも指定できるようになっています。
多分、sun.から始まっていないので、ここから公式オプションな気がします。
https://docs.oracle.com/javase/jp/20/docs/api/java.base/java/lang/System.html#getProperties()
stdout.encoding=UTF-8
stderr.encoding=UTF-8
NetBeans起動バッチの、launch.batを書いてみました。
JDK18以降を使ってる場合、NetBeansのコンソールにあわせるには、次のようにNetBeansを起動すればいいみたいです。
すると、コンソールのUTF-8が表示されます。(本体やAntなどです)
set JAVA_TOOL_OPTIONS=-Dstderr.encoding=UTF-8 -Dstdout.encoding=UTF-8
start C:\java\NetBeans-18\netbeans\bin\netbeans64.exe
ちなみに、CONFファイルでも指定できそうなので試してみましたが、こちらはダメでした。
C:\java\NetBeans-18\netbeans\etc\netbeans.conf
の該当行は以下です。
netbeans_default_options="-J ~ 中略 ~ -J-XX:+IgnoreUnrecognizedVMOptions"
この後ろダブルクォートの前に、次の修正を加えてみました、、
-J-Dstderr.encoding=UTF-8 -J-Dstdout.encoding=UTF-8
しかし、親プロセスは機能するのかもしれませんが。外部プロセスが継承しないのでダメでしたね。
かりに、システム環境変数を変えてしまった場合には、システムのコンソールが、UTF-8に対応していないため、逆に文字化けします。
結局のところ、バッチファイルなどで、NetBeans起動前に指定することになります。(希望を言えば、NetBeansのオプションで、コンソールの文字コードがUTF-8固定になっているのが、どうもよろしくない、というところではありますね。ここを変更可能にしてほしいなぁとは思っています。
(NetBeansはオープンソースなのです。。です。。)
ちなみに、コンパイル時の、日本語が文字化けする対処にはなっていますが、デバッグするアプリの文字化けの対処が、必要な場合があります。
Antを別プロセスで、Forkしてる場合などがそのようですね。通常は必要ないかもしれません。
アプリMainクラスから、次のstaticメソッドを呼ぶとよいようです。(JDK18)
stdout.encodingか、なければ、native.encodingで、指定された文字セットが、コンソールに設定されることを、つよく希望して、上書きさえしてしまうコードです。
public static void fixConsoleEncoding() {
try {
// for NetBeans + Ant
String targetCharset = System.getProperty("stdout.encoding");
if (targetCharset == null) {
targetCharset = System.getProperty("native.encoding");
}
if (targetCharset.equals(System.out.charset().toString())) {
System.out.println("Console Encoding Don't need fix.");
} else {
System.setOut(new PrintStream(System.out, true, targetCharset));
System.setErr(new PrintStream(System.err, true, targetCharset));
System.out.println("Console Encoding fixed.");
System.out.println("after overwrite System.out.charset() = " + System.out.charset());
System.out.println("after overwrite System.err.charset() = " + System.err.charset());
}
} catch (Throwable e) {
e.printStackTrace();
}
}
これで、Windowsのコンソールでは、native.encodingで指定された、Shift_JIS(MS-932、Windows-31J)で、System.setOut()が呼ばれます。
そして、NetBeansでは、stdout.encoding=UTF-8で指定しておいた、UTF-8で、System.setOut()が呼ばれます。
一件落着ですかね?
このノートでは、以下の値も参考にしています。
System.out.println("*ENV*JAVA_TOOL_OPTIONS=" + System.getenv("JAVA_TOOL_OPTIONS"));
System.out.println("*ENV*_JAVA_OPTIONS=" + System.getenv("_JAVA_OPTIONS"));
System.out.println("*ENV*LANG=" + System.getenv("LANG"));
System.out.println("*PROP*file.encoding = " + System.getProperty("file.encoding"));
System.out.println("*PROP*native.encoding = " + System.getProperty("native.encoding"));
System.out.println("*PROP*stdout.encoding = " + System.getProperty("stdout.encoding"));
System.out.println("*PROP*stderr.encoding = " + System.getProperty("stderr.encoding"));
System.out.println("*METHOD*Charset.defaultCharset() = " + Charset.defaultCharset());
System.out.println("*METHOD*System.out.charset() = " + System.out.charset());
今日はこんなかんじでまとめさせていだきました。
最後までご欄いただきありがとうございました。
参考にさせていだいたサイトです。こちらにもありがとうですね。
(Noteではない外部サイトです。)
https://qiita.com/nowokay/items/17d990aa8a5b1c5223c8
https://stackoverflow.com/questions/4896311/how-to-use-utf-8-character-in-netbeans