FaqAptJa

プロジェクトでアノテーションプロセッサを実行できますか?

はい、できますがいくつかの作業が必要です。

JDK 5 で注釈(アノテーション) とツール apt が導入されました。apt はプロジェクトから注釈をスキャンしコード生成やその他の動作を行います。

JDK 6 ではこのサポートは JSR 269 として拡張されアノテーションプロセッサーを記述できる正式な API として提供されています。apt ツールは必要ありません。javac が自動的にプロセッサーを実行します。

現在 NetBeans は直接はこのアノテーションプロセッサーを実行することはサポートしていませんが、これらをプロジェクトで実行するように設定することができます。以下に JDK6 での例をあげます。(JDK 5 では tools.jar に対してプロセッサーをコンパイルする必要がありまたアノテーションを使用しているプロジェクトとは別に apt を実行する必要があるため特殊です)

Java SE ライブラリプロジェクトを作成します。JDK 6 以上を使用してください。(プロジェクトの プロパティー ダイアログのライブラリで確認することができます) 以下のようにアノテーションを定義します。

package ann;
public @interface Handlable {}

プロセッサを作ります:

package proc;
import ann.Handlable;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
@SupportedAnnotationTypes("ann.Handlable")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class HandlableProcessor extends AbstractProcessor {
    /** public for ServiceLoader */
    public HandlableProcessor() {}
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (Element e : roundEnv.getElementsAnnotatedWith(Handlable.class)) {
            if (e.getKind() != ElementKind.FIELD) {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "Not a field", e);
                continue;
            }
            String name = capitalize(e.getSimpleName().toString());
            TypeElement clazz = (TypeElement) e.getEnclosingElement();
            try {
                JavaFileObject f = processingEnv.getFiler().createSourceFile(clazz.getQualifiedName() + "Extras");
                processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Creating " + f.toUri());
                Writer w = f.openWriter();
                try {
                    PrintWriter pw = new PrintWriter(w);
                    pw.println("package " + clazz.getEnclosingElement().getSimpleName() + ";");
                    pw.println("public abstract class " + clazz.getSimpleName() + "Extras {");
                    pw.println("    protected " + clazz.getSimpleName() + "Extras() {}");
                    TypeMirror type = e.asType();
                    pw.println("    /** Handle something. */");
                    pw.println("    protected final void handle" + name + "(" + type + " value) {");
                    pw.println("        System.out.println(value);");
                    pw.println("    }");
                    pw.println("}");
                    pw.flush();
                } finally {
                    w.close();
                }
            } catch (IOException x) {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, x.toString());
            }
        }
        return true;
    }
    private static String capitalize(String name) {
        char[] c = name.toCharArray();
        c[[0 | 0]] = Character.toUpperCase(c[0]);
        return new String(c);
    }
}

プロセッサーを登録する必要があります。 src/META-INF/services/javax.annotation.processing.Processorファイルを作成します:

proc.HandlableProcessor

ここでアノテーションを使います。新しく Java SE メインプロジェクトを作成し (JDK6 以上で使ってください) ライブラリを追加します。(ライブラリ ノードで右クリック "プロジェクトを追加" を選ぶ) アノテーションの使い方は次のようになっています:

package demo;
import ann.Handlable;
public class Main extends MainExtras {
    @Handlable
    private String stuff;
    public static void main(String[] args) {
        new Main().handleStuff("hello");
    }
}

このファイルは最初はコンパイルエラーが出るはずですが気にすることはありません。ファイル タブを開き、nbproject/project.properties を以下のように編集します:

# edit to ensure path is absolute:
build.dir=${basedir}/build
# add:
build.apt.dir=${build.dir}/apt
# add ${build.apt.dir}:
javac.classpath=\
    ${reference.lib.jar}:\
    ${build.apt.dir}
# edit:
javac.compilerargs=-s ${build.apt.dir}

プロジェクトを実行します。以下のように出力されます。

run:
hello

ファイルタブを開き、build/apt/demo/MainExtras.java は次のようになります。

package demo;
public abstract class MainExtras {
    protected MainExtras() {}
    /** Handle something. */
    protected final void handleStuff(java.lang.String value) {
        System.out.println(value);
    }
}


Main.java を再び開きます。エディタこのファイルはコンパイル可能と判断しています。(緑の四角がエディタの右上に表示されていて、エラーマークがありません)。 一般にアノテーションされたエレメントを変更した時にはこのファイルをコンパイルする必要があります。エディタで行われるバックグランドでのコンパイルはソースコード生成はこれを判断します。

もし MainExtras Javadoc 生成に含めたい場合にはファイルタブから build.xml を開き次のように nbproject/build-impl.xml からのターゲットの上書きを付け足します:

    <target name="-javadoc-build" depends="init">
        <mkdir dir="${dist.javadoc.dir}"/>
        <javadoc destdir="${dist.javadoc.dir}" source="${javac.source}" notree="${javadoc.notree}" use="${javadoc.use}" nonavbar="${javadoc.nonavbar}" noindex="${javadoc.noindex}" splitindex="${javadoc.splitindex}" author="${javadoc.author}" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}" private="${javadoc.private}" additionalparam="${javadoc.additionalparam}" failonerror="true" useexternalfile="true">
            <classpath>
                <path path="${javac.classpath}"/>
            </classpath>
            <sourcepath>
                <pathelement location="${src.dir}"/>
                <pathelement location="${build.apt.dir}"/> <!-- added -->
            </sourcepath>
            <packageset dir="${src.dir}" includes="*/**"/>
            <fileset dir="${src.dir}" includes="*.java"/>
        </javadoc>
    </target>

nbdev でのディスカッション: "Requirements for Supporting Annotation Processors in Mustang" #1 #2


バージョン: NetBeans 5.0



Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo