AOP言語におけるDynamic Weavingのための一手法

Dynamic AOPと
その実装手法について
東京工業大学
佐藤芳樹 千葉滋
Mar 12-14, 2003
SPA 2003, Hakone
1
1.AOP(Aspect-Oriented-Programming)
簡単な例
モジュール間を横断する関心事(crosscutting
concerns)をアスペクトとしてカプセル化
[ BookShelf ]
Book search(String key) {
while (_booklist.hasMoreElements())
if (_booklist.next().match(key)) return book[i];
}
なぜか遅いんだけど、
一体なんでだろう?
どこがボトルネック!?
[Book]
boolean match(String key) {
if (match0(key)) return true;
else return false;
}
Mar 12-14, 2003
SPA 2003, Hakone
2
1.AOP(Aspect-Oriented-Programming)
散らばるコード
モジュール間を横断する関心事(crosscutting
concerns)をアスペクトとしてカプセル化
[ BookShelf ]
public static File loggingFile;
Book search(String key) {
Profiler.start(BookShelf.loggingFile);
while (_booklist.hasMoreElements())
if (_booklist.next().match(key)) return book[i];
Profiler.stop(BookShelf.loggingFile);
}
[Book]
boolean match(String key) {
Profiler.start(BookShelf.loggingFile);
if (match0(key)) {
Profiler.stop(BookShelf.loggingFile);
return true;
} else {
Profiler.stop(BookShelf.loggingFile);
return false;
}
Mar
SPA 2003, Hakone
} 12-14, 2003
あちこちに散らばるコード
crosscutting concern
分散、同期、セキュリティ
トランザクション、etc…
保守性・再利用性が低下
どうやらOOでも駄目らしい
3
1.AOP(Aspect-Oriented-Programming)
アスペクトにカプセル化
モジュール間を横断する関心事(crosscutting
concerns)をアスペクトとしてカプセル化
[ BookShelf ]
Book search(String key) {
Aspect
while (_booklist.hasMoreElements())
if (_booklist.next().match(key)) return book[i];
}
[Book]
boolean match(String key) {
if (match0(key))
return true;
else
return false;
}
Mar 12-14, 2003
searchとmatchの前後
Profiler#start(),stop()
loggingFile
散らばっていた処理、無理に
受け渡してたデータを分離
アプリロジックと無関係な
非機能的処理も再利用できる
SPA 2003, Hakone
4
1.AOP(Aspect-Oriented-Programming)
アスペクト処理系が合成
モジュール間を横断する関心事(crosscutting
concerns)をアスペクトとしてカプセル化
[ BookShelf ]
public static File loggingFile;
Book search(String key) {
Profiler.start(BookShelf.loggingFile);
while (_booklist.hasMoreElements())
if (_booklist.next().match(key)) return book[i];
Profiler.stop(BookShelf.loggingFile);
}
[Book]
boolean match(String key) {
Profiler.start(BookShelf.loggingFile);
if (match0(key)) {
Profiler.stop(BookShelf.loggingFile);
return true;
} else {
Profiler.stop(BookShelf.loggingFile);
return false;
}
Mar
SPA 2003, Hakone
} 12-14, 2003
Aspect
searchとmatchの前後
Profiler#start(),stop()
loggingFile
weaver
アスペクトとプログラムを
静的に合成(weave)
5
2. Dynamic AOPとその実装
Dynamic AOP
実行時にアスペクトとプログラムを合成
利点
 開発効率を改善

実行したまま、プロファイリング、アサーション、ロ
ギングのOn/Off
AspectJ : ポーリング箇所を替えるごとにstop-rebuild-restart

実行環境に適応するソフトウェア

