Josh : バイトコードレベルでの Java用 Aspect Weaver

Download Report

Transcript Josh : バイトコードレベルでの Java用 Aspect Weaver

Josh : バイトコードレベルでの
Java用 Aspect Weaver
中川 清志(東工大)
立堀 道昭(筑波大)
千葉 滋 (東工大)
1
オブジェクト指向の限界
オブジェクト指向はモジュラリティが優れて
いるが限界もある
ある種の処理は複数のオブジェクトに散ら
ばってしまう

ログ出力,メモリ管理などの
システマティックな処理
その結果保守性が悪化し修正も困難になる
2
散らばってしまう例 : ログ出力
class Car{
void start() {
Log.print(“start”);
class Bike{
void start() {
Log.print(“start”);
..
}
void back() {
Log.print(“back”);
}
}
..
}
}
..
class Log {
static void print(String msg) {
System.out.println(msg);
}
}
ログ出力をするタイミングを変えるような変更の度に,
Car, Bikeクラスのソースコードを修正しなければならない
3
アスペクト指向
散らばっていたコードをアスペクトとしてモ
ジュール化するのがアスペクト指向

アスペクトはオブジェクトによるモジュール分割
を補完するもの
 この2種類のモジュールを
合成して,1つのプログラ
ムを作り出すことを
weave という
weave
実行
4
AspectJ の新処理系 Josh
AspectJ 言語

汎用アスペクト指向言語の代表的なもの
AspectJ 言語の処理系(weaver)


ajc
Josh
XEROX 版標準処理系
我々が新たに開発した処理系
5
AspectJの言語仕様(1)
Introduction

既存クラスに新しいメンバを加える
 フィールド,メソッドの追加

既存クラスの階層構造をかえる
 スーパクラス,インタフェースの変更
private int Point.z;
public int Point.getZ() { return z; }
declare parents : Point implements java.io.Serializable
6
AspectJの言語仕様(2)
Advice


Join-Point にコード断片を埋め込むように指示
before, after, aroundの3種類
Join-Point


プログラム実行の節目
例 : メソッド呼び出し,フィールド書き込み etc.
before() : call (int Point.getZ()) {
System.out.println(“before call getZ()”); }
after() : get (int Point.z) {
System.out.println(“after get z”); }
7
標準処理系 ajc の問題点
java
source
aspect
コンパイル時 weave

分割コンパイルできない
 アスペクトを変更したら
ソースコードも再コンパイ
ルしなければならない

weaver
ajc
ソースコードが必要
 サードパーティ製のクラス
には使えない
 動的ロードに不向き – プロ
グラム時に利用するクラス
がわかっていないといけな
い
weaved
source
weaved
bytecode
コンパイラ
8
本研究の提案 : Josh
aspect
java
source
問題点に対応した新シ
ステムJosh を提案


ロード時に,バイトコード
部分
レベルで weave
コンパイラ
部分コンパイル結果,バ
イトコードは一旦ローカ
Josh
ルディスクに保存
weaver
コンパイラ
bytecode
weaved
bytecode
9
Josh の利点
バイトコードレベルでのweave の有用性

分割コンパイル可能
 アスペクトを変更してもソースの再コンパイルの必
要がない

ソースコード無しクラスにも適用できる
ロード時の weave

複数のアスペクトを切り替えて使える
10
ソースコードなしクラスの
アスペクト
ソースコードを見ないでアスペクトを書ける
のか?


汎用性のあるアスペクトなら書ける
分散環境への適応
 既存プログラムとは別に分散化のためのアスペク
トを記述し,それらをweave して分散プログラムを
生成(e.g. Addistant )

新しいセキュリティ機構の導入
 セキュリティチェックコードの挿入
基本的にはソースコードのあるプログラムのアスペクトを書く
11
バイトコードレベルでの
weave の制限
Join-Point の消失


コンパイル時にソースコードの情報が失われ
てしまうことがある
例:インライン展開
エラーの検出がロード時


ソースコードレベルならばコンパイルエラーに
なるものが、バイトコードレベルではロード時
エラーになる
例 : 同じシグネチャのメソッドの追加
12
Josh の実装
部分コンパイラ

アスペクトをバイトコード化する
Josh Weaver

アスペクトとJava バイトコードをweave する
13
部分コンパイラ (1)
役割 : ソースコードで存在する,アスペクト内の
Javaコード断片をバイトコード化
int Point.getZ() { return z; }
これをバイト
コード化したい
ダミークラスにコード断片を埋め込んで通常の
Javac でコンパイル

コード断片だけではコンパイルエラーが起こりうる
 フィールドやメソッドの参照エラー
(上の例では z)
14
部分コンパイラ(2)
バイトコード埋め込み先のクラスの,
フィールドやメソッドも書き込む

リフレクションの機能で調査可能
public class Dummy {
int z;
int getZ() {
return z;
}
}
埋め込み先のクラスの
フィールド
コード
断片
15
Josh Weaver
役割 : アスペクトのバイトコードをロード時
にJavaバイトコードに埋め込む



Javassist が提供する構造リフレクションを使
い実装した
プログラムのバイトコードを調べてJoin-Point
を見つけ出す
バイトコードを編集してアスペクトのバイトコー
ド断片を埋め込む
16
javassist.CtClass
標準JavaリフレクションAPIと同様に,クラ
ス定義を調べるメソッドを提供

getField(..), getMethod(..),
getName(..), getSuperclass(..)
さらにクラス定義を変更するメソッドを提供


addField(..), addMethod(..),
setSuperclass(..), addInterface(..)
Introductionの実現が可能
17
javassist.CodeConverter
特定のJoin-Point のバイトコードを変換する
insertBeforeMethod(..)
メソッド呼び出しの前に別メソッドを呼ぶ
 replaceFieldRead(..)
フィールド読み込みを別メソッドに呼び代える

CodeConverter の情報をクラスに反映させてバ
イトコード変換完了

Advice の実現が可能
18
Weaver のオーバヘッドの測定
実
行
時
間
[
]
ミ
リ
秒
USparcIII 750MHz
J2SE 1.3.1
クラスファイルのサイズ [KByte]
19
まとめ
AspectJ 言語の新コンパイラJosh を提案
Josh の weave

ロード時
バイトコードレベル

分割コンパイル可能

 アスペクト変更による再コンパイルの手間を省ける

ソースコードなしクラスにも適用できる
 サードパーティライブラリもOK
 動的ロードにも対応
20