Java 6APIを使用したソースコード分析
シーマ・リチャード、ディーパ・ソバナ
CheckstyleやFindBugsなどのツールが静的コード分析を実行する方法や、NetBeansやEclipseなどの統合開発環境(IDE)が迅速なコード修正を実行する方法、またはコードで宣言されたフィールドの正確な参照を見つける方法について考えたことはありますか?多くの場合、IDEには独自のAPIがあり、ソースコードを解析して、抽象構文木(AST)または「解析ツリー」と呼ばれる標準のツリー構造を生成します。これはソース要素のより深い分析に使用できます。幸いなことに、Java Standard Edition 6リリースの一部としてJavaに導入された3つの新しいAPIの助けを借りて、前述のタスクに加えてさらに多くのタスクを実行できるようになりました。ソースコード分析を実行する必要があるJavaアプリケーションの開発者が関心を持つ可能性のあるAPIは、JavaコンパイラAPI(JSR 199)です。Pluggable Annotation Processing API(JSR 269)、およびコンパイラツリーAPI。
この記事では、これらの各APIの機能を調べ、入力として提供される一連のソースコードファイルで特定のJavaコーディングルールを検証する簡単なデモアプリケーションの開発に進みます。このユーティリティは、コーディング違反メッセージと違反したソースコードの場所も出力として表示します。Objectクラスのequals()メソッドをオーバーライドする単純なJavaクラスについて考えてみます。検証するコーディング規則は、equals()メソッドを実装するすべてのクラスも、hashcode()メソッドを適切な署名でオーバーライドする必要があるということです。以下のTestClassクラスは、equals()メソッドを持っていても、hashcode()メソッドを定義していないことがわかります。
public class TestClass implements Serializable { int num; @Override public boolean equals(Object obj) }
これらの3つのAPIを使用して、ビルドプロセスの一部としてこのクラスを分析します。
コードからのコンパイラーの呼び出し:JavaコンパイラーAPI
私たちは皆、javac
Javaソースファイルをクラスファイルにコンパイルするためにコマンドラインツールを使用しています。では、なぜJavaファイルをコンパイルするためのAPIが必要なのですか?答えは非常に簡単です。名前が示すように、この新しい標準APIを使用すると、独自のJavaアプリケーションからコンパイラーを呼び出すことができます。つまり、プログラムでコンパイラーと対話し、それによってコンパイルをアプリケーションレベルのサービスの一部にすることができます。このAPIのいくつかの典型的な使用法を以下に示します。
コンパイラAPIは、たとえば、JSPページから生成されたサーブレットソースをコンパイルするために外部コンパイラを使用するオーバーヘッドを回避することにより、アプリケーションサーバーがアプリケーションのデプロイにかかる時間を最小限に抑えるのに役立ちます。
IDEやコードアナライザーなどの開発者ツールは、エディター内からコンパイラーを呼び出したり、コンパイル時間を大幅に短縮するツールを構築したりできます。
Javaコンパイラクラスはパッケージの下にjavax.tools
パッケージ化されています。ToolProvider
このパッケージのクラスはgetSystemJavaCompiler()
、JavaCompiler
インターフェイスを実装するクラスのインスタンスを返すと呼ばれるメソッドを提供します。このコンパイラインスタンスを使用して、実際のコンパイルを実行するコンパイルタスクを作成できます。コンパイルされるJavaソースファイルは、コンパイルタスクに渡されます。このため、コンパイラAPIは、と呼ばれるファイルマネージャの抽象化を提供しますJavaFileManager
。これにより、ファイルシステム、データベース、メモリなどのさまざまなソースからJavaファイルを取得できます。このサンプルではStandardFileManager
、に基づくファイルマネージャーであるを使用しますjava.io.File
。標準のファイルマネージャは、のgetStandardFileManager()
メソッドを呼び出すことで取得できます。JavaCompiler
インスタンス。上記の手順のコードスニペットを以下に示します。
//Get an instance of java compiler JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); //Get a new instance of the standard file manager implementation StandardJavaFileManager fileManager = compiler. getStandardFileManager(null, null, null); // Get the list of java file objects, in this case we have only // one file, TestClass.java Iterable compilationUnits1 = fileManager.getJavaFileObjectsFromFiles("TestClass.java");
オプションで、診断リスナーをgetStandardFileManager()
メソッドに渡して、致命的でない問題の診断レポートを作成できます。このコードスニペットではnull
、ツールから診断を収集していないため、値を渡します。これらのメソッドに渡されるその他のパラメーターの詳細については、Java 6APIを参照してください。のgetJavaFileObjectsfromFiles()
メソッドは、提供されたJavaソースファイルに対応するStandardJavaFileManager
すべてのJavaFileObject
インスタンスを返します。
この記事の残りの部分を読む
このストーリー「Java6APIを使用したソースコード分析」は、もともとJavaWorldによって公開されました。