プログラムスライスを用いた アスペクト指向プログラムのデバッグ支援環境

Slides:



Advertisements
Similar presentations
Web アプリをユーザー毎に カスタマイズ可能にする AOP フレームワーク
Advertisements

シーケンス図の生成のための実行履歴圧縮手法
情報伝播によるオブジェクト指向プログラム理解支援の提案
プログラムの動作を理解するための技術として
AspectScope によるアスペクトとクラスのつながりの視覚化
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
アスペクト指向プログラムに対する プログラムスライシング
プログラム実行履歴を用いたトランザクションファンクション抽出手法
プログラム実行時情報を用いたトランザクションファンクション抽出手法
ソースコードの変更履歴における メトリクス値の変化を用いた ソフトウェアの特性分析
静的情報と動的情報を用いた プログラムスライス計算法
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
暗黙的に型付けされる構造体の Java言語への導入
動的依存グラフの3-gramを用いた 実行トレースの比較手法
オブジェクト指向プログラムにおける エイリアス解析手法の提案と実現
シーケンス図を用いて実行履歴を可視化するデバッグ環境の試作
動的スライスを用いたバグ修正前後の実行系列の差分検出手法
プログラムスライスを用いた アスペクト指向プログラムのデバッグ支援環境
実行時情報に基づく OSカーネルのコンフィグ最小化
限られた保存領域を使用する Javaプログラムの実行トレース記録手法の 提案と評価
Javaプログラムの変更を支援する 影響波及解析システム
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
横断的関心事に対応したオブジェクト指向言語GluonJとその織り込み関係の可視化ツール
動的データ依存関係解析を用いた Javaプログラムスライス手法
オープンソース開発支援のための ソースコード及びメールの履歴対応表示システム
コードクローンの動作を比較するためのコードクローン周辺コードの解析
UMLモデルを対象とした リファクタリング候補検出の試み
Javaバイトコードの 動的依存解析情報を用いた スライシングシステムの実現
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
アスペクト指向言語のための 独立性の高いパッケージシステム
プログラム理解におけるThin sliceの 統計的調査による有用性評価
バイトコードを単位とするJavaスライスシステムの試作
ソフトウェア保守のための コードクローン情報検索ツール
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
Javaバーチャルマシンを利用した 動的依存関係解析手法の提案
プログラムの織り込み関係を可視化するアウトラインビューの提案と実装
コーディングパターンの あいまい検索の提案と実装
JAVAバイトコードにおける データ依存解析手法の提案と実装
オブジェクトの協調動作を用いた オブジェクト指向プログラム実行履歴分割手法
静的情報と動的情報を用いた Javaプログラムスライス計算法
統合開発環境によって表現された 言語機構によるコードのモジュール化
同期処理のモジュール化を 可能にする アスペクト指向言語
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
設計情報の再利用を目的とした UML図の自動推薦ツール
依存関係の局所性を利用した プログラム依存グラフの 効率的な構築法
保守請負時を対象とした 労力見積のためのメトリクスの提案
「マイグレーションを支援する分散集合オブジェクト」
アスペクト指向言語のための視点に応じた編集を可能にするツール
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
メソッドの同時更新履歴を用いたクラスの機能別分類法
アスペクト指向プログラミングの 動的プログラムスライスへの応用
UMLモデルを対象とした リファクタリング候補検出手法の提案と実現
エイリアス関係を考慮した Javaプログラム用静的スライシングツール
複雑度メトリクスを用いた JAVAプログラム品質特性の実験的評価
プログラムの一時停止時に 将来の実行情報を提供するデバッガ
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
コードクローン解析に基づく デザインパターン適用候補の検出手法
回帰テストにおける実行系列の差分の効率的な検出手法
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
オブジェクト指向メトリクスを用いた 開発支援に関する研究 --- VC++とMFCを用いた開発を対象として ---
ベイジアンネットワークと クラスタリング手法を用いたWeb障害検知システムの開発
プログラム理解のための 付加注釈 DocumentTag の提案
GluonJ を用いたビジネスロジックからのデータベースアクセスの分離
Josh : バイトコードレベルでのJava用 Aspect Weaver
Presentation transcript:

プログラムスライスを用いた アスペクト指向プログラムのデバッグ支援環境 石尾 隆 井上研究室 博士前期課程2年 t-isio@ics.es.osaka-u.ac.jp

発表の概要 アスペクト指向プログラミング アスペクト指向プログラムの開発支援 ツールの実装と評価 今後の課題 オブジェクト指向プログラミング アスペクト指向の特徴 アスペクト指向の問題点 アスペクト指向プログラムの開発支援 アスペクト干渉の検出 プログラムスライシングの適用 ツールの実装と評価 今後の課題 この発表では,まず最初にアスペクト指向プログラミングの特徴と,その問題点について説明します.次に,この問題点に対して,有効な開発支援を行うためにアスペクト干渉の検出と,プログラム解析手法のひとつであるプログラムスライシングの適用について説明します.最後に,ツールの実装と今後の課題について述べます.

