豊富な情報を基にした pointcut

豊富な情報を基にした pointcut
を記述できるアスペクト指向言語
東京工業大学大学院 情報理工学研究科
数理・計算科学専攻 千葉研究室
02M37220 中川 清志
Feb. 6, 2004
2003年度 修士論文発表会
1
アスペクト指向(AOP)

オブジェクト指向の限界



ある種の処理は複数クラスに散らばる
ロギング,同期,永続性などの処理
アスペクト指向の利点



そのような処理をアスペクトとしてモジュール化
クラスとアスペクトは分離して記述
オブジェクト指向を補完
Feb. 6, 2004
2003年度 修士論文発表会
2
AOPの目標:図形エディタの例

目標:
「図形の外観変化を起こすメソッド」
の後にScreenを更新したい

図形クラスからScreen更新命令
 最終的には図形クラス内の
draw() メソッドが呼ばれる
これらのメソッドの最後には
Screenを更新するコードが必要
Feb. 6, 2004
2003年度 修士論文発表会
Screen
FigureElement
draw()
Point
Line
int x, y
Point p1, p2
getX()
getY()
getP1()
getP2()
setX(int)
setY(int)
move(int,int)
setP1(Point)
setP2(Point)
move(int,int)
draw()
draw()
3
AOPの目標:図形エディタの例
「従来の方法では」
void setP1(Point newP) {
p1 = newP;

screen.update();
更新のための命令が
各クラス、メソッドに散らばってしまう

}
void move(int
dx, int dy) {
FigureElement
p1.move(dx, dy);
p2.move(dx, dy);
draw()
保守性・再利用性が悪い
screen.update();
}
Point
void setX(int newX) {
x = newX;
int x, y
Point p1, p2
}
getX()
getY()
getP1()
getP2()
setX(int)
setY(int)
move(int,int)
setP1(Point)
setP2(Point)
move(int,int)
draw()
draw()
screen.update();
void move(int dx, int dy) {
x += dx; y += dy;
screen.update();
}
Feb. 6, 2004
Line
2003年度 修士論文発表会
4
AOPの目標:図形エディタの例
「AOPでは」
screen.update();
void setP1(Point newP) {
p1 = newP;


更新のための命令
を分離して記述
処理系 weaver
により合成
アスペクト:
これらのメソッドの
最後には
screen.update() を
実行せよ
}
void move(int
dx, int dy) {
FigureElement
p1.move(dx, dy);
p2.move(dx, dy);
draw()
screen.update();
}
Point
Line
void setX(int newX) {
x = newX;
int x, y
Point p1, p2
}
getX()
getY()
getP1()
getP2()
setX(int)
setY(int)
move(int,int)
setP1(Point)
setP2(Point)
move(int,int)
draw()
draw()
screen.update();
void move(int dx, int dy) {
x += dx; y += dy;
screen.update();
}
Feb. 6, 2004
screen.update();
2003年度 修士論文発表会
5
AOPの目標:図形エディタの例
「AOPでは」
screen.update();
void setP1(Point newP) {
p1 = newP;


更新のための命令
を分離して記述
処理系 weaver
により合成
アスペクト:
これらのメソッドの
最後には
screen.update() を
実行せよ
screen.update();
}
void move(int
dx, int dy) {
FigureElement
p1.move(dx, dy);
p2.move(dx, dy);
draw()
screen.update();
}
weaver Point
void setX(int newX) {
x = newX;
int x, y
screen.update();
}
getX()
getY()
「どこに合成したいか?」を
「どこに合成したいか?」を
setX(int)
どのように指示するかが問題!!
setY(int)
}
Feb. 6, 2004
2003年度 修士論文発表会
Point p1, p2
getP1()
getP2()
move(int,int)
setP1(Point)
setP2(Point)
move(int,int)
draw()
draw()
void move(int dx, int dy) {
x += dx; y += dy;
screen.update();
Line
6
AspectJ*における
合成箇所の指定方法の問題点

コードを挿入するメソッドを
全て書き並べる必要あり
FigureElement
call(void Point.set*(int))
|| call(void Point.move*(..))
|| call(void Line.set*(Point))
|| call(void Line.move*(..))

しかし、保守性・再利用性が悪い
draw()
Point
int x, y
Point p1, p2
getX()
getY()
getP1()
getP2()

見落とす可能性がある

例えばLine.rotate(..)というメソッド setX(int)
setY(int)
メソッドの追加、
move(int,int)
名前変更などに弱い
draw()
Feb. 6, 2004
2003年度 修士論文発表会
Line
setP1(Point)
setP2(Point)
move(int,int)
draw()
* Kiczales等 ECOOP1997
7
必要とされる合成箇所の指定方法

深い情報を基にして、コードを挿入
するメソッドを指定したい
「“draw”メソッドの中で読み込まれる
フィールドのどれか」をそのボディ中で
更新するような、“Point”クラス内の全
てのメソッド

メソッド名を
書き並べなくてもよい
つまりは赤い
枠内のメソッド
Feb. 6, 2004
2003年度 修士論文発表会
FigureElement
draw()
Point
Line
int x, y
Point p1, p2
getX()
getY()
getP1()
getP2()
setX(int)
setY(int)
move(int,int)
setP1(Point)
setP2(Point)
move(int,int)
draw()
draw()
8
pointcut の記述力が高い
AOP言語 Josh

きめ細かい「どこに合成するか(pointcut)」の
指示が可能

pointcut 記述言語の拡張


Java で拡張
リフレクションの使用


Javassist[Chiba00] を使用
汎用的な「何を合成するか」の記述

合成箇所の情報を利用したインタータイプ宣言
本発表は、前者の「pointcut」についてのみ説明する
Feb. 6, 2004
2003年度 修士論文発表会
9
pointcutのメカニズム


アスペクトの合成場所の指定
言い換え:
joinpoint (実行点)の選別作業


メソッド呼び出し
フィールド参照
インスタンス生成 etc.
プログラム
条件と対象joinpoint のペア
例:

joinpoint
「setXという名前の」
メソッド呼び出し
「Lineクラスの」フィールド参照
この箇所にアスペクト
合成決定!!
対象 joinpoint
条件:名前が setX
pointcut
Feb. 6, 2004
2003年度 修士論文発表会
10
pointcut の記述方法

pointcut 指定子を使い記述

指定子は、対象joinpoint と選別方針を持つ
例:call (“void *.setX(..)”)

「void 型の“setX”で引数とクラス名は任意」という
メソッド呼び出しを指定


Feb. 6, 2004
call は pointcut 指定子で、メソッド呼び出しが対象
カッコ内は条件
2003年度 修士論文発表会
11
Josh が提供する
強力な pointcut の原理

pointcut指定子をユーザが新たにJavaで定義可能

joinpoint の選別方針をJavaで定義


従来は言語組み込みの指定子のみ使用可
joinpoint をJavaのオブジェクトで表現して公開

そのjoinpointの情報を得るメソッドを提供

Feb. 6, 2004
リフレクションを使い豊富な情報を入手
2003年度 修士論文発表会
12
pointcut指定子  boolean 型メソッド
before :
call (“void Point.setX()”) {
/* アドバイスボディ */ }

pointcut 指定子を boolean
型のメソッド呼び出しへ変換

新たに boolean メソッドを
定義すれば指定子として使用可能
アドバイスボディとは
指定された箇所で実行される
コード断片
コード変換器
if ( call( jp, “void Point.setX()”, jc)) {
/* アドバイスボディ挿入 */ }
jp : Java で表現された
jc : joinpoint に
joinpoint のオブジェクト
関連する情報を持つ
Feb. 6, 2004
2003年度 修士論文発表会
13
新たなpointcut指定子の定義例
(1/2)
使用例:
例:simpleCall
という
simpleCall(“setX”)
[引数の決まりごと]
pointcut指定子を定義

第一引数で対象とする
joinpointを指定


Stringの配列で、
条件を受け取る


ここではメソッド呼び出し
args[0] = “setX”
static boolean simpleCall
(MethodCall m,String[] args,
JoshContext jc) {
String name1 =
m.getMethodName();
String name2 = args[0];
return
name1.equals(name2);
}
JoshContext は有用な
情報を保持
内容:メソッド呼び出しの中で、メソッド名が
“setX”というものを選別する
Feb. 6, 2004
2003年度 修士論文発表会
14
新たなpointcut指定子の定義例
(2/2)
使用例:
 name1 :
simpleCall(“setX”)
[ボディの記述]


m.getMethodName();
String name2 = args[0];
return
name1.equals(name2);
name2 :


このメソッド呼び出しjoinpoint
static boolean simpleCall
において、呼び出された
(MethodCall m,String[] args,
メソッド(callee)の名前
JoshContext jc) {
 joinpointオブジェクト
String name1 =
から入手
この例では
name2 = “setX”
name1とname2が
一致したら真を返す
Feb. 6, 2004
}
内容:メソッド呼び出しの中で、メソッド名が
“setX”というものを選別する
2003年度 修士論文発表会
15
複雑なpointcut指定子の定義例
[図形エディタ問題の解決]

updater 指定子を定義
内容:「drawメソッドで読み込まれる
フィールドを更新する」
メソッド呼び出しを選別する
使用例:updater(“Point”, “draw”)


図形エディタの問題を解決
リフレクションの使用

より深い情報を得られる
Feb. 6, 2004
static boolean updater(MethodCall mc,
String[] args, JoshContext jc) {
CtClass root = jc.getCtClass(args[0]);
String mname = args[1];
Hashtable fields =
enumerateFields(root, mname);
CtMethod mth = mc.getMethod();
mth.instrument(new ExprEditor() {
public void edit(FieldAccess expr) {
String name = expr.getFieldName();
if (expr.isWriter() &&
fields.get(name) ==
expr.getCtClass())
return true;
}
return false;
}
2003年度 修士論文発表会
16
Josh 処理系の全体図
.josh
独自言語で書いた
アスペクト
コード変換器
.class
アスペクト埋め込みの
ターゲット
weaver
.class
pointcut 指定子の定義
pointcut の使用
& アドバイス
Feb. 6, 2004
2003年度 修士論文発表会
.class
アスペクトとクラス
の両方の機能
17
比較実験

実験内容

Josh と AspectJ の 性能比較



weave時間
weave済みプログラムの実行時間
実験環境




Feb. 6, 2004
SunBlade1000
UltraSPARC-III 750MHzX2, Memory 1GB
Solaris8
Sun JDK 1.4.0_01, AspectJ 1.1b2
2003年度 修士論文発表会
18
実験(1)



weave 対象:XML解析器 Xerces
アスペクト:全ての public メソッド呼び出しの前にカウ
ンタをいれる
結果


Josh の方が weave 時間は少ないが
実行時オーバヘッドがある
コード長が大きくなっている

アドバイスをインライン展開しているため
コンパイル +
weave(秒)
実行(ミリ秒)
コード長(KB)
オリジナル
36.2(javacのみ)
408
1928
Josh
77.7(69%)
1106(130%)
4269(153%)
AspectJ
112
881
2787
Feb. 6, 2004
2003年度 修士論文発表会
19
実験(2)



結果

[秒]
weave対象:JavaGrande ベンチマークプログラム
アスペクト:あるクラスのオブジェクトを対象とした
メソッド呼び出しの前にカウンタをいれる

先ほどと同様に、Josh は weave 時間が少ないが
実行時オーバヘッドがある
AspectJ は最適化に力をいれているため
10
8
weave 時間
6
4
2
[秒]
Josh
AspectJ
0
40
30
実行時間
20
10
0
Eu le r
Feb. 6, 2004
Mo le c u lar
Mo n t e Car lo
R a y Tr a c e r
JavaGrande ベンチマークの種類
2003年度 修士論文発表会
S e ar c h
20
関連研究

アスペクト指向言語




AspectJ
Hyper/J
Composition Filters
pointcut の拡張

pointcut を論理型言語で記述


Feb. 6, 2004
Brichau等 [GPCE2002]
Gybels等 [AOSD2003]
2003年度 修士論文発表会
21
まとめ

アスペクト指向言語 Josh を提案 [AOSD2004]

pointcut に関して高い記述力を持つ

pointcut 指定子を新たに Java で定義できる
複雑な pointcut が可能

汎用的な指定子は組み込みで与える



複雑なものだけを自分で定義すればよい
Josh の性能を AspectJ と比較

Feb. 6, 2004
コンパイル時間は少ないが、
実行時のオーバヘッド有り
2003年度 修士論文発表会
22