Hudson の Git Plugin を使うと文字化けする問題とその解決方法 (不完全)

こちらも仕事で Hudson と Git を使い始めた頃から気付いたんですが、ちょうどいい機会なので直してみます。
文字化けするのは、Hudson の Web 画面から確認できるコミットメッセージです。

始める前に

ここで紹介する方法は、プラグインのクラスファイルの一部を入れ替える方法です。
あくまでその場しのぎの解決方法であることを理解したうえで、この方法を実行する場合は自己責任でお願いします。

調査

まず、本来あるべきコードと、認識されているコードを調査しました。

Googleの文字化け・まとめ(文字化けパターン)

上のページによると、UTF-8 なのに Shift_JIS として認識しているようです。
Git でのデフォルトのコミットメッセージは UTF-8 なので、これを読み込む際に間違ったエンコード方式を指定している可能性が濃厚です。


そこで、Git plugin のコード*1 *2を落としてコミットメッセージを読み込んでいる部分を探しました。

原因

文字化けの原因は、GitChangeLogParser クラスでファイルの読み込みに FileReader クラスを使っていることでした。
FileReader クラスは手軽にファイル読み込みができますが、読み込む際のエンコーディングは指定できず、常にシステムのデフォルトエンコーディングが使用されます。
このため、Windows で Hudson を動かし、さらに Git まで使っているという変態構成だと、ファイルのエンコーディングUTF-8 であっても MS932 を使ってしまい、文字化けが発生していました。


これを回避するためには、i18n.commitencoding を Shift_JIS にすることも考えられるのですが、すでに utf-8 で運用しているため、できればこれは避けたいです。

GitChangeLogParser.java の修正

本来なら、リポジトリのコミットメッセージのエンコーディング方式を設定出来るように修正するのが一番なのですが、Hudson で Plugin を作ったことがないため、手っ取り早い方法を取りました。
自分が使っているリポジトリi18n.commitencoding はすべてデフォルト状態、つまり utf-8 なので、FileReader を使わず、InputStreamReader と FileInputStream を組み合わせて utf-8 で読み込むようにしました。

BufferedReader rdr = null;
try {
    rdr = new BufferedReader(new InputStreamReader(new FileInputStream(changelogFile), "utf-8"));
    ...
} finally {
    if (rdr != null) rdr.close();
}

try の外側で BufferedReader と FileReader を new していた部分も、try の中で行うように変更しています。
また、import も変更しています。


後はこれをコンパイルして Hudson をインストールした場所にある plugins/git/WEB-INF/classes/hudson/plugins/git に生成された .class ファイルをコピーすればいい・・・のですが、NUnit Plugin の場合と違ってこちらは hudson.model.AbstractBuild と hudson.scm.ChangeLogParser というクラスを使用しているので、その辺もよろしくやってあげる必要があります。
使用している hudson.war から hudson-core-バージョン.jar を取り出し、src\main\java に置きます。

javac -cp hudson-core-1.355.jar hudson\plugins\git\GitChangeSet.java hudson\plugins\git\GitChangeSetList.java hudson\plugins\git\GitChangeLogParser.java

とするとコンパイルできました*3


これで、コミットメッセージが文字化けせずに表示されるようにな・・・ると思ったのですが、微妙に化けてしまいます。
jobs フォルダの中の「プロジェクト名\builds\ビルド日時\changelog.xml」を utf-8 で開いてみると、どこかで変換にミスっているのか、? という文字が目立ちます。
この changelog.xml をどこで出力しているのかわからないので、これ以上は分かりませんでした*4

*1:https://hudson.dev.java.net/svn/hudson/trunk/hudson/plugins/git/

*2:Github にもコードがあるらしい。http://github.com/magnayn/Hudson-GIT-plugin

*3:これはバージョンが 1.355 の場合です

*4:Git plugin の中を FileWriter とか BufferedWriter で検索したけど見つからなかった