成蹊大学理工学研究報告
J. Fac. Sci. Tech., Seikei Univ.
Vol.45 No.１ (2008) pp.21-29

強マイグレーションモバイルエージェントのためのソースコード変換器の実装
櫻井康樹*1，加藤史彬*1，津田 達也*2, 甲斐

宗徳*3

An Implementation of a Source Code Translator for Strong Migration Mobile Agent
Yasuki SAKURAI＊1, Fumiaki KATOH＊1, Tatsuya TSUDA＊2, Munenori KAI＊3
ABSTRACT：We have been developing a strong migration mobile agent system, called AgentSphere,
which enable users to write strong migration agent codes in Java by putting “migrate” method at any
place in the code. The strong migration agent codes have to be transformed into the codes which can be
executed on existing Java virtual machines without any modification. In this paper, we first show somebasic structural patterns in which “migration” methods are used in practical agent codes, then implement
an automatic agent code transformer from strong migration mobile agent codes to the code for ordinaryJava virtual machines by using JavaCC(Java Compiler-Compiler).
Keywords：mobile agent system, strong migration, source code transformation（Received March 25, 2008）

１. はじめにに，弱マイグレーションのモビリティを利用しているため，移動先で移動前の処理を継続するエージェントを自並列分散処理とは，ネットワークに接続された複数の由に記述することは困難であった。

マシンに負荷を分散させて並列に処理することにより，高い自律性を実現するには，採用するモビリティは強処理の高速化や耐故障性の向上ができる手法である。

マイグレーションであることが望ましい。そこで，強マ

しかし，分散処理システムでは多くのユーザがそれぞ

イグレーションモバイルエージェントシステムを実現す

れのアプリケーションの分散処理を要求するため，それる方法として，JPDA(Java Platform Debugger Architecture)らが投入されたことによる負荷の変動に合わせて，そのによるローカル変数の取得・再現手法と，ソースコード

後のアプリケーションの分散処理の仕方を適切に変えて変換手法について提案した[1]。

いかなければ，高性能でかつ信頼性の高い分散処理は実

これまでに，ソースコード変換手法の概念は完成して現できない。その対応を個々のユーザがアプリケーショ

いたが，その変換は手動で行っていた。そこで，本研究ンに組み込むのは決して容易ではない。

では，JavaCCを用いたソースコード変換自動化の実装をそこでシステム自身に自律性を持たせることにより，行った。

それを利用するユーザのアプリケーションにおいても自然と自律性を記述でき，実際に自律的な振る舞いをする

２．開発目的とする自律分散処理システムの概要

ことが可能となる。
筆者らは，これまでに自律性を実現するためのモバイ

2. 1

自律分散処理システムとモバイルエージェント

ルエージェントシステムを設計してきた。しかし，これ自律分散処理システムとは，システムの状況の変化にまで設計してきたモバイルエージェントシステムは多くシステム自身が自律的に対応しながら分散処理を行うシの Java ベースのモバイルエージェントシステムと同様ステムである。一般的に分散システムにおいて，タスクの負荷分散や停止したタスクの再生処理等の作業にはシ*1：工学研究科情報処理専攻修士学生*2：工学部経営・情報工学科学生*3：情報処理専攻教授 (kai@st.seikei.ac.jp)

ステム全体の状況把握や管理が必要であり，それらのコ
ントロールをすべて考慮してプログラム記述者がアプリ－21－

ケーションプログラムを記述するのは非常に困難である

ンピュータの性能値に合わせて自律的に各コンピューと考えられる。そこで，あらかじめシステムに自律性をタに割り当てる仕事量を調整する機能を構築している。

持たせることで，これらの問題を解決することができる。

分散処理を開始するときに Mediator によって生成されシステムの自律性を満たすためには，システム内で動くるタスクエージェントは，SPMD 形式のプログラムとし

各ソフトウェアが，他からのメッセージに応じた行動と，て記述されているため同じ仕事量を持っていて，このタ自ら取得した外部の情報に応じて判断を行い，その結果

スクエージェントの数が各コンピュータに割り当てらによって行動を計画し，その計画に基づき行動できる必れる仕事量に相当する。タスクエージェントを生成した

要がある。そこで本研究では，自律分散処理システムをMediator は性能値の高いコンピュータにより多くのタス実現するにあたって，モバイルエージェントを利用する

クエージェントを割り当てていく。

ことにした。