オブジェクト指向モデル システムの機能をオブジェクトが分担して担当 横断要素: 複数のオブジェクトが関わる機能 コードが分散,一貫性の維持が困難 →保守性の悪化 エラーが起きたらGUIに通知 GUIはユーザの入力に従って Databaseを制御 例:学生の成績管理システム GUI Student 学生情報を要求 情報の保存・取得 Database それではまず,アスペクト指向プログラミングについて説明する前準備として,オブジェクト指向プログラミングの特徴について,簡単に触れたいと思います.オブジェクト指向プログラミングでは,オブジェクトの相互通信という形でシステムをモデル化します.オブジェクトがシステムの機能を分担しますが,横断要素と呼ばれる複数のオブジェクトが関わる機能は,うまく取り扱うことができません.処理に参加するすべてのオブジェクトにコードが分散するため,一貫性の維持が難しく,保守性を悪化させる要因となっています.  例として,ここにオブジェクト指向プログラムのモデル例を挙げていますが,エラーが起きたらユーザの指示を仰ぐという処理がGUIとDatabaseに関わる横断要素として示されています. 履修情報 統計情報を要求 Statistics Course 情報の保存・取得

Error Notification Aspect アスペクト指向モデル アスペクト: 横断要素のモジュール化 アスペクト= (動作時点, 処理) の集合で定義 動作時点は,メッセージ送受信や例外の発生など 明示的な呼び出しが不要 Error Notification Aspect 「エラーが起きたら動作」 ユーザへの通知 ユーザ からの 指示 監視 GUI Student Database  これに対して,アスペクト指向プログラミングでは,アスペクトという横断要素をモジュール化するための新しいモジュール単位を導入します.  アスペクトは,メッセージ送受信や例外の発生といった,プログラム実行中のイベントに連動して動作する処理として記述されます.図に示しているエラー通知アスペクトは,Databaseでのエラー発生に連動し,ユーザへの通知,ユーザからの指示をDatabaseに伝達する,という処理を行います.  手続き呼び出し処理を呼び出す側に書くのではなく,呼び出される側に動作する条件が書いてある,という形式になります. Statistics Course

アスペクト指向の利点と問題点 利点:モジュール性の向上 問題点:プログラムの複雑化 保守性の向上 再利用性の向上 横断要素がアスペクトにまとまっているので,変更が容易 再利用性の向上 モジュール間の相互依存性の解消 横断要素とオブジェクトの独立した再利用 問題点:プログラムの複雑化 オブジェクトを見ただけでは動作がわからない アスペクトの干渉 アスペクトの動作順序で実行結果が変わる アスペクトの動作中に別のアスペクトが動作する  アスペクト指向における利点は,モジュール性の向上という形で現れます.  モジュール性の向上は,保守性と再利用性の向上につながります.横断要素に関する要求や仕様が変更された場合に,以前は関連したすべてのオブジェクトを変更していたのに対し,ひとつのアスペクトだけを変更すればよいことになります.  また,横断要素を分離することで,オブジェクト間の相互依存性を抑えることができるほか,横断要素とオブジェクトをそれぞれ独立して再利用することができます.  アスペクトの利点については,様々な報告がなされていますが,それと同時に,プログラムの複雑化が新たな問題となっています. アスペクトはオブジェクトから分離して記述されるため,オブジェクトを見ただけでは動作が分からない,という問題があります.また,複数のアスペクトが同時に実行される場合に動作順序によって結果が変わったり,アスペクトの動作中に別のアスペクトが動作するなど,アスペクトの干渉と呼ばれる問題が発生しています.これらは,いずれも,検出しにくい欠陥の原因となる恐れがあります.

本研究の目的 アスペクトを組み込んだプログラムに対する依存関係解析結果を用いた開発支援手法を提案する. 対象: AspectJ アスペクト干渉の検出 アスペクトを組み込む時点での支援 プログラムスライスの抽出 アスペクトを組み込んだ後のデバッグ支援 対象: AspectJ そこで,本研究では,アスペクトを組み込んだプログラムに対する,依存関係解析を用いた支援手法の提案を行います. アスペクトを組み込む際に発生する干渉の検出と,アスペクトを実際に組み込んだ後の依存関係解析によるデバッグ支援とを組み合わせて用います. 対象としては,最も使われている処理系であることから,AspectJを選びました.

