PowerPoint プレゼンテーション

pointcut に関して高い記述力を持つ
アスペクト指向言語 Josh
東京工業大学
中川 清志 千葉 滋
SPA 2003, Hakone
1
アスペクト指向(AOP)

オブジェクト指向の限界



ある種の処理は複数クラスに散らばる
ロギング、同期、永続性などの処理
アスペクト指向の利点



そのような処理をアスペクトとしてモジュール化
クラスとアスペクトは分離して記述
オブジェクト指向を補完
SPA 2003, Hakone
2
AOPの利用例:[ロギング]

従来は


アプリケーション内にロギング
コードを記述
ログ出力のタイミングや方式
が変わるとアプリケーション
のコードの変更も必要
class Log {
static void print(String msg) {
System.out.println(msg);
}
}
class Car extends Vehicle {
void start() {
Log.print(“start Car”);
...
}
void back() {
Log.print(“back Car”);
}
}
class Bike extends Vehicle{
void start() {
Log.print(“start Bike”);
...
}
}
SPA 2003, Hakone
3
AOPの利用例:[ロギング]

AOPでは

アプリケーションと分離して記述
アスペクト :
メソッド実行前には Log クラス
の print()を呼べ!
class Log {
static void print(String msg) {
System.out.println(msg);
}
}
class Car extends Vehicle {
void start() {
必要なし
Log.print(“start Car”);
...
}
void back() {
必要なし
Log.print(“back Car”);
}
}
class Bike extends Vehicle{
void start() {
Log.print(“start Bike”);必要なし
...
}
}
SPA 2003, Hakone
4
合成処理 weave


アスペクトを各クラスに埋め込む処理
アスペクトは以下の2つを指定


1. どこに埋め込むか (pointcut)
2. 何のコードを埋め込むか(アドバイス)
クラス
アスペクト
本研究は前者の pointcut に注目したものである
SPA 2003, Hakone
5
pointcut のメカニズム

条件に応じた join-point の抽出

join-point とはプログラム中の個々の演算

メソッド呼び出し、フィールド参照、インスタンス生成など
例 : call(void Point.setX(int))
[AspectJ*の文法]
 call は pointcut指定子の一つ


メソッド呼び出し join-point の抽出
カッコ内は条件

void型、Pointクラス、setXという名前、
int型の引数を一つ持つ
* Kiczales等 ECOOP1997
SPA 2003, Hakone
6
pointcut の記述力が高い
AOP言語 Josh

Java で新しい pointcut指定子を定義可能


強力な pointcut が可能
既存言語では組み込み指定子に限定


記述できない 複雑な pointcut の存在
汎用的な指定子は組み込みで提供

複雑な pointcut指定子のみ定義すればよい
SPA 2003, Hakone
7
複雑なpointcut例 : 排他制御
マルチスレッドにおいて、フィールド‘balance’
の一貫性を保持したい
解決方法:
class BankAccount {
ここでフィールドの

int balance;
public void withdraw(int bal){
if (balance < bal)
「balanceにアクセス 値を調べても
している全メソッド」
をsynchronizedにする

throw new BankException();
しかしながら,

「balanceにアクセスしている
全メソッド」という条件の
pointcutを記述できない
}
}
balance -= bal;
この命令の前に値が変
えられてるかもしれない
SPA 2003, Hakone
8
Josh weaver

クラス内の各コードを全てチェック

1. join-point の発見




アスペクト埋め込みの
ターゲットクラス
表 : 発見対象の join-point 一覧
2. join-point オブジェクトを渡す
3. pointcut に該当するかの決定
4. アドバイス埋め込み
MethodCall
フィールド参照
FieldAccess
インスタンス生成 NewExpr
Cast
instanceof 式
Instanceof
4
weaver
3
メソッド呼び出し
キャスト式
1
2
アスペクト
SPA 2003, Hakone
9
pointcut 指定子の定義(1/2)


boolean 型のメソッドで定義
第一引数 : 対象とする
/* pointcut メソッドの定義例*/
join-point オブジェクト
static boolean simpleCall