ただしこの割り当ては，分散処理開始時の各コンピュ

エージェントとは，人間の代理としてシステム上で自ータの性能によるものであり，一度分散されたタスクエ

律的に行動するソフトウェアであり，モバイルエージェージェントがその後の状況に応じて自由に移動できるントとは，ネットワークを通じてマシン間を移動しながわけではない。例えば，分散処理中のコンピュータに，らタスク処理を行うことができるエージェントのことをその分散処理とは別の要因で非常に大きな負荷がかか言う。そして，モバイルエージェントシステムとは，モり，タスクエージェントの処理の完了が大幅に延期されバイルエージェントの動作（生成，消去，移動，保存，るというような事態においてもエージェントはただ待

複製，通信など）を提供するシステムのことである。既つしかない。そこで，そのような場合にシステムが自動存のモバイルエージェントとしては，AgentSpace（佐藤

的に性能の良いコンピュータへタスクエージェントを一郎氏）[2]やAglets（日本IBM社）[3]，JavaGO（東京大学

移動させ，大幅な処理の遅延を防ぐ機能が必要となる。

米澤研究室） [4] ，MOBA（首藤一幸氏） [5] 等が挙げら

この機能実現には，エージェントが任意の中断した時れる。

点の実行時データを保持し，移動先のコンピュータ上で中断時点からの処理の再開ができることが必要となる。

2. 2

AgentSpace を用いた自律分散処理システムの概要

しかし，これまで利用してきたモバイルエージェント

筆者らは，モバイルエージェントシステムのソースがシステム AgentSpace のモビリティは弱マイグレーショ

公開され改造が可能となっていて，エージェント移動時ンであったため移動時に持っていく実行時データでは，に情報を圧縮して送るため移動が速いという理由から，中断した時点からの再開を行うには不十分であった。そAgentSpace を用いて自律分散処理システムのプラットフ

こで，本研究では，中断時点での再開が可能な実行時デ

ォームの開発を行っていた。

ータを持って移動する強マイグレーション方式のモバ

この自律分散処理用プラットフォームの目的は，「分イルエージェントシステムを実装することにした。

散処理の手法について詳しくない人でも簡単に分散処理の恩恵を受けられるシステムを構築すること」と，

３. エージェントの強マイグレーション化「様々な種類のプログラムを実行可能な汎用性の高い
3. 1システムにすること」である。

強マイグレーション化における問題点とその解決法

前者の目的を充たすために，ユーザが要求する処理をJava においてプログラムが使用するメモリ領域には，

効率よく分散するようなサポートを行う様々なエージ

実行コード領域（プログラムの実行コードを格納する領ェントやシステムを作成した。そして後者の目的を充た域)，スタック領域，ヒープ領域がある。

すために，SPMD 形式のプログラムと，MPMD(Multiple

Java を用いてモバイルエージェントを実装する際に，Program Multiple Data)形式のプログラムのどちらでも自予め Java に備わっているシリアライズ機能を用いるこ由に記述できるようにした[6]。

とによって，実行コードに加えてヒープ領域内の情報の保存が可能となっている。しかし，スタック領域内の情2. 3

報やプログラムカウンタを実行状態として保存する機

強マイグレーションの必要性

ネットワークに繋がれたコンピュータの性能は全て能は現状の JavaVM 1.6.0_04 ではサポートされていない。

同じではなく，各コンピュータは分散処理以外の処理もプログラムカウンタを取得・復元できれば移動直前の行っているため発揮できる性能は常に一定ではない。そ位置からのプログラムの再開が可能となる。また，スタ

こで本システムでは，分散処理開始時直近における各コ

ッ ク領 域内 に保 持さ れて いる ロー カル 変数 の値 を取－22－得・復元できれば，移動前の計算結果を無駄にせず，実エージェントは，スレッド上で実行される。そこで，JPDA

行を再開することができるようになる。そのため強マイを用いてエージェントが実行されているスレッドにアクグレーション方式のモバイルエージェントシステムをセスし，スタック内のローカル変数の値を取得する。し実現するためには，スタック領域内の情報とプログラム

かし，このローカル変数の値は JPDA 特有のクラス(Value

カウンタに相当する情報が必要となる。

型)であるため，外部への持ち出しが許可されていない。

しかし，これを Java で実装するのは容易ではない。Java

そこで，この値をシリアライズ（直列化）可能な変数にを用いた既存の強マイグレーション方式のモバイルエ

