---
title: AntでError Proneを使用する
author: aterai
pubdate: 2018-10-27T20:57:37+09:00
description: AntでのJavaコードのコンパイラにコード解析を行うErrprProneを適用する方法など。
---
#contents

* 概要 [#summary]
`Ant`での`Java`コードコンパイルに`Error Prone`を使用して、ソースコード解析を強化します。

* サンプルターゲット [#target]
- 以下、[https://errorprone.info/docs/installation#ant Installation]に記述されている[https://github.com/google/error-prone/blob/master/examples/ant/build.xml build.xml]を参考に作成したターゲットのサンプル
- 公式の`build.xml`をほぼ丸写しで動作可能だが、`2`つほど注意点がある
-- `xmlns:unless="ant:unless"`をルート要素に追加する必要がある
-- `<javaversion>`コンディションを使用しているので、`ant`は`1.10.2`以上を使用する必要がある
--- [https://archive.apache.org/dist/ant/RELEASE-NOTES-1.10.2.html Release Notes of Apache Ant 1.10.2]
--- `sdkman`で`ant`をインストールすると、`2018-10-27`現在の最新は`1.10.1`なのでエラーになる

#code{{
<?xml version="1.0" encoding="UTF-8"?>
<project name="example" default="compile" xmlns:if="ant:if" xmlns:unless="ant:unless">
...
<target name="errorprone" depends="prepare-src">
  <!-- using github.com/google/error-prone-javac is required when running on JDK 8 -->
  <property name="javac.jar" location="${env.ERRORPRONE_HOME}/javac-9+181-r4173-1.jar" />
  <path id="processorpath.ref">
    <fileset dir="${env.ERRORPRONE_HOME}">
      <include name="*.jar" />
      <exclude name="error_prone_core-2.10.0-with-dependencies.jar" if:set="jdk9orlater" />
      <exclude name="javac-9+181-r4173-1.jar" if:set="jdk9orlater" />
      <exclude name="jFormatString-3.0.0.jar" if:set="jdk9orlater" />
    </fileset>
  </path>
  <javac srcdir="${build.src}"
         destdir="${build.dest}"
         encoding="${compile.encoding}"
         fork="yes"
         includeAntRuntime="no">
    <include name="**/*.java" />
    <exclude name="**/module-info.java" unless:set="jdk9orlater" />
    <compilerarg value="-J-Xbootclasspath/p:${javac.jar}" unless:set="jdk9orlater" />
    <compilerarg value="-XDcompilePolicy=simple" />
    <compilerarg value="--should-stop=ifError=FLOW" if:set="jdk9orlater" />
    <compilerarg value="-processorpath" />
    <compilerarg pathref="processorpath.ref" />
    <compilerarg value="-Xplugin:ErrorProne -Xep:DeadException:ERROR -Xep:MultipleTopLevelClasses:OFF" />
    <compilerarg value="-J-Dfile.encoding=UTF-8" />
    <compilerarg value="-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED" if:set="jdk9orlater" />
    <compilerarg value="-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED" if:set="jdk9orlater" />
    <compilerarg value="-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED" if:set="jdk9orlater" />
    <compilerarg value="-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED" if:set="jdk9orlater" />
    <compilerarg value="-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED" if:set="jdk9orlater" />
    <compilerarg value="-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED" if:set="jdk9orlater" />
    <compilerarg value="-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED" if:set="jdk9orlater" />
    <compilerarg value="-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" if:set="jdk9orlater" />
    <compilerarg value="-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED" if:set="jdk9orlater" />
    <compilerarg value="-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED" if:set="jdk9orlater" />
    <compilerarg value="--add-exports=java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED" if:set="jdk9orlater" />
  </javac>
</target>
}}

* 解説 [#explanation]
+ [https://errorprone.info/docs/installation#ant Installation]に記述されている`error_prone_core-x.x.x-with-dependencies.jar`、`jFormatString-3.0.0.jar`、`javac-9+181-r4173-1.jar`をダウンロードし、適当な(例えば環境変数`ERRORPRONE_HOME`を設定した)場所に配置する
-- `2.10.0`以降の場合は`error_prone_core-x.x.x-with-dependencies.jar`と`dataflow-errorprone-3.42.0-eisop4.jar`(`google-java-format-1.24.0.jar`が必要になる場合もある?)
+ 上記のような`errorprone`ターゲットを`build.xml`に追加する、または`complie`ターゲットの`<javac>`を置き換えてコンパイルする

----
- 例えば`MultipleTopLevelClasses`をチェックしないように設定する場合は、以下のように`-Xep:MultipleTopLevelClasses:OFF`を引数に追加する
-- `<compilerarg value="-Xplugin:ErrorProne -Xep:DeadException:ERROR -Xep:MultipleTopLevelClasses:OFF -Xep:CatchAndPrintStackTrace:OFF" />`
-- [https://errorprone.info/docs/flags Command-line flags]

** Error Prone 2.35.1 [#i7157002]
- `Java 21.0.5` + `Ant 1.10.15` + `Error Prone 2.35.1`で実行すると`java.lang.NoClassDefFoundError: com/google/googlejavaformat/java/FormatterException`とエラーになる
-- [https://github.com/google/google-java-format GitHub - google/google-java-format: Reformats Java source code to comply with Google Java Style.]から`google-java-format-1.24.0.jar`をダウンロードして`error_prone_core-2.35.1-with-dependencies.jar`と同じディレクトリに配置すると解消する?
- `2.36.0`では`error_prone_core-2.36.0-with-dependencies.jar`に`com/google/googlejavaformat/java/`が含まれるようになってエラーは解消した
- [https://github.com/google/error-prone/pull/4633 Bundle google-java-format in the with-dependencies JAR by lgemeinhardt · Pull Request #4633 · google/error-prone]
-- `2.36.0`では`error_prone_core-2.36.0-with-dependencies.jar`に`com/google/googlejavaformat/java/`が含まれるようになってエラーは解消した

** Error Prone 2.10.0 [#g447c785]
- `Java 8`で実行可能なバージョンは`2.10.0`までで、現在のバージョンは`Java 17`以降で実行する必要がある

** Error Prone 2.4.0 [#md1bf1ec]
- `Ant` + `Error Prone 2.4.0`で以下のような例外が発生する?
-- [https://www.threeten.org/threeten-extra/ ThreeTen-Extra - Home]の`Releases`、`Download`から`threeten-extra-1.5.0.jar`をダウンロードしてクラスパス(上記の`build.xml`の場合`${env.ERRORPRONE_HOME}`に設定したディレクトリ)に配置すれば解消する

 An unhandled exception was thrown by the Error Prone static analysis plugin.
    [javac]      Please report this at https://github.com/google/error-prone/issues/new and include the following:
    [javac]
    [javac]      error-prone version: 2.4.0
    [javac]      BugPattern: (see stack trace)
    [javac]      Stack Trace:
    [javac]      java.lang.NoClassDefFoundError: org/threeten/extra/AmPm
    [javac]     at com.google.errorprone.bugpatterns.time.FromTemporalAccessor.<clinit>(FromTemporalAccessor.java:103)
    [javac]     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    [javac]     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    [javac]     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    [javac]     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    [javac]     at com.google.errorprone.scanner.ScannerSupplierImpl.instantiateChecker(ScannerSupplierImpl.java:84)

** 文字化け [#t71a6b89]
- 環境変数`ANT_OPTS`などに`-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8`を設定しても`cygwin`の`bash`(`Character set`は`UTF-8`)で文字化けする
-- `PMD`などの出力は正常
-- `javac`タスクの`encoding`を指定しても効果なし

 errorprone:
     [javac] Compiling 1 source file to C:\jst\ComboBoxItemCopy\target\classes
     [javac] C:\jst\ComboBoxItemCopy\target\src\example\MainPanel.java:105: �x��:[CatchAndPrintStackTrace] Logging or 
 rethrowing exceptions should usually be preferred to catching and calling printStackTrace
     [javac]       ex.printStackTrace();
     [javac]       ^
     [javac]     (see https://errorprone.info/bugpattern/CatchAndPrintStackTrace)
     [javac] �x��1��

- `javac`タスクの子要素に`<compilerarg value="-J-Dfile.encoding=UTF-8" />`を追加すると文字化けは解消された
-- コンソール出力には`<compilerarg value="-J-Dsun.jnu.encoding=UTF-8" />`が効きそうだが、なぜか効果なし

 errorprone:
     [javac] Compiling 1 source file to C:\jst\ComboBoxItemCopy\target\classes
     [javac] C:\jst\ComboBoxItemCopy\target\src\example\MainPanel.java:105: 警告:[CatchAndPrintStackTrace] 
 Logging or rethrowing exceptions should usually be preferred to catching and calling printStackTrace
     [javac]       ex.printStackTrace();
     [javac]       ^
     [javac]     (see https://errorprone.info/bugpattern/CatchAndPrintStackTrace)
     [javac] 警告1個

* 参考リンク [#reference]
- [https://errorprone.info/ Error Prone]
- [https://github.com/google/error-prone google/error-prone: Catch common Java mistakes as compile-time errors]

* コメント [#comment]
#comment
#comment