weaver から受け取る
メソッド呼び出し
MethodCall
フィールド参照
FieldAccess
インスタンス生成 NewExpr
キャスト式
Cast
instanceof 式
Instanceof
}
(MethodCall m,String name){
String name2 =
m.getMethodName();
if (name.equals(name2))
return true;
else
return false;
SPA 2003, Hakone
10
pointcut 指定子の定義(2/2)

join-point の情報を入手可能

名前、属するクラス、型など
例 : MethodCall クラス


getMethodName(),
getClassName()
メタオブジェクトの操作

getMethod()でメソッドの
メタオブジェクト
 深い情報を得られる
/* pointcut メソッドの定義例*/
static boolean simpleCall
(MethodCall m,String name){
String name2 =
m.getMethodName();
if (name.equals(name2))
return true;
else
return false;
}
SPA 2003, Hakone
11
Josh アスペクト 全体のコード
アスペクトの宣言
通常のJava要素
pointcut 指定子の
定義
pointcut の使用
& アドバイス
aspect LogAspect {
static int count = 0;
static void log() {
System.out.println
(“callhello” + (count++));
}
static boolean simpleCall
(MethodCall m, String name) {
/* 省略 */
}
before :
LogAspect.simpleCall(“hello”) {
LogAspect.log();
}
join-pointオブジェクト
}
の実引数は必要ない
SPA 2003, Hakone
12
Josh実行までの概観
.josh
独自言語で書いた
アスペクト
コード変換
.class
Java の要素
.class
アスペクト埋め込みの
ターゲット
weave
.class
pointcut 指定子の定義
pointcut の使用
& アドバイス
SPA 2003, Hakone
.class
アスペクトとクラス
の両方の機能
JVM
13
コード変換

独自文法のアスペクトを
Javaコードに変換

simpleCall の対象
join-point は MethodCall
before : simpleCall(“hello”) {
System.out.println(“-hello is called-”);
}
コード変換
引数 ‘m’ はWeaver
から渡される
join-pointオブジェクト
replace はjoin-pointの
コードを変える(アドバイス)
public void edit(MethodCall m) {
if (simpleCall(m, “hello”)) {
m.replace
(“Sysetem.out.println(\”-hello is called-\”);
$_ = $proceed($$);”);
}
} SPA 2003, Hakone
14
weaver のコード

CtClass, CtMethod :


public void weave(CtClass target,
ExprEditor editor){
ExprEditor :


クラス、メソッドを表す
メタオブジェクト
CtMethod[] methods =
target.getDeclaredMethods();
pointcut & アドバイスを
持つ Java コード
for (int i=0; i < methods.length; i++)
instrument(editor) :

メソッドの中身を
editorで走査、改変
methods[i].instrument(editor);
}
target.writeFile();
SPA 2003, Hakone
15
「join-pointの実行時情報」引き渡し
例えばメソッド呼び出しターゲットの、インスタンスの情報

AspectJ では

pointcut 命令内に記述


target (p)
Josh では


/* AspectJ での引き渡し*/
before(Point p) :
call(void Point.*()) && target(p) {
String targetObj = p.toString();
System.out.println(targetObj);
}
明記する必要なし
ドル記号‘$’で始まる予約語
/* Josh での引き渡し*/
 $0 :
before :
join-point の動作の対象
LogAspect.simpleCall(“hello”) {
String targetObj = $0.toString();
となっているオブジェクト
System.out.println(targetObj);
 $1, $2, ...
}
 $r
SPA 2003, Hakone
16
関連研究

アスペクト指向言語




AspectJ
Hyper/J
Composition Filters
pointcut の拡張

Soul/AOP [Brichau等 GPCE2002]
pointcutを論理型言語で記述
 埋め込むコードはSmalltalkで記述

SPA 2003, Hakone
17
まとめ

アスペクト指向言語 Josh を提案

pointcut に関して高い記述力を持つ
pointcut 指定子を新たにJavaで定義できる
 複雑な pointcut が可能


汎用的なものは組み込みで与える

複雑なものだけを自分で定義すればよい
SPA 2003, Hakone
18
SPA 2003, Hakone
19
SPA 2003, Hakone
20
(旧)pointcut 指定子の定義方法
boolean set(FieldAccess f, String type,
String dec, String name) {
CtField cf = f.getField();
String cf_name = cf.getName();
String cf_type = cf.getType().getName();
String cf_dec = cf.getDeclaringClass.getName();
if (f.isWriter() &&
cf_name.equals(name) &&
cf_type.equals(type) &&
cf_dec.equals(dec))
return true;
else
return false;
}
SPA 2003, Hakone
21
従来のAOP言語のpointcutの問題点

組み込み(built-in)のpointcut指定子しか使
用できない


意図した場所にpointcutできない、つまりアスペ
クトを埋め込めない場合がある
複雑な条件のpointcutをしたい場合に不十分

メソッドのシグネチャだけでなく、内部動作に対しても
条件を課したいときなど
SPA 2003, Hakone
22
Josh実行までの概観
.josh
独自言語で書いた
アスペクト
.class
アスペクト埋め込みの
ターゲット
.class
アスペクトとクラス
の両方の機能
コード変換
weave
.class
Java の要素
SPA 2003, Hakone
.class
JVM
pointcut 指定子の定義
pointcut の使用
& アドバイス
23