変換し，ヒープ領域内に格納する。そうすることにより，ージェントとしては，JavaGoX[7] ，MOBA，Nomads[8] ，JVM を変更することなく，Java に備わっているシリアラ

Brakes[9] な ど が 挙 げ ら れ る が ， こ れ ら の 研 究 で はイズ機能のみを用いて実行コード領域・ヒープ領域そしJavaVM 自体の変更を行ったり，バイトコード変換を行てスタック領域内のローカル変数を保存，別マシンに送ったりしている。JavaVM を変更する場合，JavaVM のバ

信することができるようになる。

ージョンアップごとに修正を行わなければならず，シス
テム開発の負担が大きい。

3. 3

スタック領域の復元

そこで本研究では，JavaVM に手を加えることなく強スタック領域を取得し，別マシンに移動した後，移動

マイグレーション方式のモバイルエージェントシステ

先のマシンで実行を再開するには，マイグレーション命ムを実現することを目指している。しかも記述上は，プ

令の直後までの状態を復元し，そこから実行を再開する

ログラム中に単に移動命令を migrate(移動先ホスト名);必要がある。そのためにはスタックの中身だけでなく，のように記述するだけでマイグレーションが可能で，こプログラムカウンタも必要とされる。JPDA では，このの命令の続きから実行できるようにしたい。

プログラムカウンタに類似したデータを扱っており，こそのための手法として，スタック領域内のローカル変れを取得することは可能である。しかし，この取得した数の取得・復元には後述する JPDA を用いた手法を，ププログラムカウンタを用いてプログラムを途中から実ログラムカウンタ相当の情報の取得・復元にはソースコ

行する機能は，JPDA でもサポートされていない。そこード変換手法を用いて実現した。以下に，それぞれの手で，本研究ではソースコードの変換を行うことにより，法について説明する。

同等の機能をサポートすることにした。
このソースコード変換手法では，プログラムコード中

3. 2

スタック領域の取得に記述された移動用関数である migrate 関数の位置で実スタック領域の中身を取得するために，JPDA(Java
Platform Debugger Architecture)を使用した。これは，サン･行時データを取得して移動し，到着後に移動直前の状態に復元するように変換する。

マイクロシステムズ社が提供する JavaVM に標準的に実装されており，Java アプリケーションのデバッグに使用

3. 4

されるもので，実行中のスレッドや実行情報へのアクセ

3. 4. 1

ソースコード変換
ソースコード変換の基本形

スが可能とである[10]。本研究では，この機能を用いるこ

ソースコード変換の手法は，プログラムコード中に記とによって，スタック領域のデータを取得することにす

述された移動用関数である migrate 関数の位置で実行時る。

データを取得して移動し，到着後に移動直前の状態に復図 3.1 は，ローカル変数を取得し，持ち出し可能にす

元するように変換する。

るまでのプロセスの概要を示したものである。

この変換手法を実現するためにまず，エージェントが直列化して直列化して別して別マシンへ
マシンへ移動持って移動する情報の中に，マイグレーション直後かどうかを示すフラグ MigFlag を用意する。このフラグが trueのときには移動直後であることを示す。初期値は false
であり，エージェントの移動が行われると，true になる。

JVMスタック

JPDA

この MigFlag と if～else 構文を組み合わせ，移動直後

Value型
ヒープ領域

ローカル変数群

図 3.1

直列化可能データには実行再開位置までのスタックフレームを再構築し，移動前にすでに得られていた値についての計算処理は直列化可能データ

全てスキップするようにソースコードを変換する。この

ローカル変数持ち出しまでのプロセス－23－

変換により，移動前のプログラムカウンタを保存して続

4. 2

きが実行できるのと同じ状態を実現することにした。

字句解析

字句解析では，ソースコードからトークンを切り出し

具体的な変換作業は，移動関数である migrate()が存在するスコープを中心に考える。まず，その後の変換の前て構文解析へと渡さなければならない。図 4.1 は，字句解析のコードの一部を示したものである。

準備として，注目しているスコープ内で定義している宣ーションコードへの変換方式を示している。ここで，ロ【Javaののプリミティブ型
プリミティブ型】
TOKEN :{< BOOLEAN: "boolean" >|< BYTE: "byte" >|< CHAR: "char" >|< DOUBLE: "double" >|< FLOAT: "float" >|< INT: "int" >|< LONG: "long" >|< SHORT: "short" >}ーカル変数の復元は，移動前の個々のローカル変数の値

