torutkのブログ

ソフトウェア・エンジニアのブログ

JenkinsのWarnings pluginがantで実行するjavacの警告を拾わない

Jenkinsのプラグインに、コンパイラの警告を集計してくれる"Warnings plugin"があります。日本語の文献でも紹介されています。コンパイラの警告を放置する人が多いので、Jenkinsで集計して可視化できるといいなと導入してみました。しかし、常に0件、コンパイラの出す警告メッセージを拾うことができません。パーサーで選択したのは"Java Compiler (javac)"です。Antが見当たらないので、これを選びました*1

javac(JDK 8)のコンパイルメッセージを一部抽出してみます。

$ javac -d build/classes -encoding utf8 src/music/album/Artist.java
注意:src\music\album\Artist.javaは非推奨のAPIを使用またはオーバーライドしています。
注意:詳細は、-Xlint:deprecationオプションを指定して再コンパイルしてください。
注意:src\music\album\Artist.javaの操作は、未チェックまたは安全ではありません。
注意:詳細は、-Xlint:uncheckedオプションを指定して再コンパイルしてください。

おや、「警告」という文字が出ると思いきや、「注意」でした。メッセージにあるように、-Xlint:xxxxオプションを追加してみましょう。

$ javac -Xlint:deprecation -Xlint:unchecked -d build/classes -encoding utf8 src
/music/album/Artist.java 
src\music\album\Artist.java:65: 警告: [deprecation] DateのgetDate()は非推奨になりました
        int d = new Date().getDate();
                          ^
src\music\album\Artist.java:67: 警告: [unchecked] raw型Listのメンバーとしてのadd(E)への無検査呼出しです
        list.add("Warning?");
                ^
  Eが型変数の場合:
    インタフェース Listで宣言されているEはObjectを拡張します
警告2個

こちらだと「警告」という文字が出てきます。しかし、Jenkins上でWarnings pluginは拾うことが出来ません*2

いろいろ調べてみたところ、"Java Compiler (javac)" ではどうやらAntのメッセージを正しく解析できないと思われます。
Warnings pluginのこのソースがたぶん"Java Compiler (javac)"と思われますが、警告の文字列が[WARNING]決め打ちです。
次の2つのソースコードが"Java Compiler (javac)"で適用されます。前者はjavacが直接出力するメッセージの解析、後者がAntのjavacタスクが出力するメッセージの解析に使われます。

https://github.com/jenkinsci/warnings-plugin/blob/master/src/main/java/hudson/plugins/warnings/parser/JavacParser.java

String JAVAC_WARNING_PATTERN = "^(?:\\[WARNING\\]\\s+)?([^\\[]*):\\[(\\d+)[.,;]*(\\d+)?\\]\\s*(?:\\[(\\w+)\\])?\\s*(.*)$";

Warnings pluginのソースを見て回ったところ、AntJavaParser.javaなるソースがありました。
https://github.com/jenkinsci/warnings-plugin/blob/master/src/main/java/hudson/plugins/warnings/parser/AntJavacParser.java

ANT_JAVAC_WARNING_PATTERN = ANT_TASK
+ "\\s*(.*java):(\\d*):\\s*(?:warning|\u8b66\u544a)\\s*:\\s*(?:\\[(\\w*)\\])?\\s*(.*)$"
+ "|^\\s*\\[.*\\]\\s*warning.*\\]\\s*(.*\"(.*)\".*)$"
+ "|^(.*class)\\s*:\\s*warning\\s*:\\s*(.*)$";

これなら拾えそうです(\u8b66\u5444aは、「警告」)。

このAntJavaParserがパーサー一覧から選択できればいいのですが、現時点ではそうなっていないみたいなので、自前でパーサー定義をして回避します。

いちおう、Jenkins Warnings pluginのバグになるかと思い、Jenkinsにアカウントを新規に作ってバグを登録してみました。
https://issues.jenkins-ci.org/browse/JENKINS-24611

自前で正規表現でパーサーを定義

以下は、自前でパーサーを定義する場合の手順です。

[Jenkinsの管理] > [システムの設定] でスクロールダウンしていくと「コンパイラの警告」があります。パーサーの[追加]ボタンを押して新たなパーサーを定義します。

  • 名前: Java Compiler(Ant)
  • リンク名: javac_ant
  • 推移レポート名: javac_ant_warnings
  • 正規表現
^\s*\[\w*\]\s*(.*java):(\d+):\s*(?:warning|\u8b66\u544a):\s*(.*)$
import hudson.plugins.warnings.parser.Warning

String fileName = matcher.group(1)
String lineNumber = matcher.group(2)
String message = matcher.group(3)

return new Warning(fileName, Integer.parseInt(lineNumber), "Dynamic Parser", "Warning", message);

として、プロジェクトの設定でパーサーを上記で定義したものに変えてみたところ、警告がカウントされるようになりました。

*1:バグレポートでのやり取りにおいて、Antからjavacを実行する場合、これで正解とのことです。

*2:バグレポートでのやり取りにおいて、問題となるのはWindows日本語環境で、Linux日本語環境では警告を拾うことができていました