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
© Copyright 2026 ExpyDoc