図 4.1

言文をスコープの先頭にまとめて配置する。その結果として得られる「「宣言部・宣言部・処理群・処理群・migrate 関数・関数・処理群」
処理群」という構造が変換対象の基本形となる。プログラム中で利用されるどのような構文でも一般的にこの基本形に直すことができる。
図 3.2 は，この基本形から JavaVM 上での強マイグレ

字句解析の例を移動後の対応するローカル変数に再代入するための一連の代入文をソースコードに挿入することにより実

4. 3

構文解析

構文解析フェーズでは，トークンの並びに対し，BNF

現する。
変換前

記法に基づいて構文を定義する。また認識された生成規変換後{則に対し，変数情報のリスト，変数宣言のリスト，migrate

{
宣言部
処理群A
migrate();
処理群B

宣言部
if(MigFlag == false){
処理群A
migrate();}else{
ローカル変数復元部
MigFlag = false;
}
処理群B

}

MigFlag:移動直後か判断するフラグメソッドの位置情報をアクション部にて取得する。
図 4.2 は，構文解析のコードの一部を示したものである。
【Javaのの文】
void Statement() : {}
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

}

図 3.2

変換の基本方式

４．JavaCC を用いたソースコード変換の自動化
ソ ー ス コ ー ド 変 換 の 自 動 化 に あ た り ， JavaCC(JavaBlock ( )< ASSERT > Expression( ) ( < CL > Expression ( ) ) ? < SM >< IF > ParExpression() Statement ( ) ( < ELSE > Statement ( ) ) ?
< FOR > < L P > ForControl() < RP > Statement ( )< WHILE > ParExpression ( ) Statement ( )< DO > Statement( ) < WHILE > ParExpression ( ) Statement ( )< TRY > Block ( ) ( Catches () )? ( < FINALLY > Block ( ) ) ?
< SWITCH > ParExpression( ) SwitchBlockStatementGroups ( )< SYNCHRONIZED > ParExpression() Block ( )< RETURN > ( Expression ( ) ) ? < SM >< THROW > Expression ( ) < SM >< BREAK > ( Identifier ( ) ) ?
< CONTINUE > ( Identifier ( ) ) ?
< SM >
LOOKAHEAD (2) StatementExpression ( )LOOKAHEAD (2) Identifier() < CL > Statement ( )}Compiler Compiler)を使用した。JavaCC とは，lex/yacc をJava 言語に置き換えたものであり，サン･マイクロシス

図 4.2 構文解析の例

テムズ社が提供しているオープンソフトである。[11]本研
究では，JavaCC を用いることによりソースコード変換の4. 4

変数リスト，変数宣言行リストの作成

次にソースコード変換に必要な情報の取得について自動化を実現する。

説明する。変数宣言をスコープの先頭にまとめるために
4. 1

は，一度目の解析の際に，宣言されている変数のリスト

コード変換までの流れ

JavaCC を用いてソースコードを解析し変換を行うとを作成する必要がある。そのリストに含まれる情報は以き，migrate 関数が使用されている個数およびその位置に下の通りである。

よって変換後のソースコードの形が異なるので，ソース

・変数の型，名前

コードを 1 パスで解析し変換するのは困難である。そこ

・宣言されている関数の名前

で，字句解析・構文解析を一度行って migrate の使用状・配列か否か(復元部での記述が変化)

況をはじめ必要な情報を取得し，その後もう一度ソース

・for,while 文などで宣言されているか

コードを解析して，最初に取得した情報を元にコード変・宣言されているスコープの深さ換を行う。このように，2 パスの解析・変換方式を用いた。まず字句解析・構文解析について説明する。

－24－

変数の型，名前の他に，初期値が宣言されている場合

・自身の関数名には，その情報も保持しなければならないが，配列など

・その関数内で呼ばれている関数のリストの場合，その取得が困難であるため，変数宣言の行その・呼び出した関数が migrate に関係しているか否か

ものをリスト化することにした。この操作により，変数宣言をスコープの先頭にまとめる際の作業が簡略化で4. 7制御文に関する情報の取得

さらに，migrate 関数が if 文や for 文といった制御文のきる。
変数リスト，変数宣言行リストの例を以下に示す。

中に記述されていることも考えられるので，そのスコー

