動的依存情報に基づく アスペクト間の関係抽出 石尾 隆 大阪大学大学院情報科学研究科 t-isio@ist.osaka-u.ac.jp
アスペクト指向プログラミングの利点 アスペクトは システムの振る舞いを外から変更する 既存のモジュール(クラス)の枠をこえて作用する オブジェクトに色々貼り付けて機能を拡張できる クラス階層とは直接関係ない機能: 永続化,シングルトン,ロギング,アクセス管理, トランザクションのサポートなど
アスペクト指向の複雑さ 理想: アスペクト同士は相互に独立 現実:アスペクトを複数貼り付けた結果は不明瞭 ユーザは,適当にいくつか選んで貼り付けるだけ 現実:アスペクトを複数貼り付けた結果は不明瞭 追加されたアスペクトが新しくイベントを発生させる 既にあるアスペクトがそのイベントに対しても動作する可能性がある あるアスペクトが別のアスペクトの動作を阻害する アスペクトが連鎖していって無限ループに陥る あるアスペクトが勝手にデータを書き換えてしまう
アスペクトの管理 アスペクトがどう動くか良く分からないのは不安 アスペクト間の関係を明示的に管理すればどうか? 何か設定ファイルのようなもので一元管理すると: 保守性,理解容易性は向上するはず しかし: アスペクトの便利さが失われる 何も書かなくて動くのが一番いい 管理情報を誰が,いつ,どのように書くのか? 誰: 個々のアスペクトの開発者?アスペクトのユーザ? いつ: アスペクトが「干渉しそう」と判断できたとき?
アスペクト間の関係の抽出 アスペクト間の関係を明示的に書くのはつらい しかし「どんな関係にあるか」という情報はほしい プログラムから,現在のアスペクト間の関係を抽出する
アスペクト間の関係 アスペクト A, B について ある特定のイベント(join point)に対して プログラムの実行経過にしたがって
関係が分かることにより期待される効果 問題が起きていないかどうかの診断 他のアスペクトに影響を与えるアスペクトの調査 関係ないアスペクトの間に関連が生じていないか確認 狙った相互関係,優先度が反映されているか確認 他のアスペクトに影響を与えるアスペクトの調査 テスト,保守作業時に注意すべき存在の把握 新しく導入したアスペクトの影響の調査
どうやって関係を抽出するか 動的な依存情報解析 実行履歴情報から,依存関係を見つけてくる 依存関係の中から候補を絞る メソッド呼び出し関係 アドバイスの実行関係 データの授受関係 依存関係の中から候補を絞る アスペクト間で起こっている依存関係パスを見つける そのパスの出現頻度などの特徴を調べる あるアスペクトに到達するパスがユニークか,複数あるのか
なぜ動的アプローチか? 静的な情報解析と何が違うか: 動いているものに対する診断 ソースコードからの検出は正確性が下がりがち 動的 pointcut,実行時ウィービングなど動的な要素が多い 「関連するかもしれない」関係の候補は大量に生成されうる 動いているものに対する診断 「実際に起こった関連」だけが抽出できる 注目したいテストケースだけを個別に調査できる ただし,関係を「証明」するわけではない
予備実験 実際にどの程度実行履歴から情報が抽出できるか AspectJ のプログラムを対象に実験: 用意したもの アスペクトのメンバー間の呼び出し関係 アスペクトの動作順序関係 用意したもの AspectJ のプログラム1個とテストケース メソッド呼び出し関係の抽出ツール JVMDI (Debugger Interface) を用いて構築したもの
用意したプログラム グラフ構造を Depth-First で訪問するプログラム アスペクト4つがノード訪問に関連付けられている ノードが “+”, “*” の演算,数値を表現 グラフ全体で1つの式を表現 グラフ構築 → ノードの訪問処理 → 最終結果の出力 アスペクト4つがノード訪問に関連付けられている LoopDetect: グラフ内部のループ検出 Print: 訪問した頂点の情報を出力 Caching: 一度訪問した頂点への再訪問を省略 Cleanup: 計算が終わったノードから解放していく
実施した作業 典型的なデータ構造を1個作成して実行 メソッド呼び出し列を得る 得られた実行履歴から,呼び出し関係を分析 取得した関係: AspectJ 生成コードの特徴を利用してアドバイス呼び出しを抽出 取得した関係: 「あるアスペクトAが呼び出された直後に 次のアスペクトBへの呼び出しが起きる」 「あるアスペクトAから他のアスペクトBへの呼び出しが起きる」 到達までに他のメソッドを経由しても OK B への A から以外の経路があるかどうかも調べる
実験結果 アドバイスごとの関係をアスペクト単位でまとめた結果 Caching が他のアスペクトに強く影響を与えている Print, Cleanup は Caching からのみ呼ばれる 呼び出し関係 外からの呼び出し Caching 前後関係 Cleanup LoopDetect Print
得られた情報の評価 アスペクトの動作として Caching が支配的 LoopDetect と Caching が絡みあっているように見える Print アスペクトは必ず Caching アスペクトの下で動く Caching が計算を飛ばすと Print 処理が飛ばされたりもする Cleanup アスペクトも Caching アスペクトの下で動く Cleanup は Caching の存在を前提にしているので OK LoopDetect と Caching が絡みあっているように見える LoopDetect は,ループ検出のために訪問ノードを管理している Caching の直前にループチェック,スタックへノードを載せる Caching の処理が終わるとスタックからノードを除去する Caching が,値のキャッシュを返すか,データ計算をする データ計算でノード訪問が発生するため LoopDetect が呼ばれる データ計算の再帰呼び出し構造をきちんと捉えれば,関係を整理できる?
まとめ 実行時情報から,アスペクト間の関係を抽出 解析手法,可視化方法の拡張 今の時点では呼び出し関係と,呼び出しの順序関係 アスペクトの動作関係を検知できている ただし,再帰呼び出しなどが原因で,結果がやや複雑になる 解析手法,可視化方法の拡張 データ依存関係の捕捉 同じ join point からのアスペクト起動の明示 再帰呼び出し構造も明示する
補足資料
アドバイスは実行履歴上でどう見える? ajc$before: before アドバイスに対応 ajc$after: after アドバイスに対応 aroundBody: around アドバイスに対応. コードはクラス内のメソッドとして見える. 直前に必ず around を実装した アスペクトの aspectOf が呼ばれる. aspectOf: アスペクトのインスタンス参照 clinit, init: アスペクトのロード,インスタンス初期化時 (アスペクトが最初に実行されるとき) interFieldInit: フィールドの初期化時
関連研究: アスペクトの干渉 干渉とは何か? 複数のアスペクトが同じ Join Point で動くこと[1] around アドバイス(proceed を使わないものなど)は問題の引き金となりやすい データを書き換える(副作用を持った)アスペクトは干渉を起こさないが問題となる データベースの中身を暗号化するアスペクトなど [1] Douence, R. et al.: Detection and Resolution of Aspect Interaction. RR-4435, INRIA, 2002.
関連研究: アスペクトの明示的な管理 アスペクト間の合成方法を明示的に開発者が指示する方法の提案[2] 同一時点で動作するアスペクトが複数あるとき, どのアスペクトがどのアスペクトより先,後という制約を 記述していくことで順序を確定する [2] Nagy, I. et al.: Declarative Aspect Composition. SPLAT Workshop held in conjunction with AOSD2004.
関連研究: 実行履歴の解析 実行トレースからの機能の実装位置特定[3] 実行履歴からのアスペクト抽出[4] 関数 f が様々な実行履歴に,共通して登場するか単独でしか登場しないか,といった特性によって関数を分類し,システム内での役割を推測する 実行履歴からのアスペクト抽出[4] メソッド呼び出し関係の履歴から規則を発見 使っているのはメソッド呼び出しの順序関係だけ [3] Eisenbarth, T. et al.: Locating Features In Source Code. IEEE Transactions on Software Engineering, Vol.29, No.3, pp.210-224, 2003. [4] Silvia Breu et al.: Aspect Mining Using Event Traces. ASE2004, to appear.
既存ツールと比べると? AJDT のようなマーカー表示は便利,ただし デバッガのステップ実行は非常に強力 順序関係の情報は出せない 直接見えない join point までは効果は及ばない メソッド呼び出し文からは,“execution” join point は見えない デバッガのステップ実行は非常に強力 スタックトレース情報があれば呼び出し関係は分かる しかし,途中経過まで調べるのは難しい ステップ実行だけで処理を進めていくのは非現実的 データ依存関係など,ステップ実行だけでは捕らえにくい