分散 Java プログラムのための アスペクト指向言語

遠隔ポイントカット
- 分散アスペクト指向プログラミング
のための言語機構
西澤 無我 (02M37259)
指導教官: 千葉 滋
修士論文発表 2004年2月
1
本研究

分散ソフトウェアのモジュール化技術



アスペクト指向プログラミング (AOP)


ソフトウェアを小さなプログラムに分割する技術
ソフトウェアの可読性・保守性の向上
横断的関心事をモジュール化する技術
AOP で分散ソフトウェアをモジュール化

DJcutter の開発
修士論文発表 2004年2月
2
アスペクト指向プログラミング
(AOP)

横断的関心事をまとめる技術


まとめられたモジュールをアスペクトと呼ぶ
横断的関心事とは



複数のモジュールにまたがってしまう処理
既存のモジュール化技術では分離が困難
横断的関心事
例: ログ処理
class Car {
ログ処理はモジュールその void start() {
ものの機能とは無関係だが、 System.out.println(“start”);
……
モジュール内に入り混じる }}
class Bike {
void start() {
System.out.println(“start”);
……
}}
修士論文発表 2004年2月
3
AspectJ: 汎用 AOP 言語

ポイントカット



実行中のプログラム箇所を指定
例: メソッド呼出、メソッド実行、フィールドアクセス
アドバイス

ポイントカットとして指定された箇所で実行する処理
aspect Log {
before():
execution(void Car.start())
|| execution(void Bike.start()) { exec
System.out.println(“start”);
exec
}}
class Car {
void start() {
System.out.println(“start”);
……
}}
class Bike {
void start() {
System.out.println(“start”);
……
}}
修士論文発表 2004年2月
4
認証サービス・アプリケーションの
テストプログラム

認証サーバが正しく DB サーバにアクセスしているか?
1.registerUser() 呼出
AuthServer
クライアント
2.addUser() 呼出
・ユーザ認証を行うAuthServer
・ユーザ情報を DB に登録するDbServer
DbServer
テストプログラムで、registerUser() を呼び出したとき、
addUser() が実行されているかどうかを確認したい
修士論文発表 2004年2月
5
テストプログラムのアルゴリズム

テストプログラムに flag を用意する
AuthServerTest
registerUser() 呼出
AuthServer
テスト本体
1. flag の初期値 false
2. registerUser() 呼出
addUser() が実行され
たら、flag を true に変更
addUser() 呼出
DbServer
3. flag をチェック
true ならテスト成功
false なら失敗
修士論文発表 2004年2月
6
Java で書いたテストプログラム

テストプログラムに flag を用意する
AuthServerTest
registerUser() 呼出
AuthServer
テスト本体
1. flag の初期値 false
2. registerUser() 呼出
3. flag をチェック
true ならテスト成功
false なら失敗
addUser() 呼出
通知
DbServer
addUser() が実行され
たら、flag を true に変更
修士論文発表 2004年2月
7
テストプログラムが
DbServer を横断してしまう

テストのためだけに、既存のプログラムを修正・
変更したくない

addUser() 内に flag を true にするコードが入り込
んでしまう



横断的関心事
ソフトウェアの開発・保守作業効率を低下
AOP でモジュール化を試みる

テストコードと既存プログラムを
うまく分離できないか?
修士論文発表 2004年2月
8
AspectJ を利用した
テストプログラム

アドバイス内でプログラム setFlag を呼び出す
AuthServerTest
1.registerUser() 呼出
AuthServer
テスト本体
1. flag の初期値 false
2. registerUser() 呼出
3. flag をチェック
true ならテスト成功
false なら失敗
setFlag
2.addUser() 呼出
DbServer
RMI
flag を true に変更
exec
アスペクト
addUser() が実行され
たら、setFlag を呼ぶ
一応、テストプログラムを DbServer から分離
修士論文発表 2004年2月
9
複数のモジュールから構成された
テストプログラム

1つの関心事は1つのモジュールから構成されるべきだ
(AOP の観点)


複数のモジュールから構成されるプログラムは
開発・保守が面倒くさい



特に、分散コンピューティング
互いに密なネットワーク通信をしている
さらに、デプロイ作業が必要になる
汎用 AOP 言語 (AspectJ) では

テストコードを既存ソフトウェアから分離することはできたが、
複数のモジュールに分かれてしまった
修士論文発表 2004年2月
10
DJcutter の提案

単一ホスト上で動作するモジュールを作成できる



分散アスペクト指向プログラミング言語


分散した複数のモジュールからなる実装を避けられる
可読性・保守性の高いアスペクト、ソフトウェアを実現
AspectJ の言語仕様を分散ソフトウェア用に拡張
遠隔ポイントカット機能を提供
修士論文発表 2004年2月
11
DJcutter の遠隔ポイントカット