public class ClassTest {println();public void create(){int[] d = new int[3];int[] array = { 117, 75, 24, 32};
int a[],c=3;

プ内で migrate 関数が記述されている制御文に関する情報も取得する必要がある。この場合も migrate 関数が記述されている制御文のみを変換し，その他の制御文に対して不必要な変換を行わないようにする。必要な情報は

c = 5;
d = new int [3];int aaaa=10;a[2] = 10;

以下の通りである。
・if や for など，制御文のタイプ}

・記述が開始されている行番号

public static void main(int a, int b){}

・その制御文内で migrate 関数が呼ばれた回数}

図 4.3 ソースコードの例

５. 様々なソースコードに対する変換のパターン
変数リスト
変数型:int 名前:d 配列:1
変数型:int 名前:array 配列:1
変数型:int 名前:a 配列:1
変数型:int 名前:c 配列:0
変数型:int 名前:aaaa 配列:0

変数宣言行リスト
int[] d = new int[3];int[] array = { 117, 75, 24, 32};
int a[],c=3;
int aaaa=10;

図 4.4a 変数リスト

図 4.4b 変数宣言行リスト

5. 1

簡単なコードの変換

4.4 で述べた各リストと，migrate 関数の位置情報を元に，二度目の解析で，ソースコード変換の基本形に則って変換を行う。どのように変換を行うを以下に示す。

図 4.3 はリスト作成のために使用するソースコードの例

・プログラムファイル名は“Translated_”+ オリジナル

であり，それを解析にかけ，取得した各リストが図 4.4a，のファイル名とする。それに伴い，コード内のクラス

図 4.4b である。取得したこれらのリストは，変換を行う

宣言部分も変更する。

ための解析で用いることになる。

・migrate 関数呼出が含まれるユーザ関数に到達したら，取得した変数リスト，変数宣言行リストを用いて，ス

4. 5

migrate 関数に関する情報の取得

コープの先頭に変数宣言をまとめる。

ソースコード変換のためには，宣言されている変数の・変数宣言をまとめた後，その直後の行に AgentCoordinator

リストと共に，使用されている migrate 関数についてのを取得する命令文を挿入する。

情報も必要となる。その必要な情報とは，以下の通りで・migrate 前後かどうかを判断する if 文を挿入する。

ある。

・migrate 関数呼出までの処理郡を出力する。

・migrate が配置されている関数の名前

・migrate 関数呼出後，自身のスレッドを終了させる関数

・migrate が配置されているスコープの深さの呼出文を挿入する。この関数自体も自動で挿入する。

・migrate が使用されている数

・migrate 後に変数復元を行うための else 文，変数復元部，
MigFlag の初期化を行う関数呼出を挿入する。

4. 6

関数呼出に関する情報の取得

migrate が，ユーザが作成した関数内にある事も考えら以上の作業を行うことにより，ソースコード変換が完れるため，どの関数を呼び出しているかの情報も取得す了する。実際に変換を行ったコードの一部を図 5.1，図る必要がある。その理由は，migrate 関数を呼び出すまで

5.2 に示す。図 5.1 は変換前のソースコードの一部で，図に終了している関数は，スタックフレームの復元を行う

5.2 がソースコード変換後のコードの一部である。変換

変換の必要が無いので，migrate に関与している関数の情

後のコードを，実際に本研究で開発している強マイグレ

報だけを取得し，その他の関数に対して不必要な変換をーションモバイルエージェントシステム AgentSphere で行わないようにするためである。これに必要な情報は以起動させたところ，正しく動作することが確認できた。

下の通りである。

－25－

図 5.3 は，ユーザ関数内に複数の migrate 関数が記述さ

public class TransTest extends StrongMigAgent implements Serializable {private String IPaddress = "192.168.11.2";
private static AgentCoordinator userAC;

れており，その一つが if 文の中に記述されている場合のpublic void create(){int tmp = 0;
String line = "hello";
tmp = 3;例である。
5. 2. 1

ユーザ関数からマイグレートする場合

migrate 関数がユーザの作成した関数の中に存在した

int a = 0;
a = 10;
System.out.println(tmp);
System.out.println(a);場合には，図 5.3 で示した情報を元に変換を行う。そのuserAC.migrate(IPaddress,1);変換の例が図 5.4 である。
変換されたユーザ関数全体をマイグレーションブロ

System.out.println(a);System.out.println(tmp);

ックとおくと，ユーザ関数を呼び出しているスコープも

}
}

図5.1