アスペクト干渉の検出 Aspect を含めた Call Graph の利用 ある時点でアスペクトが作動する=アスペクトを呼び出している 頂点:クラス,アスペクトに含まれるメソッド(手続き)単位 辺:メソッドの呼び出し,アスペクトの呼び出し (呼び出し関係はソースコードから解析) ある時点でアスペクトが作動する=アスペクトを呼び出している 「Call Graphでアスペクトの頂点に到達可能」ならば「アスペクトの影響を受ける」  まず,アスペクトを組み込む段階で,アスペクトの干渉についての情報を開発者に提示します.  アスペクトの干渉を検出するために,アスペクトを含めたCall Graphを作成します.  具体的には,クラスやアスペクトに含まれたメソッドを頂点として,辺としてメソッドの呼び出し,アスペクトの動作を取ります.ある時点でアスペクトが動作する,ということを,アスペクトに対する一種のメソッド呼び出しが起こるとみなします.Call Graph上で,ある頂点から呼び出し辺を辿ってアスペクトの頂点に到達可能であれば,その頂点はアスペクトの影響を受けていると考えることができます.

Call Graph 例 凡例 Aspect Class 無限ループ call このグラフでは,ここにループが存在しており,実行すると無限ループに陥ってしまう可能性を示しています.  プログラムの規模が大きくなるに従ってグラフのサイズも大きくなっていきますので,実際に開発者に提示するには,このグラフを直接与えるのではなく,ループ部分に対するマーキングや警告メッセージの出力など,開発者により理解しやすい形式での出力を行うことになります. Class call

プログラムスライシングの適用 プログラムスライシングとは プログラム解析手法のひとつ 開発者が注目する必要があるコードのみを抽出し,提示する技術 元々は手続き的プログラム用に開発され,オブジェクト指向プログラムに対して拡張されている 依存関係が複雑になるアスペクト指向プログラムに対して有効性が期待される  以上が,アスペクトを組み込む段階での情報の提示でした.Call Graphを用いることで,少なくとも無限ループに陥るような重大な干渉は除去されており,プログラムを実行できるという状態になります.  今度は,実行結果が正しくない場合,その原因を調べるための支援を行います.ここではプログラムスライシングと呼ばれるプログラム解析手法を利用します.プログラムスライシングは,プログラムの中に含まれるデータや制御の依存関係を解析し,開発者が注目する必要があるコードのみを抽出,提示するという手法です.  元々は手続き的プログラムに対して提案されたものですが,オブジェクト指向プログラムに対しても既に拡張され,その有効性が確認されています.モジュール間の依存関係が複雑化になるアスペクト指向プログラムでも,その効果が期待されるため,Call Graphの場合と同様の発想で,手法を拡張します.

プログラムスライスの定義 プログラムのある文sのある変数v(スライス基点<s,v>)の値に“影響”を与えうる文の集合 影響 = 代入-参照 関係, if 文など制御関係 プログラム文を頂点,依存関係を辺としたグラフ探索 プログラマが扱う必要があるコードを提示 デバッグ作業の効率化 1: a = 5; 2: b = a + a; 3: if (b > 0) { 4: c = a; 5: } 6: d = b; 1: a = 5; 2: b = a + a; 3: if (b > 0) { 4: c = a; 5: } 6: d = b; a a 基点< 6, b > b 制御 b  プログラムスライスがどういうものか,例を示して説明します.プログラムスライスは,プログラム文の中のある変数に注目し,その変数の値に影響を与える文の集合のことを言います.ここで言う影響とは,変数の代入・参照関係,if文やwhile文などの制御関係のことです.  ここにプログラムの断片を示していますが,1行目で代入された変数aが2行目で参照されているので,1行目から2行目に依存関係がある,ということになります.同様に,2行目から,3行目と6行目へ依存関係があります.また,4行目が実行されるかどうかは3行目の条件判定によって決定されることから, 3行目から4行目に依存関係がある,ということになります.  ここで,6行目の変数 b に注目して,この変数に対するプログラムスライスを計算すると,右側に示したものになります.この計算は,プログラムの各文を頂点とし,依存関係を有効辺としたグラフにおいて,その依存辺を逆向きに辿っていく探索問題として考えることができます.  求められたプログラムスライスを見ることで,開発者は,その値がどのように決まったかを知ることができます.たとえばデバッグ作業中,ある時点で変数の値がおかしくなっていることに気付いたとすると,その変数を基点にスライスを計算することで,無関係なコードをあらかじめ取り除くことができ,作業を効率的に進めることができます.

