37
僕の考えるAPT開発の常識 Annotation Processing Tool ぐだなま( ω)2011/04/09 201149日土曜日

僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

Embed Size (px)

Citation preview

Page 1: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

僕の考えるAPT開発の常識Annotation Processing Tool

ぐだなま╮( ╹ω╹ )╭ 2011/04/092011年4月9日土曜日

Page 2: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

わかめ↓新食感!

 @vvakame

2011年4月9日土曜日

Page 3: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

APTのスゴさを魅せる

2011年4月9日土曜日

Page 4: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

ね、簡単でしょう?

※ 5分で実演が完了していた場合 ちゃんとホメてください

2011年4月9日土曜日

Page 5: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

Annotationて何?

2011年4月9日土曜日

Page 6: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

Annotationて何?

• Annotation = 注釈

• プログラムから読取可能

• コメントと違って影響力有

• @Override とかあるやん!

@JsonModelpublic class Message {

@JsonKey String id;

@JsonKey String room;

@JsonKey String text;

@JsonKey String timestamp;

2011年4月9日土曜日

Page 7: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

APTって何?

2011年4月9日土曜日

Page 8: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

APTって何?• Annotation Processing Tool の略

• コンパイル時に色々処理出来ます

• アノテーションに基づいて処理

• コードが規約に沿っているかチェックしたり

• コードを動的に生成したり!

2011年4月9日土曜日

Page 9: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

APT活用例• JSON ⇔ Model のマッピング

• Map<String, Object> と

POJOのマッピングみたいな感じ

• 型安全なコードが書けるよに!

• Reflectionせずに済むので高速!

2011年4月9日土曜日

Page 10: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

←今まで  これから→• 実行時にReflection

• エラーは実行時

• 実行時間 長め

• 型安全じゃない

• 実行時例外

• コンパイル時コード生成

• エラーはコンパイル時

• 実行時間 普通

• 型安全である

• 親切なエラー通知

2011年4月9日土曜日

Page 11: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

APTのVersion

2011年4月9日土曜日

Page 12: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

APTのVersion

• 最初のやつ

• com.sun.mirror

• Java5でなんか入った

• Slim3 が使ってるのはこれ

ぶっちゃけよくしらない

2011年4月9日土曜日

Page 13: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

APTのVersion

• JSR 269

• javax.lang.model

• Java6 (JSR270)で入った

• JsonPullParser が使ってるのはこれ

• Project Coin(JSR334)でちょっと追加今日はこっちを説明

2011年4月9日土曜日

Page 14: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

開発手順JsonPullParserでの使用例

→緑色の吹出し!

2011年4月9日土曜日

Page 15: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

Annotation定義• @interface で定義

• Retention (いつまでAnnotationが残るか)

• Target (何にAnnotation付けられるか)

@Retention(RetentionPolicy.SOURCE)@Target({ ElementType.FIELD})public @interface JsonKey { public String value() default ""; public boolean in() default true; public boolean out() default true; public boolean decamelize() default false;}

JsonModelJsonKey

2011年4月9日土曜日

Page 16: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

AbstractProcessor

• 定義

• EntryPoint

• process メソッド

• RoundEnviroment経由でElement取得

@SupportedSourceVersion(SourceVersion.RELEASE_6)@SupportedAnnotationTypes("net.vvakame.util.jsonpullparser.annotation.*")public class JsonAnnotationProcessor extends AbstractProcessor {

JsonAnnotationProcessor

2011年4月9日土曜日

Page 17: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

RoundEnviroment• 注釈処理すべきElementを持っている

• ラウンドという考え方

• 一気に処理されるわけではない

• 更新差分だけそのラウンドで処理

• 分割処理=処理済クラスのRetentionがSOURCEのAnnotation触れない…

2011年4月9日土曜日

Page 18: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

Element• 型とかクラスとかフィールドとか、全てのものが Element で表される

• 以下の流れで処理• 指定Annotation付Elementを取得

• 何らかの処理を行う• 文法チェック (ex setter, getterある?)

• コード生成ClassGenerateHelper#ValueExtractVisitor

2011年4月9日土曜日

Page 19: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

TypeMirror

• 型

• フィールドのElement→TypeMirror→

フィールドの型のElement

• 要するに中継地点…?

• Elementの方が重要です…。

2011年4月9日土曜日

Page 20: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

Annotation• Annotationに指定されたオプションが取得できる

@JsonModel(treatUnknownKeyAsError = true, decamelize = true)

public class Hoge extends RecvGeoInfoLog {

@JsonKey("foga") String piyo;

@JsonKey(converter = DateConverter.class) Date at;}

String getElementKeyString(Element element) { JsonKey key = element.getAnnotation(JsonKey.class); JsonModel model = element.getEnclosingElement()

.getAnnotation(JsonModel.class); String keyStr; if (!"".equals(key.value())) { keyStr = key.value(); } else if ("".equals(key.value()) && key.decamelize()) { keyStr = decamelize(element.toString()); } else if ("".equals(key.value()) && model.decamelize()) { keyStr = decamelize(element.toString()); } else { keyStr = element.toString(); } return keyStr; }

利用コード APT側

2011年4月9日土曜日

Page 21: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

Message• メッセージの出力

• 指定のElementに警告|エラー表示

Log

JsonKey key = el.getAnnotation(JsonKey.class);

String setter = getElementSetter(el);if (key.in() && setter == null) { Log.e("can't find setter method", el); encountError = true; return defaultAction(t, el);}

2011年4月9日土曜日

Page 22: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

JavaFileObject• Javaソースファイルの抽象

• ProcessingEnvironmentからFiler経由で取得可能

• ボイラープレートコードなので適当なサンプルコード見るのが良

ClassGenerateHelper#write

2011年4月9日土曜日

Page 23: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

便利屋系• Util

• Elements Element関係のユーティリティ

• Types• TypeMirror関係のユーティリティ

• Visitor• Annotation, Element, TypeMirror用

ClassGenerateHelper#ValueExtractVisitor

2011年4月9日土曜日

Page 24: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

特殊な設定ファイル

• 自作APT一式をjarにまとめる時必要

• META-INF/services/ javax.annotation.processing.Processor

• 中身は自作ProcessorのFQNFQN = package名+クラス名

/src/main/resources/ 以下略

2011年4月9日土曜日

Page 25: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

おすすめ開発方法

2011年4月9日土曜日

Page 26: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

おすすめの組合せ• Aptina

• UnitTest に利用

• TemplateEngine (MVEL)• 可読性の高いソース生成に一役

• Eclipse• maven

• jar の作成など

2011年4月9日土曜日

Page 27: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

Aptina• Aptina を使う

• 自作ProcessorのJUnitが書ける!

• デバッガ使える!Try&Errorも楽!

• UnitTestはちょっと不満が…

• 生成後ソースの検証が困難

• エラー通知のテストができない…?JsonAnnotationProcessorTest

2011年4月9日土曜日

Page 28: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

TemplateEngine(MVEL)

• 生成後ソースの可読性大事

• デバッグ的にも

• ライブラリ利用ユーザ的にも• Javadoc 提供もらくちん

• どこを変更するとどこに影響があるか分かりやすい (全部プログラムで生成=難読!)

MvelTemplate, JsonModelGen.java.mvel

2011年4月9日土曜日

Page 29: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

maven

• jar 作るの楽

• 依存ライブラリが多くなりがち管理の手間が少し省ける

• ユーザにEclipseの設定させなくて済む

• バージョン管理や公開も楽• バグがあって、分割コンパイルが必要...

pom.xml

2011年4月9日土曜日

Page 30: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

Formatter...?• Javaコードのフォーマッタが欲しい

• 今現在は使ってない (適切なのが無い)

• 手書きと自動生成を同じフォーマッタにかけてUnitTestで突合したい…

• コード中のFQN表記を import 利用に…} else if ("place".equals(key)) {

net.vvakame.sample.twitter.Place tmp = net.vvakame.sample.twitter.PlaceGenerated.get(parser);

obj.setPlace(tmp); if (listener != null) { listener.onAdd(tmp); }

2011年4月9日土曜日

Page 31: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

プロジェクト構成• core 

• ユーザが使うjarのため• apt 

• APTライブラリのjarのため• APTライブラリ自体のUnitTest

• usage• APTで生成されたコードのUnitTest• 兼、利用例、設定例

2011年4月9日土曜日

Page 32: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

Eclipseでの注意

• リソース系は1回落とさないと再読込されない

• MVELテンプレートの更新が反映されなくてハマる

2011年4月9日土曜日

Page 33: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

作ってみた!

2011年4月9日土曜日

Page 34: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

JsonPullParser作った!

• https://github.com/vvakame/JSONPullParser

• APTでJson→POJOマッピング用Javaコード生成

• Androidでも動くよ! http://bit.ly/hFTbtP

• Tweetを逐次読込→1Tweet毎に表示

• SengokuDroid server-side でガンガン利用中

2011年4月9日土曜日

Page 35: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

今後の野望

2011年4月9日土曜日

Page 36: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

今後の野望• Android用Slim3欲しい

• HamsterDB..? → GPL...

• SQLite..? → 擬似KVS化しないと...

• MsgpackParser欲しい

• JavaソースFormatter欲しい

2011年4月9日土曜日

Page 37: 僕の考えるAPT開発の常識 ぐだ生 2011/04/09版

なにか質問は?

Minecraft面白いからやるべき べき

2011年4月9日土曜日