基本形と同様の形になる。この時，ユーザ関数は必ず呼変換に用いたソースコードの一部

び出さなければならないため，スキップする条件文の中
public class Translated_TransTest extends StrongMigAgent implements Serializable {private String IPaddress = "192.168.11.2";
private static AgentCoordinator userAC;に記述される。こうすることで，移動直前の JavaVM ス

public void create(){int tmp = 0;
String line = "hello";
int a = 0;
userAC = getAgentCoordinator();if(userAC.checkflag()== 0){
tmp = 3;
a = 10;
System.out.println(tmp);
System.out.println(a);userAC.migrate(IPaddress,1);
agent_cessation(userAC);}else{
tmp = userAC.getIntegerValue("tmp",0);line = userAC.getStringValue("line",0);a = userAC.getIntegerValue("a",0);userAC.setFlag();}
System.out.println(a);System.out.println(tmp);
}...

図5.2
5. 2

には含めず，変数の復元等が含まれた else 文を抜けた後タックの構造まで復元することが可能となる。
{

{
宣言部１
処理群A
function();
処理群B

function(){
宣言部２
if(MigFlag == false){
処理群C
migrate();}else{
ローカル変数復元
MigFlag = false;
}
処理群D
}

function(){
宣言部２
処理群C
migrate();
処理群D}

より複雑なコードの変換

宣言部１
if(MigFlag == false){
処理群A}else{
ローカル変数の再現
MigFlag = false;}function();
処理群B

}

}

ソースコード変換後のコード

{
宣言部１
処理群A
マイグレーションブロック
function();
処理群B

}

図 5.4

ユーザ関数からマイグレートする場合の変換

5. 2. 2migrate 関数が複数存在する場合の変換5.1 では単一関数での変換の例を述べたが，ここではユーザ関数からマイグレートする場合や，migrate 関数が複数存在する場合，またその両方の条件を満たす場合の変換について述べる。

コード中に関数が複数存在する場合の変換には，図 5.3
で示した情報を元に変換を行う。その変換の例が図 5.5

どの変換においても，4.4，4.5，4.6，4.7 で述べたようである。

な情報が必要となる。以下の図にそれぞれの場合での情報取得の例を示す。

create{
宣言部１
処理群A
function();}

処理群B

function(){
宣言部２
処理群C
if(条件文){migrate();}
処理群D
migrate();
}

図 5.3

変換前
create(){
宣言部1
処理群A
migrate(0);
処理群B
migrate(1);
処理群C}

関数呼出情報■create (migBlock)-function(migBlockflag=1)■function (migrate)-migrate(migBlockflag=0)
migrate関数情報■function■function
個数：2
制御文情報
■if
■行数
migrate関数呼出数：1

図 5.5

変換に必要な各情報の取得

－26－

変換後
create(){
宣言部1
if(MigFlag[1] == false){
if(MigFlag[0] == false){
処理群A
migrate(0);}else{
ローカル変数復元
MigFlag[0] = false;}
処理群B
migrate(1);}else{
ローカル変数復元
MigFlag[1] = false;
}
処理群C
}

migrate 関数が複数ある場合の変換

図 5.3 で示しているように，ソースコード中に存在す

MigFlag が true の時には，復元を行うために無条件でスる migrate 関数の個数は取得できているため，その数だ

コープに入り，false の時には元の条件文の真偽でスコー

け MigFlag を用意する。このとき MigFlag は boolean 型

プに入るかどうかが決まる。

の配列となる。

制御文の中は「「宣言部・宣言部・処理群・処理群・ migrate 関数・関数・処理

そして，ソースコード変換時に，各 migrate 関数にシーケンスとなる番号を付け，その番号に対応する群」という基本形の変換を行う。if 文の例を図 5.7 に，for文の例を図 5.8 に示す。

MigFlag を使って処理をスキップするか判断する。
5. 2. 3合の変換…
}
If(条件文){宣言部
処理群A
migrate();
処理群B
}
…

5.2.1，5.2.2 の両方の条件を満たしているコードの場合，
migrate 関数が存在しているユーザ関数内の変換については，図 5.5 で示した変換と同様であるが，MigFlag が複数あるので，図 5.4 で示したユーザ関数を呼び出しているスコープの変換において if 文の条件式が異なる。その例を図 5.6 に示す。
Create(){
宣言部１
処理群A
function();マイグレーションブロック
処理群B}
function(){
宣言部２
処理群C
migrate(0);
処理群D
migrate(1);}…
}If(MigFlag[0]==1 || 条件文){
宣言部
if(MigFlag==0){
処理群A
migrate();}else{
復元部
}
処理群B
}
…

