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


いいなと思ったら応援しよう!