720 likes | 819 Views
プログラム変換のための クラスオブジェクトモデル. 筑波大学 大学院 工学研究科 電子・情報工学専攻 立堀道昭. 研究背景. オブジェクト指向モデルの 限界. オブジェクト指向の コード再利用・分離. Java のようなオブジェクト指向プログラムはクラスによって、モジュール分けされる モジュール - 再利用可能な単位 クラスによるモジュール分けは 万能ではない Crosscutting Concerns. Motivating Example 1 分散配置プログラム. 分散オブジェクトを配置するコードは プログラム全体に四散する. Host B. Host A.
E N D
プログラム変換のためのクラスオブジェクトモデルプログラム変換のためのクラスオブジェクトモデル 筑波大学 大学院 工学研究科 電子・情報工学専攻 立堀道昭 学位論文公開発表
研究背景 オブジェクト指向モデルの限界 学位論文公開発表
オブジェクト指向のコード再利用・分離 • Java のようなオブジェクト指向プログラムはクラスによって、モジュール分けされる • モジュール - 再利用可能な単位 • クラスによるモジュール分けは万能ではない • Crosscutting Concerns 学位論文公開発表
Motivating Example 1分散配置プログラム • 分散オブジェクトを配置するコードはプログラム全体に四散する Host B Host A class P {.. new C() ..} class A {.. remote.gen(“P”) ..} class C {.. new P() ..} class B {.. remote.gen(“P”) ..} class D {.. new P() ..} 学位論文公開発表
配置設計の変更に伴うプログラムの修正 • 配置設計の変更に伴い、多くのクラスのコードを少しづつ修正しなければならない class P{..remote.gen(“C”)..} Changed allocation of P’s instances class A{..new P()..} classC{..remote.gen(“P”)..} class B{..new P()..} classD{..remote.gen(“P”)..} 学位論文公開発表
Motivating Example 2遠隔参照 • 遠隔オブジェクトをシームレスに提供するプロキシクラスには大量の通信コード記述 class A_Proxy { C getIt() { ..通信コード.. }void setIt() { ..通信コード.. }} class A { C getIt() {} void setIt() {}} class B {} class C {} B_Proxy .. C_Proxy 学位論文公開発表
類似のコードの頻出 • 似たようなコードが頻出するが、再利用できない A_Proxy D_Proxy ライブラリ? {パラメータを正規化 直列化して通信 通信先から送られてきた 結果をリターン} B_Proxy E_Proxy C_Proxy 学位論文公開発表
Crosscutting Concerns • 配置設計の関心事項(concern)がプログラムのモジュール構造を横切って(crosscut)いることが問題 微に入り細を穿つ記述、四散するロジック、類似の記述の繰り返し • 大きな記述量 - 分散に関する簡単な事項を簡潔に記述できない • 保守性の悪さ - 絡み合ったコードの修正は困難 プログラミングを重労働にしている要因のひとつ 学位論文公開発表
設計上の問題ではない • Design patterns[GoF94] など、よい設計を実現するための様々なプログラミング技法はある • しかし、「あちらをたてればこちらがたたず」という場合がしばしば 学位論文公開発表
差分パッチによる実現 • Diff ファイルのパッチとして分離して書けばよい? • パッチファイルに再利用性なく、記述量膨大 パッチあて パッチファイル 単純に分離するだけではだめ 学位論文公開発表
Advanced Separation of Concerns (ASoC) • 理想形 • 記述の分離 • 関心点の抽象化 • 現在盛んに研究されている [OOPSLA, ECOOP, ICSE, Reflection] • オブジェクト指向モデルだけでは不十分 • AOP[Kiczales97], MDSoC[Tarr99], … 学位論文公開発表
プログラム変換による ASoC- 本研究のアプローチ • パッチをプログラム変換を行うプログラムとして記述 • sed, awk, perl, java? プログラム変換 しかし、プログラム変換を行うプログラムの記述は容易ではない プログラム変換プログラム 学位論文公開発表
オブジェクト指向プログラムの変換 • オブジェクト指向プログラム • クラスをはじめとする宣言的な要素によりプログラムが構成される • 構文木やバイト列といった表現 • オブジェクト指向プログラムのロジックからかい離している クラスを直接表現する抽象データ構造が望まれる 学位論文公開発表
本研究の Overview • プログラム変換によるコード再利用・分割の実現 • オブジェクト指向の枠内ではできなかった部分に挑む • クラスオブジェクトモデルによってプログラム変換器の作成を容易に • オブジェクト指向プログラムをオブジェクト指向プログラムで変換するシステム設計のための抽象データ構造モデル 学位論文公開発表
本発表の以降の構成 • クラスオブジェクトモデルを適用した実際のシステムの設計・実装・応用 • オブジェクト指向プログラミング一般向けシステム • OpenJava - ソーステキストベースのプログラム変換 • [LNCS1826][情報処理学会論文誌41巻8号] • Javassist - バイトコードベースのプログラム変換 • [情報処理学会論文誌42巻11号] • 分散プログラミング専用システム • Addistant –分散配置の SoC • [ECOOP2001] 学位論文公開発表
OpenJava Java 言語のためのオブジェクト指向マクロ 学位論文公開発表
拡張可能言語の必要性 • 複雑なプログラミング • 分散処理 • 煩雑なネットワーク処理 • デザインパターン • 例 Adapter, Visitor, … • 言語による直接のサポートがない • distributed,adapts などのキーワードが使えればプログラムを簡潔に記述できる 学位論文公開発表
Program 変換 …. Method call 変換 name Arguments list 変換 従来型のプログラム変換による言語拡張機構 • C/C++ マクロ • 非常に単純な文法拡張のみ • EPP[Ichisugi98], JSE[Bachrach01] • 広域にわたる変換の記述が難しい • 構文木を直接操作 学位論文公開発表
OpenJava • Java のためのマクロ機構 • Java で言語拡張ができるようになった • distributed マクロ • adapts マクロ • 特徴 • 自己反映(reflection)モデルの採用 • クラスオブジェクト API • 構文木を直接扱わずに変換を記述できる 学位論文公開発表
visits distributed adapts IOIO OOI .oj Translator javac .java IOIO OOI .class OpenJava の処理系概要 • ソーステキスト変換器 • 拡張言語で書かれたソースコードを通常の Java 言語のソースコードに変換 マクロ マクロ 学位論文公開発表
Reflection モデルの採用 プログラムでプログラムを扱うモデル • プログラムでプログラムの情報を得ること • 例:このクラスは何個メソッドをもっている? • Java の Reflection API • プログラムでその言語の仕様を変えること • 言語拡張にあたる • Java にはない 学位論文公開発表
オブジェクト指向の Reflection • メタオブジェクト • 通常扱えないデータ (プログラム、コンパイラ等)をオブジェクトとして扱えるようにする • メタオブジェクトの API • 何をメタオブジェクトにするか • どのようにメタオブジェクトにアクセスさせるか • API の設計は自明ではない。この出来が肝要 • OpenJava ではクラスオブジェクトを設計した 学位論文公開発表
OpenJava のマクロ • マクロはメタクラスとして実装される マクロのプログラム class VerboseClass extends OJClass { translateDeclaration() expandAllocation() expandMethodCall() expandType() デフォルトの メタクラスを拡張 拡張したい部分の変換をオーバーライド メタクラスを選択 マクロの適用 OpenJava の予約語 class MyObject instantiates VerboseClass 学位論文公開発表
OpenJava のクラスオブジェクト • クラスオブジェクトの操作によって間接的に構文木が変換される 例:getSuperclass(), getField(name), addMethod(m) • オブジェクト機構の操作であり直感的 • 変換の操作を簡潔に記述できる • オブジェクトの型(クラス)ごとに、異なる変換を適用できる 例:expandAllocation() のオーバーライド • 衝突なしに複数の言語拡張を導入できる 学位論文公開発表
クラスオブジェクトの操作 • オブジェクト指向の論理構造の操作 プログラム クラスオブジェクト getName() getMethods() getSuffix() setName() addMethod() removeMethod() OpenJavaSystem システムはクラスオブジェクトの操作に基づいて 構文木を自動的に変換 学位論文公開発表
呼出し側の変換例 • ソースプログラム • 変換後のソースプログラム • 拡張のためのプログラム class Person instantiates ReplacedClass { : p = new Person() p = new PersonProxy() public class ReplacedClassextendsOJClass { Allocation expandAllocation(Allocation expr) { String newname = expr.getType().getName() + “Proxy”; return new Allocation(newname,expr.getArguments()); } : 学位論文公開発表
クラス宣言側の変換例 • ソースプログラム • 変換後のソースプログラム public class VectorStackinstantiatesAdapterClass adaptsVector in v to Stack {Object pop() { return v.remove(); } void push( Object o ) { v.add( o ); } public class VectorStack implements Stack { private Vector v; VectorStack(Vector o) { this.v = o; } boolean isEmpty() { return v.isEmpty(); } Enumeration elements() { return v.elements(); } Object pop() { return v.remove(); } void push( Object o ) { v.add( o ); } } 学位論文公開発表
クラス宣言側の変換例(cont.) • 拡張のためのプログラム public class AdapterClassextendsOJClass { void translateDeclaration() { OJClass adaptee = .. getSuffix(“adapts”) ..; Variable v = .. getSuffix(“adapts”) ..; OJClass target = .. getSuffix(“adapts”) ..; OJMethod[] tmethods = target.getMethods(); for (int i = 0; i < tmethods.length; ++i) { if (adaptee.getMethod(tmethods[i]) != null){ OJMethod newmtd = new OJMethod(tmethods[i]); newmtd.setBody(new ReturnStatement( new MethodCall(v, newmtd.getName(), newmtd.getParameters()) ) ); } : Vector Stack Stack のメソッド を調べる 新しいメソッド を作る 学位論文公開発表
OpenJava まとめ • オブジェクト指向言語用マクロ機構 • クラスオブジェクトによる変換 • ソースコード変換がクラスの操作として直感的に記述可能になった • 構文木を直接操作せず、オブジェクト機構を操作 学位論文公開発表
Javassist バイトコード変換による構造リフレクションの実現 学位論文公開発表
Java のリフレクション • 内視(introspection) • 標準 java.lang.reflectパッケージ • プログラムの意味の変更(intercession) • 提供されていない • セキュリティ上、実行性能上の問題を引き起こす 学位論文公開発表
動作リフレクション(Behavioral Reflection) • MetaXa, Kava, (Sun JDK1.3,) … • メタオブジェクト機構 modify Meta program Metaobject trap reflect Object Object method call 学位論文公開発表
これは最もよい抽象化だろうか? • 動作リフレクションは全ての種類のアプリケーションにとって直感的なわけでない • 例 • 遠隔メソッド呼び出し(RMI)のための言語拡張 • 遠隔 Accountオブジェクトのwithdraw()メソッドを呼び出す 学位論文公開発表
動作リフレクションによる RMI • メタプログラムはプロキシを作る proxy object network metaobject metaobject invoke trap dummy callee withdraw() withdraw() caller instance of Account class 学位論文公開発表
この dummy オブジェクトは • 自動的に作られなければならない • コンストラクタのパラメータには何を渡せばよいのか • もし Account のコンストラクタが副作用を起こしたら • Dummy オブジェクトの生成においてはコンストラクタ呼び出しを省く必要がある これらの問題を回避するためには、プロキシクラスを作り出す必要がある 学位論文公開発表
問題点のまとめ • 動作リフレクションの「トラップ」モデルは • 多くの言語拡張に便利である • が、全てにというわけではない • ある種のアプリケーションには、この抽象化はマッチしない • 数々のアドホックなトリックが必要になる 学位論文公開発表
Javassist • 我々の提案する Java 用の構造リフレクション(structural reflection)システム • 内視(introspection) • Java reflection API とほぼ互換 • プログラムの意味の変更(intercession) • 新たなクラスを作る • 既存のクラス定義を変更する プログラムの構造的な側面を扱う 学位論文公開発表
構造リフレクション • 今日あまり使われない • が、Smalltalk, CLOS, ObjVlisp, Classtalk, …によって提供されていたもの 学位論文公開発表
構造リフレクションによる RMI • プロキシクラスはメタプログラムにより自動的に作られる • Accountクラスに空のコンストラクタを追加 • RMI を行う withdraw()メソッドを追加 class AccountProxy extends Account { int withdraw() { .. Communication with RMI server .. } } class Account { Account() {} … } 学位論文公開発表
Javassist API • クラス・ダイアグラム • Class, Field, Constructor, Method オブジェクトは改変可能 Class Field Method Constructor 学位論文公開発表
Java のバイナリ互換性 • Javassist はあらゆる変更を許すわけではない • 例:フィールドの削除は許されない • ある種の変更はプログラムの正当性を壊す恐れが強い • Javassist はバイナリ互換性を保つような変更のための API のみを提供する 学位論文公開発表
ロード時のリフレクション • 標準の JVM を利用するために • リフレクションはロード時にのみ許される User meta program Local Disk modify a class file Javassistclass loader Java VM class file (bytecode) Network 学位論文公開発表
バイトコード変換器 • JOIE, Java Class API • バイトコード編集のための Java のライブラリ • Javassist • ソーステキストレベルの抽象度 • ユーザはバイトコードの知識を必要としない • 使い易さ v.s. 記述力 Javassist JOIE, Java Class API 学位論文公開発表
メソッド本体部(method body)の編集の仕方 • バイトコードの知識なしに • Javassist の提供する編集方法 • 他のメソッドから本体をコピー • 型名置き換え • パラメータを Object 型の配列に変換 • 典型的なメソッド本体から選択 • Delegator, default constructor, … 学位論文公開発表
実験:プログラム変更の準備に要する時間 • クラスを reify するのに関わる時間 学位論文公開発表
まとめ • Reflection • Behavioral reflection • MetaXa, Kava • Structural reflection • OpenJava, Javassist Load-time Compile-time 学位論文公開発表
Addistant 既存Javaプログラムのバイトコード変換による機能分散 学位論文公開発表
ソフトウェアの分散実行 例えば、GUI とアプリケーション・ロジックの分離 • 管理コストの削減 • 安価なクライアント環境を活用できるよう 「PC anywhere」 「ゼロ・アドミニストレーション」 「シン・クライアント」 学位論文公開発表
既存ソフトウェアの分散化 • 従来の環境(全自動の遠隔 GUI) • X Window System、VNC、Rawt[IBM Haifa 98] • 従来の分散化支援ツール • JavaRMI、HORB、ObjectSpace、… • Emerald[Black87]、”remotenew”[Nagaratnam96]、JavaParty[Philippen99]、… 学位論文公開発表
X Window • Xlib ライブラリレベルで分散化 • 低レベルな命令が大量にネットワークを飛び交う マウスが動いた マウスボタン押された Xlib マウスボタン離された ユーザプログラム 線を書け 学位論文公開発表