スライス計算に必要な情報 データ依存関係 制御依存関係 目的をデバッグに限定 ローカル変数の 代入 → 参照 フィールド(メンバ変数)の 代入 → 参照 制御依存関係 実行制御文の条件節 → 制御される文 メソッド呼び出し文 → 呼び出されるメソッドの文 アスペクトが連動する位置 → 動作するアスペクト 目的をデバッグに限定 実行が失敗するテストケースが特定されている状態を想定 動的(実行時)情報 が利用可能 オブジェクトの区別,動的束縛の解決によってコード量を減らす  プログラムスライスの計算を行うために,データと制御という二つの依存関係を解析します.  データ依存関係は,変数それぞれについて,ある代入文から,そこで代入された値を参照する文への依存関係として定義します.  制御依存関係は,if や while などの実行制御文から制御される文へ,メソッド呼び出し文から呼び出されるメソッドへ,そして,アスペクトが起動される時点から動作するアスペクトへ,という依存関係とします.これは,Call Graphのときと同じ発想です.  目的をデバッグに限定するため,実行が失敗するようなテストケースが特定されている状態を想定します.この特定のテストケースの実行経過を監視し,その情報,たとえばオブジェクトの区別,動的束縛の解決を反映することで,扱うコード量を減少させることができます.

動的情報収集の実装 アスペクトとして動的解析処理を記述する 1つのモジュールにカプセル化可能 実現および実行時コストの軽減 可読性・保守性の向上 実現および実行時コストの軽減 実用上十分な情報が収集可能 Java を対象とした場合は十分に有効† → AspectJ で書かれたプログラム用に拡張  このような実行時情報の収集を実現するために,本研究では,その情報収集処理自体も,アスペクトを用いて記述します.メソッド呼び出しなどに対応して行う処理は,アスペクトを用いて作成すると,実現に必要なコストが非常に安く済ませられるだけでなく,実行時のオーバーヘッドについても小さく済ませることができます.これについては,Javaを対象とした実験結果が既に得られていますので,これをAspectJ用に拡張したものを使用します. † 石尾隆, 楠本真二, 井上克郎: “アスペクト指向プログラミングの動的スライス計算への応用", 2002年電子情報通信学会総合大会講演論文集,D-3-4,p.30 (2002).

スライスツールの実装 統合開発環境 Eclipse への統合 コンパイル時にソースコード情報を収集 実行時情報が存在すれば読み込んで利用 プラグイン形式で機能を追加できる 開発者がエディタ上でそのまま利用できる コンパイル時にソースコード情報を収集 静的依存情報の収集 Call Graphの作成,無限ループ等の指摘 実行時情報が存在すれば読み込んで利用 動的解析モジュールを付加して実行しておく必要あり 実行時情報がなければ静的情報だけでスライス計算  開発者から利用しやすくするという観点から,スライスツールを統合開発環境に組み込む形で実装を行いました.オープンソースの統合開発環境Eclipseが持つ,プラグインによる拡張機構を利用しています.Java,AspectJを対象としたソースコード入力支援プラグインなどが既に提供されており,それにスライス計算機能を上乗せする形式になっています.  プラグインは,コンパイルの実行開始,終了や失敗,ソースファイルの保存など,重要なイベントの通知をフレームワークから受け取ることができます.そこで,現在実装中のスライスツールでは,コンパイル終了時に静的な情報をすべて収集し,Call Graphを構築します.  また,動的解析モジュールを組み込んで実行することで情報を生成し,その情報をスライス計算に使用することができます.実行時情報がなければ,静的情報だけでスライス計算を行います.

プロトタイプのスクリーンショット 3. スライス計算実行を指示 2. スライス基点をエディタ上で選択 4. スライス結果を エディタ上に出力  ツールのスクリーンショットはこのようになっています.  プログラムをコンパイルすると,静的な情報が収集され,スライス計算が可能な状態になります.スライス基準をエディタ上で範囲選択し,ツールバーからスライス計算を指示すると,結果がエディタ上に,ここでは青い波線として表示されています. コンパイル時に静的情報収集

適用実験 適用対象 実験内容 AspectJ サンプルコード 5種類 プログラムの実行時情報解析アスペクト サンプルコードを実行し,その結果に対してプログラムスライスを計算 従来のツールを用いた依存関係の追跡との定性的比較 AJDE: どこでアスペクトが動作するかをマーカーで表示する 各サンプルコードのサイズは平均500行 作成したツールを用いて実験を行いました. 適用対象は,インターネット上で公開されているAspectJのサンプルコード5種類と,プログラムの実行時情報を解析するために作ったアスペクトの合計6種類です. サンプルコードを実行し,その結果に対してプログラムスライスの計算を行い,その有効性に関する定性的な評価を行いました.各サンプルコードのサイズは平均500行となっています.

評価 プログラムスライシングの有用性 アスペクトが増えた分,考慮すべき依存関係は増加 ファイルをまたいだ依存関係:手作業の追跡はコスト大 「依存関係がなくなる」コードの発見が可能 アスペクトの動作によって,実行されなくなるような文が発見できる 実験に関する評価は,次のとおりです. まず,アスペクト指向プログラムでは,横断要素だけがアスペクトというモジュールに分離された分,考慮すべき依存関係の数自体は増加しています.特に,複数のファイルにまたがる依存関係が多いため,手作業での追跡作業はコストが高くなります. また,プログラムスライシングを用いることで,アスペクトの動作によって実行されなくなる,依存関係がなくなるコードを発見できることが示されました.