遠隔ホスト上のプログラムをポイントカット可能
アドバイスはアスペクトのあるホスト上で実行

ポイントカットした遠隔プログラムのコンテキストを扱える
2. アドバイスを実行
Log
アドバイス実行の
ためのメッセージ
aspect Log {
before() :
execution(void DbServer.addUser()) {
System.out.println(“addUser”);
}
}
1.addUser() 呼出
DbServer
修士論文発表 2004年2月
12
AspectJ のポイントカットとの違い

DJcutter


遠隔ホスト上のプログラム
をポイントカット可能
AspectJ

同じホスト上のプログラム
しかポイントカットできない
aspect Log {
before() :
execution(void DbServer.addUser()) {
System.out.println(“addUser”);
}
}
DJcutter の
アスペクト Log
addUser() 呼出
Remote exec
DbServer
Local exec
AspectJ の
アスペクト
修士論文発表 2004年2月
Log
13
DJcutter でテストを記述

明示的なネットワーク通信のない、1つのモ
ジュール
AuthServerTest
1.registerUser() 呼出
AuthServer
テスト本体
1. flag の初期値 false
2. registerUser() 呼出
3. flag をチェック
true ならテスト成功
false なら失敗
2.addUser() 呼出
DbServer
Remote exec
addUser() が実行され
たらflag を true に変更
テストプログラムを DbServer から分離
かつ、1つのモジュールにまとめられる
修士論文発表 2004年2月
14
具体的な実装

