アノテーションプロセッサ処理時の例外をソースコードに吐く
アノテーションプロセッサ処理中にエラー等をシステム側(Eclipse側)に通知したい場合は、通常の標準出力にプリントしても駄目で、代わりにMessagerクラスを使う。
@Override public boolean process(Set annotations, RoundEnvironment roundEnv) { Messager messager = processingEnv.getMessager(); try { 何か処理 } catch (Exception e) messager.printMessage(Kind.ERROR, e.getMessage()); }
Messagerから出力されたメッセージは標準出力コンソールには表示されず、Eclipseでいうと「エラー・ログ」という(私は)普段はあまり開かないビューにしか表示されない。
もっと強烈にエラーが発生したことをユーザ側に通知するには? と考えたんだけど今ひとつ思いつかなかったので、例外を現在ソースコード生成のために開いているWriterに出力するようにしてみた。
try { 何か処理 } catch (Exception e) e.printStackTrace(new PrintWriter(this.writer)); messager.printMessage(Kind.ERROR, e.getMessage()); }
アノテーションプロセッサの実行時にエラーが発生すると以下のように生成したソースコード側に出力される。
/* * このファイルはアノテーションプロセッサ(net.kazzz.annotation.ActivityAutoDtoAnnotationProcessor)により自動生成されました。 * file : UserInfo.java; * base : net.kazzz.android.UserActivity.java; */ package net.kazzz.android.dto; import net.kazzz.annotation.Element; import net.kazzz.annotation.XmlAutoBean; java.lang.NullPointerException at net.kazzz.annotation.AbstractBeanAnnotationProcessor.getShortClassName(AbstractBeanAnnotationProcessor.java:188) at net.kazzz.annotation.ActivityAutoDtoAnnotationProcessor.needConverters(ActivityAutoDtoAnnotationProcessor.java:322) at net.kazzz.annotation.ActivityAutoDtoAnnotationProcessor.writePackageAndImport(ActivityAutoDtoAnnotationProcessor.java:290) at net.kazzz.annotation.ActivityAutoDtoAnnotationProcessor.outputBean(ActivityAutoDtoAnnotationProcessor.java:194) at net.kazzz.annotation.ActivityAutoDtoAnnotationProcessor.process(ActivityAutoDtoAnnotationProcessor.java:94) at org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:139) at org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.round(RoundDispatcher.java:121) at org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotationProcessorManager.processAnnotations(BaseAnnotationProcessorManager.java:159) at org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeAnnotationProcessorManager.processAnnotations(IdeAnnotationProcessorManager.java:134) at org.eclipse.jdt.internal.compiler.Compiler.processAnnotations(Compiler.java:809) at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:428) at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:364) at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.compile(BatchImageBuilder.java:178) at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:301) at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:60) at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:254) at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:173) at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:629) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:172) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:203) at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:255) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:258) at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:311) at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:343) at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:144) at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:242) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
わかりやすいんだけど、ちょっと刺激が強すぎるかな。