「依存関係がなくなる」コードの例 開発者が意識する依存関係 実際のスライス結果 void foo() { x = bar(); : }  : } int bar() { return doSomething(); int baz() { return doSomething2(); aspect redirectMethodCall { int around(): call(bar) { return baz(); 実際のスライス結果 void foo() { x = bar();  : } int bar() { return doSomething(); int baz() { return doSomething2(); aspect redirectMethodCall { int around(): call(bar) { return baz(); 依存関係がなくなるコードの例を示します.ここでは,メソッドfooの中でメソッドbarが呼び出されていますが,下にアスペクトがひとつ定義されており,barへの呼び出しに対して動作することがわかります.一見すると,色をつけた四箇所に依存関係がある,と考えられますが,このアスペクトはメソッド呼び出しを「置き換える」アスペクトなので,元のbarへの呼び出しは消えてしまい,実際のスライス結果はこのようになります. このような,開発者が誤解しやすい点をサポートできることが,プログラムスライシングの利点だと言えます. メソッド呼び出しを 置き換えるアスペクト

計算コスト 時間コスト 空間コスト 静的情報の収集=コンパイラが構築した意味解析木に対する1パス処理 動的情報の収集=実行するプログラムに依存,過去の実験では通常の実行に比べて最大で10倍程度 空間コスト アスペクトの種類によってコストに大きな差 多数のクラスを横断して動作するアスペクトは,メモリ消費量が非常に大きい 約10000行のコードに,実行時情報解析アスペクト(1000行)を追加した結果,必要メモリが20MBから500MB以上に増加 プログラムスライス計算に必要なコストについても説明しておきます. まず時間コストについてですが,プログラムスライスの計算では,実際のグラフ探索よりも,プログラムの依存関係をグラフ化するのに必要な時間が大きな問題となります.静的情報と動的情報の二つがありますが,静的情報については,コンパイラが構築した意味解析木に対する1パス処理として実装しているため,構文木のサイズ,ソースコードの量に比例するものとなっています. 動的情報の収集については,実行するプログラムに依存しますが,過去の実験では,通常の実行に比べて最大で10倍程度となっていたので,バグを明確にする小さいテストケースを特定できれば,実用的な範囲で抑えられると考えます. 空間コストについては,アスペクトの種類によって大きな差が出ることが分かりました.多数のクラスを横断して動作するアスペクトは,依存関係の量を大きく増加させます.このようなアスペクトについては,何らかの特別な扱いをしなければ,より大規模なソフトウェアに対する適用は難しい,ということが分かりました.

まとめ アスペクト指向プログラミングの特徴 Call Graphを用いた干渉の検出 プログラムスライシングの適用 今後の課題 横断要素のモジュール化 保守性,再利用性の向上 ソースコードの見た目と動作とのギャップが拡大 Call Graphを用いた干渉の検出 アスペクトの動作を,メソッド呼び出しと等価とみなす ループ等,実行を不可能にするような重大な干渉の提示 プログラムスライシングの適用 従来手法に,「アスペクト呼び出し」を追加 静的情報,実行時情報を組み合わせた開発者の支援 アスペクトによる振る舞いの変化を示す 今後の課題 多数のオブジェクトを横断するアスペクトの効率的な扱い 最後にまとめます.  アスペクト指向プログラミングの特徴は,横断要素のモジュール化にあります.複数のオブジェクトが関わる処理を単一のモジュールにまとめることで,保守性,再利用性を向上させることができます.しかし,ソースコードの見た目と実際の動作との間のギャップが拡大するという問題があります.  これに対して,まずCall Graphを用いたアスペクト干渉の検出を行いました.アスペクトの動作をメソッド呼び出しと同様に考えて呼び出し関係をグラフ化し,無限ループの発生のような,実行を不可能にするような重大な干渉を検出し,開発者に提示します.  また,実行した結果が正しくないと判明した際には,その原因の調査を支援するために,プログラムスライシングの適用を行います.プログラムスライシングは,依存関係を追跡して,開発者が調査すべきコードを抽出・提示する手法です.ソースコードの静的な情報と,実行時情報を組み合わせて,開発者の支援を行います.アスペクトによる依存関係の変化を開発者に提示できる点が特徴です.  今後の課題として,多数のオブジェクトを横断したアスペクトの効率的な扱い,スケーラビリティの実現が挙げられます.

オブジェクトの横断要素 横断要素=複数のオブジェクトに要求される特性 横断要素をモジュール化する単位「アスペクト」の導入 例:「データベースでエラーが起こったらユーザの指示を仰ぎたい」 例:「デバッグ用に,オブジェクトに送られたメッセージを記録したい」 処理が複数のオブジェクトに分散する  → 分散したコードの一貫性の維持が困難 変更すべき場所を変更し忘れる 変更すべきでない場所まで一緒に変更してしまう 書かれたコードを後で見て,どこまでがその処理に関連するか分からない 横断要素をモジュール化する単位「アスペクト」の導入 しかし,複数のオブジェクトに要求される特性は,担当者を決められないためにうまく扱えないという問題があります.たとえばデータベースでエラーが起こったらユーザの指示を仰ぎたい,デバッグ用にオブジェクトに送られたメッセージを記録したい,といった要求です.  このような,複数のオブジェクトが関わる処理のことを横断要素と呼びます.横断要素のコードは,それに関わるすべてのオブジェクトに分散するために一貫性の維持が難しく,保守性の悪化要因となります.  横断要素が複数のオブジェクトに分散するために問題が発生するのですから,それを一箇所にモジュール化することで解決しよう,というのがアスペクト指向プログラミングの基本的なアイディアです.そのために,新しいモジュール単位アスペクトを導入します.

利用例:プログラムの実行時情報収集† オブジェクト指向プログラムの実行経過を観測する 抽出した情報の主な用途 メソッドの呼び出し関係 データの依存関係(代入-参照) 抽出した情報の主な用途 デバッグ支援 ソフトウェアの定量的評価(複雑さ,品質等) 次の例は,アスペクトの応用例で,プログラムの実行時情報の収集,つまりプログラムの実行経過を監視し,メソッドの呼び出し関係やデータの代入-参照関係などを解析する処理です. これは,解析した結果をデバッグ支援に用いたり,たとえばメソッド呼び出しの深さであるとか,ある処理に関与するデータ個数などに,ソフトウェアの複雑さや品質などを評価するための定量的な値を算出するために利用されます.

その他のアスペクトの利用例 アスペクトによるトランザクションの実現† GoF デザインパターンのアスペクトによる書き換え‡ 種々のトランザクションメカニズムを利用したトランザクションのモジュール化 GoF デザインパターンのアスペクトによる書き換え‡ デザインパターン=オブジェクトの「連携のやりかた」のパターン 設計レベルでの再利用,使うときは個別のコードを書く パターンに関連するオブジェクトにコードは分散する いくつかのパターンは,単独のアスペクトに簡潔に記述することができる アスペクトとして再利用可能なコードになったパターンも存在 さて,他にも,いくつものアスペクトの利用が報告されています.たとえば,データベースなどに対するトランザクション処理や,オブジェクト指向でデザインパターンとして知られるオブジェクトの連携パターンをアスペクトで実装した例があります.特にデザインパターンのいくつかでは,オブジェクト指向による実現に比べて,分散したコードの局所化が達成されたものや,パターンを実装したコードの再利用可能性が達成されたものもあります.従来は,パターンはあくまでパターンであり,プログラマが個々の状況に合わせて実際のコードを書かなければならなかったのですが,それが再利用可能なモジュールとしての記述に成功した例も報告されています. † S. Soares, E. Laureano, P. Borba: `Implementing Distribution and Persistence Aspects with AspectJ'', OOPSLA 2002 ‡ J. Hannemann, G. Kiczales: ”Design Pattern Implementation in Java and AspectJ'‘, OOPSLA 2002

情報収集の従来の実現方法 「監視」処理は対象ソフトウェア全体に影響する Java を対象とした場合のその他の実現方法 単純な実装:対象ソフトウェアの各所でログを生成する → アスペクトでモジュール化するべき Java を対象とした場合のその他の実現方法 Java Virtual Machine (JVM)の改造 移植性がない,実現に必要なコストが高い JVMの持つ Profiler Interface の利用 実行時のコストが高い,バイトコード最適化で結果が変わる プリプロセッサによるソースコード変換 構文木の変換ルールが複雑,保守性が低い このような目的に対して,ソースコードからの情報収集は構文解析や意味解析を実行するだけでよいのですが,実行時の情報収集では,その実現方法が問題となってきます. プログラムの実行状態を監視する処理が必要となりますが,この監視処理そのものも,対象ソフトウェア全体に影響するものとなっています.単純な実装では,対象ソフトウェアの各所でログを生成するという形式ですが,これは,アスペクト指向において,アスペクトで実装すべき処理のひとつとなっています. 対象とするプログラム言語として Java を選んだ場合,他にも次の三つのような選択肢があります.Java の実行環境である Java Virtual Machine の改造,Java Virtual Machine が公開している Profiler Interface と呼ばれる性能計測インタフェースの利用,プリプロセッサによるソースコードの変換です. ひとつめの JVM の改造という方式は,改造元となる JVM のバージョンに依存してしまうこと,つまりバージョンアップに対応して毎回作り直す必要があること,実現に必要なコストが高いという問題があります. 二番目のProfiler interface の利用という方式は,元々性能計測用のインタフェースであるため,メモリの確保や解放,スレッドの利用などの粒度の細かい情報が得られますが,逆に,データ依存解析のようなフィールドの参照や代入,メソッドの呼び出しといった粗い粒度の情報を得ようとするには,オーバーヘッドが若干高めになってしまうこと,バイトコード最適化の影響で結果が変わってしまうことなど,いくつかの弱点が知られています. プリプロセッサによるソースコードの変換は,この三つの中では一番有望な選択肢ですが,構文木ベースでの変換ルールは記述の手間が多く,現状では再利用しにくい問題があります.アスペクトによる実装は,アスペクトを注意深く記述する必要はありますが,導入が容易で,実現に要するコストが小さいものとなっています.

アスペクトによる実装の利点 アスペクトとして動的解析処理を記述 1つのモジュールにカプセル化可能 実現および実行時に要するコストの軽減 可読性・保守性の向上 実現および実行時に要するコストの軽減 実用上十分な情報が収集可能 成果については論文投稿中† アスペクトによる実装の利点をまとめると,このようになります. まず,アスペクトとしてひとつのモジュールにカプセル化が可能となります.これは,可読性と保守性の向上をもたらします. 次に,実現に要するコストを低く抑えることができ,また,実行時に要するコストも,コンパイラの最適化などの恩恵を受けることができるため,抑えやすいものとなっています. また,オブジェクト指向プログラムに対して,アスペクトを付加して情報を収集することは既に実現しており,実用上十分な情報が収集できることが分かっています.これについては,成果を論文投稿中です. †: 石尾 隆,楠本 真二,井上 克郎: アスペクト指向プログラミングの 動的プログラムスライスへの応用,情報処理学会論文誌,投稿中

アスペクト指向の「複雑さ」 アスペクトは便利だが…… オブジェクトを見ただけでは動作がわからない アスペクトの干渉 単純な代入文でさえも,アスペクトが連動していることがある アスペクトが,予想外の場面で作動してしまう可能性がある アスペクトの干渉 アスペクトの動作順序で実行結果が変わる アスペクトの動作中に別のアスペクトが動作する  さて,ここまでアスペクト指向プログラミングがもたらす利点について説明しました.アスペクトの利便性については広く認められるようになってきましたが,プログラムの複雑さという観点では,新たな問題を導入しています.  今までオブジェクト指向プログラミングでは,「誰が何をするか」を順番に書き下していたところが,アスペクト指向では「いつ,何をするか」という記述を列挙する方法に変わりました.そのため,ひとつのファイルに書いてあるプログラムの一部分を見ただけでは,その動作が分からなくなっています.単純な代入文ですら,それに連動するようなアスペクトがあるかもしれません.開発者が不用意なコードを書くと,予期せぬアスペクトの動作を引き起こす場合があります.  また,アスペクトの干渉と呼ばれる問題があります.これは,単一のイベントに対して複数のアスペクトが動作するとき,その動作順序によって実行結果が変わってしまったり,アスペクトの動作中に別のアスペクトが動作するために,本来意図した振る舞いにならないという問題です.干渉によって発生するバグは,原因の特定が非常に難しいことが知られています. このような問題に対して,統合開発環境などのツールによる,アスペクトの表示やデバッグ支援といったサポートが非常に重要な要素となっています. ツールによるサポートが重要! アスペクトの表示 デバッグ支援

アスペクト干渉とは アスペクトが他のアスペクトに影響を与える 単体では正しいアスペクトでも,正しい動作が阻害されることがある 以下は無限ループの例 Client Object Disk I/O Object ディスク I/O を ネットワーク I/O にマップする アスペクト Network I/O Object  ではまず,アスペクト干渉について説明します.アスペクト干渉とは,アスペクトが他のアスペクトの動作に影響を与えることで,単体では正しいアスペクトでも,同時に使用すると正しい動作が阻害されることがあるという問題です.  図として,無限ループの例を挙げています.二つのアスペクト,ひとつはディスクI/OをネットワークI/Oにマップするアスペクトで,もうひとつは,ディスクI/O以外のすべての呼び出しをディスクに記録するためのアスペクトです.前者はシステムの機能として,後者はデバッグ等に利用されるものです.それぞれ,単体では正しい動作をします.  しかし,二つを同時に用いると次のように問題が生じます.Client Objectがデータをディスクへ書き出そうと送ったメッセージを,アスペクトがとらえて,ネットワークへ出力しようとします.ここで,ディスクI/O以外の呼び出しはディスクに記録しよう,とアスペクトが作動し,Disk I/Oオブジェクトへメッセージを送ります.このメッセージさえもネットワークI/Oへマップしようとしますから,この呼び出しもまたディスクに記録する対象となる,というようにループに陥ってしまいます.  ここでは単純な例ですが,二つではなく三つ以上のアスペクト,また複数のオブジェクトを経由してアスペクトが動作するようになると,開発者が気付く可能性はほとんど期待できません. ディスク I/O 以外の呼び出しを ディスクに記録するアスペクト

アスペクト干渉に対する方針 アスペクトの干渉は必要な場合もある ディスク I/O を置き換えるアスペクトなど コンパイル時に干渉可能性を検出してユーザに通知,実行するかどうかはユーザの選択  アスペクト干渉をどう扱うかですが,ここで重要な点は,アスペクトの干渉は必要な場合もある,ということです.もし他のアスペクトに干渉できないとなると,先ほどのディスクI/Oの置き換えアスペクトは,他のアスペクトが勝手にディスクにデータを書き出すことを止められません.  そこで,コンパイル時に干渉の可能性を検出し,開発者へ通知を行います.アスペクトがどのように関連しあっているか,特に先ほどのような無限ループに陥る可能性を通知し,開発者が意図していない関連性が生じていないか確認する機会を提供することにします.

スライスツールの動作概要 スライス 計算 スライス結果 依存関係解析 アスペクト スライス対象 ソースコード (含アスペクト) AspectJ Compiler アスペクト結合済み クラスファイル 通常の JVM 依存関係情報 通常の実行結果  ここで,実際のツールがどういう手順でスライスを計算するか,ということを説明します.最初にスライスをとりたいプログラムのソースコードと,依存関係解析のアスペクトを一緒に AspectJのコンパイラを用いてコンパイルします.コンパイラはアスペクトが結合されたクラスファイルを生成します.この結合結果は通常の Java バイトコードとなっているので,標準の JVM 上で実行することができます.依存関係解析アスペクトは,解析結果をファイルに出力します.得られた実行時情報と,ソースコードを解析して得られた静的依存関係から,最終的にスライスを計算・出力します。

情報収集: 動的 or 静的 目的をデバッグに限定 データ依存関係 制御依存関係 実行が失敗するテストケースが特定されている状態を想定 動的(実行時)情報 が利用可能 オブジェクトの区別,動的束縛の解決によってコード量を減らす データ依存関係 フィールド(メンバ変数)の 代入 → 参照 関係 ローカル変数の 代入 → 参照 関係 制御依存関係 実行制御文の条件節 → 制御される文 メソッド呼び出し文 → 呼び出されるメソッドの文 アスペクトが連動するメッセージ → 動作するアスペクト  ここではさらに,必要な情報をどのように集めるか,という問題があります.選択肢は,ソースコードから静的に解析するか,プログラムを実際に実行して動的に収集するか,という二つです.  デバッグを支援するという目的に限定すると,開発者が,実行結果が正しくないようなテストケースを特定して,実際にバグがどこにあるか探そうとしている状況が想定できます.ですから,そのテストケースを実際に実行した時の情報をできるだけ利用することが望ましいということになります.ただし,すべて実行時の情報から計算しようとすると,プログラムの実行系列というのは一般にソースコードに比べて非常に大きなものとなるので,現実的ではありません.  実行時情報を用いるものを,スライドでは,赤字で示しています.フィールドの代入・参照ではオブジェクトの区別を,メソッド呼び出しについては動的束縛の解決を行います.特に動的束縛の解決は,「呼ばれる可能性はあるが実際には呼ばれなかったコード」をメソッド単位でスライスから除去するために重要です.また,アスペクトの動作についても,実際の順序がどうであったかということを重視するため,実行時情報を用います.  ローカル変数や実行制御文は,厳密に観察するにはコストがかかりすぎることから,静的解析のみで対応します.

関連研究 AspectJ† IDE for JBuilder, Forte, Emacs ソースコードエディタで,オブジェクトのコード上にアスペクトの連動位置を表示する アスペクト干渉の検出は行わない アスペクト指向プログラムに対するプログラムスライス計算の提案‡ 提案だけ,有効性については評価されていない  この分野で,現在までに行われている研究のうち,二つを紹介します.まず一つ目は,AspectJ IDE と呼ばれるものです.Javaのアスペクト指向拡張言語であるAspectJを対象に,JBuilder, Forte, Emacs といった開発環境のエディタ上で,どのアスペクトが連動するかを表示するというものです.アスペクトの存在を意識してコードを書くことができますが,アスペクト干渉などについては,開発者が手作業で調べるしかありません.  もう一つは,アスペクト指向プログラムに対する,ソースコード情報を用いたプログラムスライス計算の提案です.これは,提案だけが成されているものの,実際にツールとして実装されているわけではなく,有効性についても評価されていない,というのが現状です. †: AspectJ Official Site: http://www.eclipse.org/aspectj/ ‡: Jianjun Zhao, “Slicing Aspect-Oriented Software”, In Proc. of the 10th IEEE International Workshop on Programming Comprehension, pp.251--260, 2002