要求・環境に応じて、最適なアスペクトに切り替え
Mar 12-14, 2003
SPA 2003, Hakone
6
2. Dynamic AOPとその実装
分散GUIの例
Aspect pda = new Aspect(“PDAAspect”);
Aspect pc = new Aspect(“PCAspect”);
switch(client) {
クライアントに応じて
case PDA : weaver.weave(pda);
case PC : weaver.weave(pc);
アスペクトを合成
}
PC用Aspect
Note用Aspect
PDA用Aspect
Mar 12-14, 2003
・配置
・解像度
・ビットレート
・色数 etc…
SPA 2003, Hakone
7
2. Dynamic AOPとその実装
AOPのモデル
join-point でアドバイスを実行する
プログラム中の場所
・・・
・フィールド
アクセス
・メソッド
呼び出し
・オブジェクト
生成
コードの断片
Dynamic Join Point Model
(AspectJ[*1]で提案)
アスペクト
pointcut 場所の指定
(join-pointを指定)
advice 処理の記述
match()
search()
join-point
Profiler.start()
*1 Xerox Corporation. “The AspectJ Programming Guide.
Online Documentation”, 2001. http://www.eclipse.org/aspectj/
Mar 12-14, 2003
SPA 2003, Hakone
8
2. Dynamic AOPとその実装
フックでの典型的な実装
フックコードの挿入
 コード変換器でjoin-pointへフックコードを挿入
 プログラムの実行をインターセプトし、アドバイ
スを実行
join
point
pointcut
指定
Mar 12-14, 2003
do_before_advice();
do_after_advice();
do_before_advice();
do_after_advice();
挿入された
フックコード
フック
SPA 2003, Hakone
9
2. Dynamic AOPとその実装
求められるDAOPシステムの要件
実行時にフックを引っ掛けてアスペクトを合成
 仕掛けが少なく
通常の実行では性能を落とさない
 処理系に手を加えない


合成は早く


停止時間を抑えてプログラムに反映
コードの実行も早く

高速にアドバイスを実行
Mar 12-14, 2003
SPA 2003, Hakone
10
2. Dynamic AOPとその実装
DAOPシステムの実装技法
実行時にフックを挿入するための技法

MOP(Metaobject Protocol)
 CLOS、Smalltalk、etc

リフレクション(イントロスペクション)[3]


静的コード変換[4,5]


静的なAOPシステムの手法と類似した手法
処理系に用意[6,7]


クラスを巡回
インタプリタ(JIT)、デバッガ
ジャストインタイム・フック
埋め込み(我々)
 オンデマンドにフックを埋め込む
Mar 12-14, 2003
SPA 2003, Hakone
[3] D. Orleans and K. Lieberherr. DJ: Dynamic Adaptive
Programming in Java In Reflection 2001
[4] J. Baker and W. Hsieh. “Runtime Aspect Weaving
Through Metaprogramming” In AOSD’02
[5] A. Popovici, T. Gross, and G. Alonso. “Dynamic
Weaving for Aspect Oriented Programming” In AOSD’02
[6] A. Popovici, G. Alonso, and T. Gross. “Just-In-Time
Aspects” In AOSD’03
[7] Andrei. P, Thomas. G and Gustavo. A. “Dynamic
Weaving for Aspect-Oriented Programming” In AOSD’02
11
2. Dynamic AOPとその実装
DAOPシステムの実装技法
実行時にフックを挿入するための技法

MOP(Metaobject Protocol)
 CLOS、Smalltalk、etc

リフレクション(イントロスペクション)[3]


静的コード変換[4,5]


静的なAOPシステムの手法と類似した手法
処理系に用意[6,7]


クラスを巡回
インタプリタ(JIT)、デバッガ
ジャストインタイム・フック
埋め込み(我々)
 オンデマンドにフックを埋め込む
Mar 12-14, 2003
SPA 2003, Hakone
[3] D. Orleans and K. Lieberherr. DJ: Dynamic Adaptive
Programming in Java In Reflection 2001
[4] J. Baker and W. Hsieh. “Runtime Aspect Weaving
Through Metaprogramming” In AOSD’02
[5] A. Popovici, T. Gross, and G. Alonso. “Dynamic
Weaving for Aspect Oriented Programming” In AOSD’02
[6] A. Popovici, G. Alonso, and T. Gross. “Just-In-Time
Aspects” In AOSD’03
[7] Andrei. P, Thomas. G and Gustavo. A. “Dynamic
Weaving for Aspect-Oriented Programming” In AOSD’02
12
2. Dynamic AOPとその実装
イントロスペクションによる手法
DJ(Demeter/Java)[3] Adaptive-Programming
 アドバイスを実行する場所を、戦略として与える
 実行時にクラスを巡回し、アドバイスを実行
 フックをかけられず、毎回巡回のため遅い