ユーザ関数内に migrate 関数が複数存在する場

create(){
宣言部１
if((MigFlag[0] == false) &&((MigFlag[1] == false)){
処理群A}else{
ローカル変数の復元}
function();
処理群B
}

図 5.7

…
}
for(初期化部; MigFlag[0]==1 ||条件文;更新部){
宣言部
if(MigFlag==0){
処理群A
migrate();}else{
復元部
}
処理群B
}
…

…
}
for(初期化部;条件文;
更新部){
宣言部
処理群A
migrate();
処理群B
}
…

処理群E

図5.6

if 文に対する変換

ユーザ関数内にmigrate関数が複数ある場合

図 5.8

まず各 MigFlag が false の時は処理 A を実行し，2 つあ

for 文に対する変換る migrate 関数を実行した場合は，どちらの場合でも処理 A をスキップする必要がある。そのため，ユーザ関数

６． 強マイグレーション方式にソースコード変換を行ったモバイルエージェントの動作確認を呼び出しているスコープの変換の if 文の条件を，((MigFlag[0] == false) && ((MigFlag[1] == false))

本研究室では，強マイグレーションモバイルエージェとすることによって上記の処理の流れを実現することントを動作させるシステム AgentSphere を開発している。

が出来る。
さらに，ユーザ関数が増え，マイグレーションブロッ

これは，AgentSpace と同様に，AgentSphere を各コン

クが複数存在する場合でも，MigFlag を，マイグレーシ

ピュータで起動することにより，エージェントをそれらョンブロックの個数と，migrate 関数の個数の積の数だけのコンピュータに送り込むことができる。本研究で実装用意すれば，変換可能である。

したソースコード変換器の動作確認をするために，図 6.1

5. 2. 4制御文の中に migrate 関数がある場合の変換のようなソースコードを用意した。そしてこのコードを

if 文や for 文などの制御文内に migrate 関数が記述され自動変換し，AgentSphere 上で動かし，正しく動作が行わていた場合には，移動後に無条件にその制御文内に入るれているかを確認した。図 6.1 のプログラムは，5 秒間 j必要がある。そこで，その制御文の条件文に「MigFlagの値をインクリメントし，その値を出力したら別のマシ==true」という条件式を追加し，これと元の条件文とのンへと移動を行う。また，i の値が指定した値になった論理和をとる。スコープ内で migrate 関数が複数記述さら，別のマシンへ移動するというものである。これを 2

れ てい る場 合は ，そ の数 だけ の論 理和 を追 加す る。

台のマシン間で行う。

－27－

public class TransCode extends StrongMigAgent
implements Serializable {private String IPaddressprivate static AgentCoordinator userAC;

public class Translated_TransCode extends
StrongMigAgent implements Serializable {private String IPaddress;
int count=0;
private static AgentCoordinator userAC;

public void create(){int a = 20;
func1();}

public void create(){int a = 20;
userAC = getAgentCoordinator();if(userAC.checkflag(0)==false &&userAC.checkflag(1)==false){}else{
a = userAC.getIntegerValue("a",1);}
func1();}
public void func1(){
int i=10,j=0;
long start,end,sum;if(userAC.checkflag(0)==false &&userAC.checkflag(1)==false){
System.out.println("start!");}else{//変数復元部
i = userAC.getIntegerValue("i",0);…..
}for(int a=0;userAC.checkflag(0)==true ||userAC.checkflag(1)==true || a<10; a++){if(userAC.checkflag(1)== false){
if(userAC.checkflag(0)== false){
start = System.currentTimeMillis();j=0;
while(true){
j=j+1;
end = System.currentTimeMillis();if((end-start)/1000 > 5) break;}if(a%2==0) IPaddress = "133.220.114.127";
else IPaddress = "133.220.114.240";i= i+1;
System.out.println("a:" + a + " i:" + i + " j:" + j);
userAC.migrate(IPaddress, 0);}else{//変数復元部
userAC.setFlag(0);}}else{//変数復元部}
if(userAC.checkflag(1)==true || i==15){
if(userAC.checkflag(1)== false){
if(a%2==0) IPaddress = "133.220.114.240";
else IPaddress = "133.220.114.127";
userAC.migrate(IPaddress, 1);}else{//変数復元部
userAC.setFlag(1);}}}System.out.println("finish!!");}}

public void func1(){
int i=10,j=0;
long start,end,sum;
System.out.println("start!");for(int a=0; a<10; a++){start = System.currentTimeMillis();j=0;
while(true){
j=j+1;
end = System.currentTimeMillis();if((end-start)/1000 > 5) break;}if(a%2==0) IPaddress = "133.220.114.127";
else IPaddress = "133.220.114.240";i= i+1;
System.out.println("a:" + a + " i:" + i + " j:" + j);
userAC.migrate(IPaddress, 0);if(i==15){
if(a%2==0) IPaddress = "133.220.114.240";
else IPaddress = "133.220.114.127";
userAC.migrate(IPaddress, 1);}}
System.out.println("finish!!");}}

図 6.1 動作確認に用いたソースコードの一例
そして migrate 関数は，どのような制御構造でも対応できることを確認するため，ユーザ関数の中かつ，for
文，if 文の制御文内に 2 つ記述してある。このソースコードを変換すると図 6.2 のようなコードが出力される。
そして，表 6.1 は動作に使用したマシンである。
表 6.1

動作確認に使用したマシン一覧

マシン名
CPU名 クロック数
マシンA Core 2 Duo
2.2GHz
マシンB PentiumD
2.8GHz

メモリ
2.0GB
1.0GB

次に，2 台のマシンで処理を行った時の，マシン A で

図 6.2

ソースコード変換後のコードの結果を図 6.3 に，マシン B での結果を図 6.4 に示す。
これらの図から，変数の状態を保持しながらエージェ
ントが移動し，移動後ではその続きから処理を行っていることが確認された。

図 6.3

－28－

マシン A

図 6.4

マシン B

７．終わりに[10] Illmann, T. et al.: “Transparent Migration of Mobile
Agents Using the Java Platform Debugger Architecture”,

本研究では，JavaCC を用いてソースコード変換器を実Mobile Agents: Proceedings of the 5th International

装したことにより，昨年度まで手動で行っていた変換がConference, Ma 2001 Atlanta, Ga, December 2-4,

自動化できるようになった。そして，どのような制御構pp.198- 212, 2001

造でも変換が可能であることを確認できた。

[11] https://javacc.dev.java.net/, Jan.2008 参照可

また，変換されたコードが強マイグレーションモバイ
ルエージェントとして正しく動作し，ソースコード変換が正しく行われていることが確認できた。
今後の課題としては，移動オーバヘッドに関する評価を行い，ソースコード変換仕様・ローカル変数取得復元機能を改善し性能の向上を目指すこと，クラス変数等の取得・復元できるローカル変数の種類の拡張等が挙げら
れる。

参考文献
[1] 田久保雅俊, “強マイグレーションモバイルエージェ
ントを実現するコード変換手法”, 成蹊大学大学院工学研究科情報処理専攻修士論文, 2006[2] 佐藤一郎：「AgentSpace：モバイルエージェントシス
テム」,日本ソフトウェア科学会, Dec.1998[3] 日本 IBM 東京基礎研究所：
http://www.trl.ibm.com/aglets/ , Jan.2008 参照可[4] 米澤明憲,関口龍郎,橋本政朋：「移動コード技術に基づくモバイルソフトウェア」
http://homepage.mac.com/t.sekiguchi/javago/index-j.html,
Jan.2008 参照可[5] 首藤一幸 :http://www.shudo.net/moba/ ,Jan.2008 参照

可[6] Sasaki, R. et al.: “Implementation and
Evaluation Autonomic Distributed Processing System
Using Mobile Agent”, Proc.of IEEE Pacific Rim
conference, No.237, Aug.2005[7] Sakamoto, T., Sekiguchi, T., Yonezawa, A.: “Byte CodeTransformation for Portable Thread Migration in Java”,
In Proceedings of ASAMA’2000, Springer, Zuerich,Germany (2000) 16-28.
[8] Suri, N. et al.: “Strong Mobility and Fine-Grained
Resource Control in NOMADS”, In Proceedings of
ASAMA’2000, Springer, Zuerich, Germany (2000) 2-15.
[9] Truyen, E. et al.: “Portable Support for Transparent
ThreadMigration

inJava”,

In

ProceedingsofASAMA’2000, Springer, Zuerich, Germany (2000)
29-43－29－