WindowsでClojureを使う際の文字化け
- Clojureと書くが…実はJVMの話だった(前置き)
- Windows10 + LeiningenでClojureのAPIを作っていると、
文字コードUTF-8を指定しているはずなのに実際にはShift-JISのままになっていて日本語が文字化け
する - DockerでMySQL DBを立てたりしてると
どっちに原因があるのか戸惑う
(余談)
原因がJVM optionsにある場合
今回はコレだった。WindowsでJVMを使っていると良くある?
(javaで起きている様子 https://teratail.com/questions/125729)
要するにJVMは、文字コードを指定しない場合は 環境変数などから得られた文字コード
を使うので、Windowsの場合はデフォルト文字コードである 例のShift-JISを選択してしまう…ということらしい。
参考 https://qiita.com/seraphy@github/items/98e2908b63af58ef0032
そんな状態を放置したまま、偶然 API開発で Pedestal
の http
の json-body
インターセプターを利用していたりすると大ダメージを受ける
※ pedestal.http/json-bodyはレスポンスをJSON変換するついでに ちゃっかり文字コードをUTF-8指定している
ので、Shift-JISだろうが何だろうが問答無用でUTF-8として返してしまう(そして文字化けする😇)
JVMの文字コード指定をしてどうにかする
Leiningenを使っている場合は、 project.clj
にjvm-options :jvm-opts
を追加することでJVM optionsを指定できる。
参考 https://stackoverflow.com/questions/25461955/leiningen-project-program-cant-output-non-ascii-string-in-windows
※ そしてこの参考リンクでは書き方が間違っている😇
たとえば :jvm-opts ["-Dfile.encoding" "UTF-8"]
と書こうとすると java.nio.charset.IllegalCharsetNameException
を引き起こす。
正しくは :jvm-opts ["-Dfile.encoding=UTF-8"]
今回はJVMがUTF-8を使っていなかった(Shift-JISだった)ことが原因だったので、 :jvm-opts ["-Dfile.encoding=UTF-8"]
を加えてファイルエンコーディングをUTF-8にすることで解決。
まとめ
-
Shift-JISじゃね?
と思ったらJVMが原因のこともある - Leiningenなら
project.clj
に:jvm-opts ["-Dfile.encoding=UTF-8"]
追加
※ 別解として ~/.lein/profiles.clj
(ドキュメント)に {:user {:jvm-opts ["-Dfile.encoding=UTF-8"]}}
と書いても良さそう(自分1人で使ってチームメンバーに影響を与えない運用とかするならそっちのが良さそう)