可読性・保守性の高いアスペクト記述
wasAddUserCalled を初期化
registerUser() を呼び出す
wasAddUserCalled の真偽
でテストの成功を判断
AddUser() が実行されたら
wasAddUserCalled が true
aspect AuthServerTest extends TestCase {
boolean wasAddUserCalled;
void testRegisterUser() {
wasAddUserCalled = false;
String userId = "muga", password = "xxx";
AuthServer auth
= (AuthServer) Naming.lookup("auth");
auth.registerUser(userId, password);
assertTrue(wasAddUserCalled);
}
before(): // remote pointcut
execution(void DbServer.addUser(..)) {
wasAddUserCalled = true;
}}
修士論文発表 2004年2月
15
AspectJ を利用した
テストプログラムの実装
AuthServerTest
1.registerUser() 呼出
AuthServer
class AuthServerTest extends TestCase {
boolean wasAddUserCalled;
void testRegisterUser() {
Naming.rebind("test", new RecieverImpl());
2.addUser() 呼出
wasAddUserCalled = false;
String userId = "muga", password = "xxx";
DbServer
AuthServer auth
= (AuthServer) Naming.lookup("auth");
auth.registerUser(userId, password);
interface NotificationReceiver { void confirmCall(); }
aspect Notification {
assertTrue(wasAddUserCalled);
before():
}
class ReceiverImpl
execution(void DbServer.addUser()){
extends UnicastRemoteObject
NotificationReceiver test
implements NotificationReceiver {
= (NotificationReceiver)
void confirmCall() {
Naming.lookup("test");
wasAddUserCalled = true;
RMI
test.confirmCall();
}}
}}
interface NotificationReceiver { void confirmCall(); }
修士論文発表 2004年2月
16
言語仕様 (1)

ポイントカット指定子

Call, execution, target, within, args …


Hosts(HostIds)


異なるスレッド、異なるホストでも有効なコントロールフロー
アドバイス宣言


ホスト毎にプログラムを指定可能
Cflow(Pointcut)


すべてのホスト上のプログラムを指定可能
Before, after, around をサポート
アスペクトメソッドの宣言

アクセス方法はインターフェース経由でアクセス
修士論文発表 2004年2月
17
言語仕様 (2)

遠隔インタータイプ宣言

アスペクト内で遠隔ホスト上で動作するクラスのメ
ソッド・フィールドを宣言
AuthServerTest
実行時に適用する
aspect AuthServerTest {
boolean DbServer.containsUser(String userId) {
// DB にユーザ情報が登録されているかどうか
}
}
修士論文発表 2004年2月
DbServer
boolean containsUser();
18
実装

コンパイラ




アスペクトのソースファイルの内容から Java のbytecode を
生成
ポイントカットや遠隔インタータイプ宣言の情報をランタイムラ
イブラリに渡す
AspectJ 1.0.6 のコンパイラが出力するコードと同等
ランタイムライブラリ


コンパイル済みのアスペクトやその他の分散ソフトウェアを
ロード・実行
それぞれのホスト上の拡張クラスローダがポイントカットや遠
隔インタータイプ宣言の情報を受け取り、bytecode 変換
修士論文発表 2004年2月
19
関連研究

分散プログラム内の特定の横断的関心事を
モジュール化




D 言語: 並列に動作するスレッド間の協調動作、遠
隔メソッド呼び出し
Addistant: オブジェクトの配置、遠隔参照の実装
JAC: Consistency、同期、トランザクション
DJcutter


遠隔ポイントカットを提供
AspectJ と同様、汎用的な横断的関心事が扱える
修士論文発表 2004年2月
20
これまでの仕事 (1)

査読つきの論文


Remote Pointcut – A Language Construct for Distributed AOP
AOSD 2004 (International Conference on Aspect-Oriented
Software Development)
査読なしの論文(発表のみ・ポスターのみを除く)




分散 Java プログラミングのための AOP 言語
SWoPP 2003 (Summer United Workshops on Parallel,
Distributed and Cooperative Processing)
Jarcler: Aspect-Oriented Middleware for Distributed Software in
Java
Dept. of Math. and Comp. Sciences Research Reports 2002 C164
アスペクト指向の分散化支援ツール
SPA summer 2002 (Systems for Programming and Applications)
プログラム分散化のためのアスペクト指向言語
SPA 2002 (Systems for Programming and Applications)
修士論文発表 2004年2月
21
これまでの仕事 (2)

発表のみ、ポスターのみ








プログラム分散化のためのアスペクト指向言語
SPA 2002 (Systems for Programming and Applications)
プログラム分散化のためのアスペクト指向言語
SPA 2003 (Systems for Programming and Applications)
分散 Java プログラムのためのアスペクト指向言語
SPA summer 2003 (Systems for Programming and Applications)
分散 Java プログラミングのためのアスペクト指向言語
CREST Meeting 2003
アスペクト指向ソフトウェア開発のための基盤ツール
情報学 公開シンポジウム 2004
SPA 2004 (Systems for Programming and Applications) (予定)
CREST Meeting 2004 (予定)
PPL 2004 (Programming and Programming Languages) (予定)
修士論文発表 2004年2月
22
まとめ

DJcutter: Java 用の分散 AOP 言語


遠隔ポイントカット機能を提供
分散ソフトウェア内の横断的関心事をモジュール化





認証サービス・アプリケーションのテストプログラムを例に
出した
汎用 AOP 言語では複数のモジュールになってしまう
DJcutter では、1つのモジュールに記述できる
可読性・保守性の高いアスペクト記述
関連研究

分散ソフトウェア内の横断的関心事をモジュール化

D言語、Addistant, JAC
修士論文発表 2004年2月
23
まとめ

DJcutter: Java 用の分散 AOP 言語


遠隔ポイントカット機能を提供
分散ソフトウェア内の横断的関心事をモジュール化




認証サービス・アプリケーションのテストプログラムを例に
出した
汎用 AOP 言語では複数のモジュールになってしまう
DJcutter では、1つのモジュールに記述できる
可読性・保守性の高いアスペクト記述
修士論文発表 2004年2月
24
修士論文発表 2004年2月
25
修士論文発表 2004年2月
26
実装 (1)
- DJcutter コンパイラ


アスペクトのソースファイルの内容から Java の
bytecode を生成
AspectJ 1.0.6 のコンパイラが出力するコードと同等
aspect LoggingAspect {
pointcut logX(Point p):
(call(void Point.setX(int)
|| call(void Point.setY(int))
&& target(p);
after(Point p, int x):
logX(p, x) {
System.out.println(“set x: “ + x);
}
class LoggingAspect {
static void after_$0(Point p, int x) {
System.out.println(“set x: “ + x);
}
}
}
修士論文発表 2004年2月
27
実装 (2) DJcutter runtime
- アスペクト・サーバ

アドバイスやアスペクトメソッドを実行


プログラム実行時にコンパイル済みアスペクトを
ロード
アスペクトの pointcut 情報を保持

他のホストの DJcutter runtime はアスペクト・サー
バに問い合わせる
修士論文発表 2004年2月
28
実装 (3) DJcutter runtime
- 拡張クラスローダ


各ホストで Java クラスをロード、実行
クラスのロード時


Pointcut をアスペクト・サーバに問い合わせ
ロードしているクラスがポイントカットされて
いれば、アドバイスを呼び出すコードを
bytecode 変換で埋め込む
修士論文発表 2004年2月
29
DJcutter Runtime の性能測定
- Advice 呼び出しと JavaRMI

DJcutter は join point が存在するホストの情報等
を advice へ送る
同一
ホスト
遠隔
ホスト
DJcutter
1.3
2.3
JavaRMI
(0 引数)
0.7
1.4
JavaRMI
(1 引数)
1.3
2.3
実験に利用したマシンスペック
-Sun Blade 1000
-Sun Enterprise 450
ネットワーク
- 1000baseFX
Null advice/method の実行時間(msec.)
修士論文発表 2004年2月
30
今後の課題

DJcutter の実行速度を改良


Join point が同一ホスト上にある場合も、
advice は別プロセスで実行
多くの pointcut 機構をサポート

Join point をホストの情報で選択するため
の指定子は用意していない
修士論文発表 2004年2月
31