int sumSalaries() {
// Adaptiveメソッドを定義
String s = "from Company to Salary"; // traversal strategy
Visitor v = new Visitor() {
// adaptive visitor
private int sum;
public void before(Salary man) { sum += man.getSalary(); }
public Object getReturnValue() { return new Integer(sum); }
};
Mar 12-14, 2003
SPA 2003, Hakone
13
2. Dynamic AOPとその実装
DAOPシステムの実装技法
実行時にフックを挿入するための技法

MOP(Metaobject Protocol)
 CLOS、Smalltalk、etc

リフレクション(イントロスペクション)[3]


静的コード変換[4,5]


静的なAOPシステムの手法と類似した手法
処理系に用意[6,7]


クラスを巡回
インタプリタ(JIT)、デバッガ
ジャストインタイム・フック
埋め込み(我々)
 オンデマンドにフックを埋め込む
Mar 12-14, 2003
SPA 2003, Hakone
[3] D. Orleans and K. Lieberherr. DJ: Dynamic Adaptive
Programming in Java In Reflection 2001
[4] J. Baker and W. Hsieh. “Runtime Aspect Weaving
Through Metaprogramming” In AOSD’02
[5] A. Popovici, T. Gross, and G. Alonso. “Dynamic
Weaving for Aspect Oriented Programming” In AOSD’02
[6] A. Popovici, G. Alonso, and T. Gross. “Just-In-Time
Aspects” In AOSD’03
[7] Andrei. P, Thomas. G and Gustavo. A. “Dynamic
Weaving for Aspect-Oriented Programming” In AOSD’02
14
2. Dynamic AOPとその実装
静的コード変換による手法
コンパイル時リフレクションですべてのjoin-point
へ最小のフックを挿入 (JAC[3], Handiwrap[4])
 静的にはフックする場所を特定できない
 アドバイスを実行するかどうかをチェック
pointcut
指定はここだけ
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
Mar 12-14, 2003
分岐、無駄なフック - 仕掛けが大
常にすべてのjoin-pointでチェック
コードサイズの肥大化
SPA 2003, Hakone
15
2. Dynamic AOPとその実装
DAOPシステムの実装技法
実行時にフックを挿入するための技法

MOP(Metaobject Protocol)
 CLOS、Smalltalk、etc

リフレクション(イントロスペクション)[3]


静的コード変換[4,5]


静的なAOPシステムの手法と類似した手法
処理系に用意[6,7]


クラスを巡回
インタプリタ(JIT)、デバッガ
ジャストインタイム・フック
埋め込み(我々)
 オンデマンドにフックを埋め込む
Mar 12-14, 2003
SPA 2003, Hakone
[3] D. Orleans and K. Lieberherr. DJ: Dynamic Adaptive
Programming in Java In Reflection 2001
[4] J. Baker and W. Hsieh. “Runtime Aspect Weaving
Through Metaprogramming” In AOSD’02
[5] A. Popovici, T. Gross, and G. Alonso. “Dynamic
Weaving for Aspect Oriented Programming” In AOSD’02
[6] A. Popovici, G. Alonso, and T. Gross. “Just-In-Time
Aspects” In AOSD’03
[7] Andrei. P, Thomas. G and Gustavo. A. “Dynamic
Weaving for Aspect-Oriented Programming” In AOSD’02
16
2. Dynamic AOPとその実装
JITコンパイラによるフック
JITが生成したネィティブコード上のすべてのjoinpointへ最小のフック挿入(PROSE[7])
 Javaでのフックよりネィティブのフックは小さい
 Jalapeno(Javaで書かれたVM、すべてJITコンパ
イル)へ実装
再JITコンパイルしない
 不必要なフックも挿入

Mar 12-14, 2003
SPA 2003, Hakone
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
need_advice();
17
2. Dynamic AOPとその実装
デバッガによるフック
フックをbreakpointとして設定 (PROSE[6])



標準機能 JPDA の利用
HotSpot使用でデバッグ実行(3~6%程度遅い)
アドバイスの実行が遅い
breakpointセット
デバッガ
デバッガ
do_advice();
Mar 12-14, 2003
SPA 2003, Hakone
デバッガが
アドバイス実行
18
2. Dynamic AOPとその実装
デバッガによるフック挿入・実行
do_advice();
Mar 12-14, 2003
SPA 2003, Hakone
19
2. Dynamic AOPとその実装
DAOPシステムの実装技法
実行時にフックを挿入するための技法

MOP(Metaobject Protocol)
 CLOS、Smalltalk、etc

リフレクション(イントロスペクション)[3]


静的コード変換[4,5]


静的なAOPシステムの手法と類似した手法
処理系に用意[6,7]


クラスを巡回
インタプリタ(JIT)、デバッガ
ジャストインタイム・フック
埋め込み(我々)
 オンデマンドにフックを埋め込む
Mar 12-14, 2003
SPA 2003, Hakone
[3] D. Orleans and K. Lieberherr. DJ: Dynamic Adaptive
Programming in Java In Reflection 2001
[4] J. Baker and W. Hsieh. “Runtime Aspect Weaving
Through Metaprogramming” In AOSD’02
[5] A. Popovici, T. Gross, and G. Alonso. “Dynamic
Weaving for Aspect Oriented Programming” In AOSD’02
[6] A. Popovici, G. Alonso, and T. Gross. “Just-In-Time
Aspects” In AOSD’03
[7] Andrei. P, Thomas. G and Gustavo. A. “Dynamic
Weaving for Aspect-Oriented Programming” In AOSD’02
20
2. Dynamic AOPとその実装
動的クラス書き換え(我々が開発1)
フックをコード中に埋め込む



古いクラス定義を新しいもので置換
HotSwap機能を使用 (Sun JDK1.4 JPDA)
 デバッガの制御下でロード済みクラスを再ロード
置換処理は低速だが、アドバイスの実行は高速
JVM
do_advice();
do_advice();
フック入り
クラス
JPDA
do_advice();
do_advice();
do_advice();
do_advice();
Mar 12-14, 2003
ロード済み
クラス
do_advice();
do_advice();
クラス再定義
SPA 2003, Hakone
21
2. Dynamic AOPとその実装
動的クラス書き換え(我々が開発1)
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
Mar 12-14, 2003
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
SPA 2003, Hakone
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
22
ジャストインタイム・フック埋め込み
(我々が開発2)
2段階のフック挿入

ア
ド
バ
イ
ス
実
行
時
間
デバッガによるフックと動的クラス書き換えをハ
イブリッド
デバッガによるフック
1
switch
フック挿入に準備がいらない
高速にフックを挿入
バイトコード変換でフックを挿入し、
クラスを再ロード
頻繁にデバッガへスイッチするなら、
2
動的クラス書き換え フックを埋め込んでしまう
フック埋め込み時間
Mar 12-14, 2003
SPA 2003, Hakone
23
ジャストインタイム・フック埋め込み
(我々が開発2)
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
do_advice();
Mar 12-14, 2003
SPA 2003, Hakone
24
3. Wool
アスペクト処理系 Wool
ジャストインタイム・フック埋め込みをPure Javaで実装
 実行途中のメソッドにもフック挿入



Javaでアスペクトを記述



ActiveFrameで参照されるクラスへもフック挿入
フックを挿入するか否かも選択
ポイントカットの動的な変更
アドバイスの動的な追加・変更・削除
性能劣化の60~70%がコード変換・再ロード処理
Mar 12-14, 2003
SPA 2003, Hakone
25
4.おわりに
今後のDAOPの展望
ポストDLL
 開発時にリンクポイントを用意しなくて良い
アプリケーションコードの見せ方
 フックポイントの制限(セキュリティ)

オートノミックコンピューティング
 あらゆる場所へ改変箇所が浸透

実行時にアスペクトの自動抽出・自動分離
フックの高速化・コードの高質化の両立(Wool)
Mar 12-14, 2003
SPA 2003, Hakone
26