概要

AntでのJavaコードコンパイルにError Proneを使用して、ソースコード解析を強化します。

サンプルターゲット

  • 以下、Installationに記述されているbuild.xmlを参考に作成したターゲットのサンプル
  • 公式のbuild.xmlをほぼ丸写しで動作可能だが、2つほど注意点がある
    • xmlns:unless="ant:unless"をルート要素に追加する必要がある
    • <javaversion>コンディションを使用しているので、ant1.10.2以上を使用する必要がある
<?xml version="1.0" encoding="UTF-8"?>
<project name="example" default="compile" xmlns:if="ant:if" xmlns:unless="ant:unless">
...
  <path id="project.class.path">
    <pathelement location="${build.dest}" />
    <pathelement location="${java.home}/lib/javaws.jar" />
    <pathelement path="${java.class.path}" />
  </path>
  <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}"
           debug="${compile.debug}"
           optimize="${compile.optimize}"
           deprecation="${compile.deprecation}"
           fork="yes"
           includeAntRuntime="no"
           classpathref="project.class.path">
      <include name="**/*.java" />
      <exclude name="**/module-info.java" if:set="jdk9orlater" />
      <compilerarg value="-J-Xbootclasspath/p:${javac.jar}" unless:set="jdk9orlater"/>
      <compilerarg value="-XDcompilePolicy=simple"/>
      <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>

解説

  1. Installationに記述されているerror_prone_core-2.3.2-with-dependencies.jarjFormatString-3.0.0.jarjavac-9+181-r4173-1.jarをダウンロードし、適当な(例えば環境変数ERRORPRONE_HOMEを設定した)場所に配置する
  2. 上記のようなerrorproneターゲットをbuild.xmlに追加する、またはcomplieターゲットの<javac>を置き換えてコンパイルする

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

Error Prone 2.4.0

  • Ant + Error Prone 2.4.0で以下のような例外が発生する?
    • ThreeTen-Extra - HomeReleasesDownloadから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)

文字化け

  • 環境変数ANT_OPTSなどに-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8を設定してもcygwinbash(Character setUTF-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個

参考リンク

コメント