以下、図面に基づいて本発明の実施の形態を説明する。図1は、本発明の実施の形態における文脈違反検出支援装置のハードウェア構成例を示す図である。同図の文脈違反検出支援装置10は、それぞれバスBで相互に接続されているドライブ装置100と、補助記憶装置102と、メモリ装置103と、CPU104と、インタフェース装置105と、表示装置106と、入力装置107とを有する。
文脈違反検出支援装置10での処理を実現するプログラムは、CD−ROM等の記録媒体101によって提供される。プログラムを記録した記録媒体101がドライブ装置100にセットされると、プログラムが記録媒体101からドライブ装置100を介して補助記憶装置102にインストールされる。但し、プログラムのインストールは必ずしも記録媒体101より行う必要はなく、ネットワークを介して他のコンピュータよりダウンロードするようにしてもよい。補助記憶装置102は、インストールされたプログラムを格納すると共に、必要なファイルやデータ等を格納する。
メモリ装置103は、プログラムの起動指示があった場合に、補助記憶装置102からプログラムを読み出して格納する。CPU104は、メモリ装置103に格納されたプログラムに従って文脈違反検出支援装置10に係る機能を実現する。インタフェース装置105は、ネットワークに接続するためのインタフェースとして用いられる。表示装置106はプログラムによるGUI(Graphical User Interface)等を表示する。入力装置107はキーボード及びマウス等であり、様々な操作指示を入力させるために用いられる。
図2は、本発明の実施の形態における文脈違反検出支援装置の機能構成例を示す図である。同図において、文脈違反検出支援装置10は、ルール記述記憶部11、ルール解析部12、プログラム生成部13、及び雛形データ記憶部14等を有する。これら各部は、文脈違反検出支援装置10にインストールされたプログラムがCPU104に実行させる処理により実現される。
文脈違反検出支援装置10は、これら各部によって、例えば、或るライブラリを使用して開発されるアプリケーションにおける、当該ライブラリの文脈上のルール(規則)又は制約等(以下、「ルール」で統一する)に対する違反の検出を支援する。文脈上のルールとは、ライブラリに含まれる関数又はメソッドの呼び出しの有無や呼び出しの前後関係(呼び出し順)等に関するルールをいう。
ルール記述記憶部11は、例えば、アプリケーションより利用されるライブラリについて、補助記憶装置102を用いてルール記述を記憶する。ルール記述とは、ライブラリの利用に関する文脈上のルールが所定の形式又は文法によって記述されたテキストデータをいう。本実施の形態において、ルール記述は、ルール要素がオペレータによって接続された式形式によって記述される。ルール要素とは、ルールの最小要素をいう。すなわち、ルール要素単体でも、一つのルール記述が成立しうる。オペレータは、ルール要素間の論理関係を示す記号をいう。
図3は、ルール記述を構成するルール要素の例を示す図である。同図には、4つのルール要素と、それぞれのルール要素のルール記述内における記述形式が示されている。なお、同図において、小文字のアルファベット(a〜j)は、ライブラリに含まれる関数又はメソッド(以下、「メソッド」で統一する。)を示す。
一つ目は、cメソッド内において、aメソッドがbメソッドの実行前の必須条件であることを示すルール要素である。すなわち、cメソッド内において、bメソッドが実行される場合は、bメソッドの実行前にaメソッドが必ず実行されなければならないことを示すルール要素である。当該ルール要素は、「@Before(a,b,c)」の形式でルール記述に記述される。以下、当該ルール要素を「Beforeルール要素」という。
二つ目は、fメソッド内において、dメソッドがeメソッドの実行後の必須条件であることを示すルール要素である。すなわち、fメソッド内において、eメソッドが実行される場合は、eメソッドの実行後に必ずdメソッドが実行されなければならないことを示すルール要素である。当該ルール要素は、「@After(d,e,c)」の形式でルール記述に記述される。以下、当該ルール要素を「Afterルール要素」という。
三つ目は、hメソッド内におけるgメソッドの呼び出しが必須条件であることを示すルール要素である。すなわち、gメソッドが、hメソッド内において必ず呼び出されなければならないことを示すルール要素である。当該ルール要素は、「@Call(g,h)」の形式でルール記述に記述される。以下、当該ルール要素を「Callルール要素」という。
四つ目は、引数の型が指定されたメソッドの呼び出しの必須条件を示すルール要素である。すなわち、iメソッドについて、特定の型の引数が指定されたバージョンがjメソッド内において必ず呼び出されなければならないことを示すルール要素である。当該ルール要素は、「@Call(i(型),j)」の形式でルール記述に記述される。以下、当該ルール要素を「型指定Callルール要素」という。
また、図4は、ルール記述を構成するオペレータの例を示す図である。同図には4つのオペレータと、それぞれのオペレータのルール記述内における記述形式が示されている。
一つ目は、(式k)かつ(式l)の関係を示すためのオペレータである。すなわち、(式k)及び(式l)の双方が必ず満たされなければならないというルールを記述するためのオペレータである。当該オペレータは、「&&」によってルール記述に記述される。
二つ目は、(式m)または(式n)の関係を示すためのオペレータである。すなわち、(式m)又は(式n)のいずれか一方が満たされなければならないというルールを記述すためのオペレータである。当該オペレータは、「||」によってルール記述に記述される。
三つ目は、(式o)ならば(式p)の関係を示すためのオペレータである。すなわち、(式o)が満たされる場合は、(式p)が必ず満たされなければならないというルールを記述するためのオペレータである。当該オペレータは、「−>」によってルール記述に記述される。
四つ目は、(式q)の否定を示すためのオペレータである。すなわち、(式q)が満たされてはならないというルールを記述ためのオペレータである。当該オペレータは、「!」によってルール記述に記述される。
なお、ルールは、ライブラリごとに異なる。したがって、ルール記述は、例えば、ライブラリの開発者、又はライブラリの使用者の中でライブラリの仕様に精通している者等によってライブラリごとに作成される。
ルール解析部12は、ルール記述記憶部11に記録されているルール記述を解析し、ルール記述の内容を、コンピュータ(プログラム生成部13)が処理し易い形式に変換する。より詳しくは、ルール解析部12は、ルール記述よりその構成要素(後述されるルール要素一覧及び式構造)を抽出する。すなわち、ルール記述は、人によって記述されうるため、人に理解し易い形式を有する。一方、人に理解し易い形式は、コンピュータによるロジカルな処理には不向きである傾向がある。そこで、ルール解析部12は、人とコンピュータ(プログラム生成部13)との間を仲介するための処理を実行する。
プログラム生成部13は、ルール解析部12による解析結果(ルール解析部12によって抽出されたルール記述の構成要素)に基づいて、ルール違反を検出するためのプログラムのソースコードを自動的に生成する。より詳しくは、プログラム生成部13は、履歴記録プログラム生成部131及びルール検証プログラム生成部132等を含む。履歴記録プログラム生成部131は、ルール違反を検出するためのプログラムの一部として履歴記録プログラムPrを生成する。ルール検証プログラム生成部132は、ルール違反を検出するためのプログラムの一部としてルール検証プログラムPcを生成する。
履歴記録プログラムPrは、開発対象のアプリケーションによるメソッドの呼び出し(メソッドの実行)を検知し、当該呼び出しの履歴を記録するプログラムである。ルール検証プログラムPcは、履歴記録プログラムPrによって記録された履歴に基づいて、ルール違反の有無を検証するプログラムである。
なお、履歴記録プログラムPr及びルール検証プログラムPcは、アスペクト指向プログラミングに基づいて作成される。アスペクト指向プログラミングが有する特長の一つが、本実施の形態に好適だからである。当該特長は、対象のプログラム(本実施の形態におけるライブラリ)の外側から当該対象のプログラムに対して作用することができるという性質である。斯かる性質により、ライブラリ側に変更を加えずに、ライブラリのメソッドの呼び出し(実行)を検知等することができる。本実施の形態では、アスペクト指向プログラミング言語として、AspectJを利用する。但し、他の言語が用いられてもよい。
雛形データ記憶部14は、履歴記録プログラムPr又はルール検証プログラムPcのソースコードの雛形となるデータ(雛形データ)を補助記憶装置102を用いて記憶する。
以下、文脈違反検出支援装置10の処理手順について説明する。図5は、ルール解析部が実行する処理手順の一例を説明するためのフローチャートである。同図の処理は、例えば、ユーザによって入力される、処理の開始指示に応じて開始される。当該指示において、解析対象のルール記述の識別情報が指定される。なお、ルール記述の識別情報を、以下「ルール名」という。
ステップS101において、ルール解析部12は、指定されたルール名に係るルール記述をルール記述記憶部11よりメモリ装置103に読み込む。すなわち、ルール記述は、ルール名に関連付けられてルール記述記憶部11に記憶されている。
図6は、第一のルール記述の一例を示す図である。同図に示されるルール記述rd1は、記述d11及び記述d12を含む。
記述d11は、ルール記述rd1の対象となるメソッド名を示す。したがって、記述d11より、ルール記述rd1は、メソッド「SSLSocket.startHandshake()」に関するルール記述であることが分かる。なお、一つのルール記述内に、複数のメソッドに関するルールが記述されてもよい。また、対象となるメソッド名を示す記述は、必須ではない。
記述d12は、ルールを示す式である。記述d12では、二つのBeforeルール要素が「−>」オペレータによって接続されている。第一項のBeforeルール要素は、「@Before(X509TrustManager.checkServerTrusted(),SSLSocket.startHandshake(),httpServlet.doPost())」であり、第二項のBeforeルール要素は、「@Before(X509Certificate.checkValidity(),SSLSocket.startHandshake(),httpServlet.doPost()))」である。
したがって、記述d12に係る式は、「httpServlet.doPost()内において、SSLSocket.startHandshake()より前にX509TrustManager.checkServerTrusted()が実行される場合(実行されるならば)、httpServlet.doPost()内において、SSLSocket.startHandshake()より前にX509Certificate.checkValidity()が実行されなければならない。」というルールを示す。
ルール記述rd12は、Java(登録商標)のSSL(Secure Socket Layer)クライアントとしてのアプリケーションの実装におけるSSLSocketライブラリの利用に関するルールを記述したものである。
すなわち、SSL通信では、サーバ証明書が信頼できるものか否かを検証することが必要とされる。Java(登録商標)のSSLSocketライブラリは、startHandshake()を呼び出してハンドシェークを開始する場合、証明書の検証処理は自動的に行われるため通常は問題ない。但し、X509TrustManagerの実装クラスにおいてcheckServerTrusted()がオーバーライドされた場合、上記証明書の検証処理は、オーバーライドされてしまう。したがって、この場合、上記証明書の検証処理は、アプリケーションの開発者が適切に実装しなければならない。
したがて、SSLクライアントとしてのアプリケーションを実装する場合におけるSSLSocketライブラリの利用に関するルールは、以下のようになる。
対象メソッド:javax.net.ssl.SSLSocket#startHandshake()
ルール:サーブレッドから呼び出された処理内において、javax.net.ssl.SSLSocket#startHandshake()よりも前に、X509TrustManager(の実装クラス)の checkServerTrusted()が実行される場合、必ずX509Certificate#checkValidity()も実行されなければならない
当該ルールをルール要素及びオペレータを用いて表現したものが、ルール記述rd1である。
なお、ここでは、サーブレットから呼び出されるWebアプリケーションがアプリケーションの例とされている。また、httpServlet.doPost()は、Webサーバにおいて、HTTPリクエストのPOSTコマンドが受信されたときに呼び出されるメソッドである。したがって、「サーブレットから呼び出された処理」に対して、「httpServlet.doPost()」が当てはめられている。
ルール記述は、その解析処理の便宜を考慮して、XML形式等の構造化文書形式によって記述されてもよい。
図7は、XML形式による第一のルール記述の一例を示す図である。同図のルール記述rd2は、図6のルール記述rd1において定義されているルールと同じルールをXML形式によって記述したものである。
ルート要素であるrule要素(<rule>タグによって囲まれた要素)のlibrary属性の値(「SSLSocket.startHandshake()」は、対象となるメソッド名を示す。rule要素の子要素rd21のタグ名(「−>」)は、当該子要素の値として含まれている二つのBeforeルール要素を接続するオペレータを示す。before要素rd22は、図6の記述d12における第一項のBeforeルール要素に対応する。before要素rd23は、図6の記述d12における第二項のBeforeルール要素に対応する。すなわち、各before要素において、proc属性、succ要素、within要素は、それぞれ、Before要素のaメソッド、bメソッド、cメソッド(図3参照)に対応する。
XML形式のデータは、既存のXMLパーサによって解析が容易である。したがって、ルール解析部12の処理内容を簡便化することができる。
続いて、ルール解析部12は、読み込んだルール記述の構造を解析する(S102)。具体的には、ルール記述内のルール要素とオペレータとが分解され、構造化される。すなわち、各ルール要素間の論理関係がルール解析部12によって認識される。なお、ルール記述が図7に示されるようにXML形式の場合、XMLパーサによってDOM(Document Object Model)形式に読み込まれることが、ステップS102でいうところの解析に相当する。したがって、ルール記述が構造化文書形式によって記述されている場合、ステップS101及びS102は、実質的に一つのステップとなりうる。
続いて、ルール解析部12は、必要に応じてルール記述の式を変形(又は変換)する(S103)。本実施の形態では、オペレータ「−>」を含む式に関して、オペレータ「!」及び「||」を用いて変形(又は変換)が行われる。具体的には、「A−>B」の構造を有する式は、「!A||B」に変形される。双方の式においてAとBとの論理関係は同じであるところ、「!」及び「||」のオペレータの方が、式の論理値(真偽値)の評価(式が示すルールが満たされているか否かの評価)をし易いからである。なお、ここでの「A」及び「B」は、一つのルール要素又は式を示す。ステップS103において、オペレータ「−>」は、全て解決(置換)される。
続いて、ルール解析部12は、ルール記述rd1の解析結果よりルール要素を抽出する(S104)。続いて、ルール解析部12は、抽出されたルール要素ごとに変数名を生成する(割り当てる)(S105)。変数名とは、ルール要素の論理値(真偽値)を記憶するための変数に対する識別名である。ルール要素間で一意性が保証されれば変数名の命名規則は所定のものに限定されない。続いて、ルール解析部12は、ルール要素と変数名との組の一覧を、ルール名に関連付けて補助記憶装置102に記録(出力)する(S106)。当該一覧を以下「ルール要素一覧」という。
図8は、第一のルール要素一覧の例を示す図である。同図のルール要素一覧rL1は、図6に示したルール記述rd1に基づいて生成されるルール要素一覧である。同図では、第一項のBeforeルール要素に対して、変数名「R1」が割り当てられ(生成され)、第二項のBeforeルール要素に対して、変数名「R2」が割り当てられた例が示されている。
続いて、ルール解析部12は、ルール記述の式における各ルール要素を、当該ルール要素に対応する変数名によって置き換えたものを、式構造とする(S107)。なお、ステップS103において変形された式については、変形後の式が置換の対象とされる。図6のルール要素記述rd1及び図8のルール要素一覧rL1に基づく式構造は、以下の(1)のようになる。
!R1||R2 ・・・(1)
なお、ルール記述rd1の各ルール要素について、単純に変数名への置換を行った結果は、
R1−>R2
であるが、ステップS103における変形により、ルール記述rd1より抽出される式構造は、上記(1)の通りとなる。
続いて、ルール解析部12は、式構造をルール名に関連付けて補助記憶装置102に記録(出力)する(S108)。
続いて、プログラム生成部13の処理手順について説明する。図9は、プログラム生成部が実行する処理手順の一例を説明するためのフローチャートである。同図の処理は、例えば、ユーザによって入力される、処理の開始指示に応じて開始される。当該指示において、ルール名が指定される。
ステップS201において、プログラム生成部13は、アスペクトの雛形(アスペクト雛形)を雛形データ記憶部14よりメモリ装置103に読み込む。
図10は、アスペクト雛形の一例を示す図である。同図に示されるように、アスペクト雛形は、アスペクト指向プログラミング言語(AspectJ)におけるアスペクトの定義の雛形である。同図のアスペクト雛形t1において、アスペクト名は、パラメタ化されている。すなわち、アスペクト名には具体的な値ではなく、「<アスペクト名>」が記述されている。また、アスペクト雛形t1には、一行のステップs11が記述されている。ステップs11では、MAP<MAP>型の変数varTableのメモリへの生成が定義されている。MAP<MAP>型とは、キー名とMAP型の変数とを関連付けて記憶することのできるデータ型をいう。本実施の形態では、斯かるMAP<MAP>型の変数varTableを用いて、ライブラリのメソッドの呼び出し履歴(実行履歴)を管理する。
図11は、本実施の形態においてライブラリの呼び出し履歴を管理するためのデータ構造の一例を概念的に示す図である。
同図には、変数varTableが、便宜上、テーブル形式によって表現されている。変数varTableは、キーとしてスレッドの識別子を記憶し、値として履歴テーブルを記憶する。スレッドの識別子とは、アプリケーションによるライブラリの適否の検証時において履歴記録プログラムPrが動作するスレッドの識別子である。マルチスレッド環境では、履歴記録プログラムPrは、複数のスレッド上で並列的に実行されうる。そして、ライブラリに関するルール記述(文脈に関するルール)は、スレッドごとに満たされる必要がある。そこで、変数varTableは、スレッドごとに履歴テーブルを対応付けて記憶する。なお、通信用のライブラリの場合は、変数varTableにおいて、セッションごとに(セッションIDに対応付けて)履歴テーブルが記憶されてもよい。また、スレッド又はセッション以外の単位で、ルール記述が満たされる必要が有る場合、当該単位ごとに、履歴テーブルが対応付けられればよい。
一方、履歴テーブルとは、本実施の形態において生成される履歴記録プログラムPr内においてcurrentTableという変数名によって参照される、MAP<boolean>型の変数である。currentTable変数(履歴テーブル)は、キーとしてルール要素の変数名又はルール要素内のメソッドごとに割り当てられる変数名を記憶し、値として当該ルール要素が満たされているか否かを示す真偽値、又は当該メソッドが呼び出されたか(実行されたか)否かを示す真偽値を記憶する。
続いて、プログラム生成部13は、アスペクト雛形t1の<アスペクト名>に対して、ユーザによって指定されたルール名を当てはめて(<アスペクト名>をルール名によって置換して)、当該ルール名に係るルール記述rd1に対応した具体的なアスペクトのソースコード(アスペクトコード)を生成する(S202)。
図12は、第一のアスペクトコードの具体例を示す図である。同図におけるアスペクトコードac1では、図10の「<アスペクト名>」が、「SSLSocket」に置換されている。すなわち、本実施の形態において、ルール記述rd1に関するルール名は、「SSLSocket」であるとする。
なお、ステップS202では、ルール名の当てはめだけでなく、ルール名が当てはめられたアスペクトコードac1を含むファイルが補助記憶装置102に生成される。
続いて、履歴記録プログラム生成部131は、指定されたルール名に関連付けられているルール要素一覧rL1及び式構造を補助記憶装置102からメモリ装置103に読み込む(S203)。続いて、履歴記録プログラム生成部131は、読み込まれたルール要素一覧rL1の中で、未処理のルール要素を処理対象とする(S204)。未処理のルール要素とは、ステップS205の処理対象とされていないルール要素をいう。したがって、最初は、読み込まれた全てのルール要素一覧rL1に含まれる全てのルール要素が未処理のルール要素である。
続いて、履歴記録プログラム生成部131は、処理対象のルール要素(以下、「カレントルール要素」という。)について、履歴記録プログラムPrの生成処理を実行する(S205)。履歴記録プログラムPrの生成処理においては、カレントルール要素について、履歴記録プログラムPrとしてのソースコードが、ステップS202において生成されたアスペクトコードac1に追加される。ステップS205は、読み込まれたルール要素一覧rL1に含まれる全てのルール要素について順番に実行される(S206)。
続いて、ルール検証プログラム生成部132は、ルール検証プログラムPcの生成処理を実行する(S207)。ルール検証プログラムPcの生成処理においては、指定されたルール名に対応するルール記述に対するルール検証プログラムPcとしてのソースコードが、ステップS202において生成されたアスペクトコードac1に追加される。したがって、履歴記録プログラムPrとルール検証プログラムPcとは、ファイル単位としては(ソースコードの単位としては)、一つのソースコードとして生成される。
続いて、ステップS205の履歴記録プログラムPrの生成処理の詳細について説明する。履歴記録プログラムPrの生成処理は、カレントルール要素が、Beforeルール要素、Afterルール要素、Callルール要素、又は型指定Callルール要素のいずれのタイプであるかに応じて異なる。したがって、履歴記録プログラム生成部131は、カレントルール要素が、いずれのタイプであるかを判定し、処理を分岐させる。以下、分岐後の各処理手順について説明する。
まず、Beforeルール要素(@Before(a,b,c))に関する履歴記憶プログラムの生成処理について説明する。当該生成処理では、要するに次のような処理を実行する履歴プロログラムが生成される。以下の説明において、aメソッド、bメソッド、cメソッドとは、@Before(a,b,c)における、aメソッド、bメソッド、又はcメソッドをいう。
(1)cメソッドの実行をフックし(検知し)、Beforeルール要素の評価値(当該要素の要件が満たされているか否かを示す真偽値)をtrueとする。また、aメソッドは実行されていないことを記録する。
(2)aメソッドの実行をフックし(検知し)、aメソッドが実行されたことを記録する。
(3)bメソッドの実行をフックし(検知し)、aメソッドが実行されたか否かを示す真偽値を、当該Beforeルール要素の評価値とする。
したがって、bメソッドが実行されたにも拘わらず、bメソッドの実行前にaメソッドが実行されていない場合は、評価値はfalseとなる履歴記憶プログラムが生成される。
以下、斯かる履歴記録プログラムPrの生成処理の詳細について説明する。
図13は、Beforeルール要素に関する履歴記録プログラム生成処理の処理手順の一例を説明するためのフローチャートである。すなわち、同図は、カレントルール要素がBeforeルール要素である場合の履歴記録プログラムPrの生成処理の処理手順の一例である。
ステップS301において、カレントルール要素のcメソッドの呼び出しをフックするためのポイントカット定義をアスペクトコードac1に追加生成する。具体的には、履歴記録プログラム生成部131は、雛形データ記憶部14よりポイントカット定義雛形を取得し、ポイントカット定義雛形にカレントルール要素のcメソッドを当てはめた結果をアスペクトコードac1に追加する。なお、ポイントカット定義とは、アスペクト指向プログラミング言語において、1以上のジョインポイントの集合の定義をいう。ジョインポイントとは、アスペクトをウィーブするコード上のポイントをいう。すなわち、ジョインポイントとは、対象のプログラムにおいて、フックする位置をいう。
図14は、ポイントカット定義雛形の一例を示す図である。同図のポイントカット定義雛形t2において、ポイントカット名と、ジョインポイントとされるメソッドのメソッド名とは、それぞれ、<ポイントカット名>又は<メソッド名>としてパラメタ化されている。なお、ポイントカット定義雛形t2のポイントカットタイプは、callである。したがって、ポイントカット定義雛形t2は、<メソッド名>に係るメソッドの呼び出しをジョインポイントとするポイントカット定義の雛形である。
ステップS301において、履歴記録プログラム生成部131は、ポイントカット定義雛形t2の<ポイントカット名>を適当な値に置換し、<メソッド名>をカレントルール要素のcメソッドのメソッド名に置換して、当該cメソッドに対するポイントカット定義を生成する。
図15は、履歴記録プログラムにおけるポイントカット定義の第一の具体例を示す図である。同図のポイントカット定義pc11は、図14のポイントカット定義雛形t2に対して、図8の1行目のルール要素(以下、「ルール要素R1」という。)のcメソッドが当てはめられた場合に生成されるポイントカット定義である。すなわち、現段階において、ルール要素R1がカレント要素であるとする。
ポイントカット定義pc11において、ポイントカット定義雛形t2の<ポイントカット名>は、「callR1−c」に置換されている。また、ポイントカット定義雛形t2の<メソッド名>は、ルール要素R1におけるcメソッドのメソッド名「httpServlet.doPost()」に置換されている。なお、ポイントカット名は、各ポイントカット定義間で一意性が保証され、かつ、プログラミング言語の仕様の範囲内において、任意の文字列が指定されてよい。本実施の形態では、Beforeルール要素のcメソッドに対するポイントカット名は、「call<カレントルール要素の変数名>−c」という命名規則に従って生成される。<カレントルール要素の変数名>は、カレントルール要素に対する変数名によって置換される。ルール要素R1の変数名は、「R1」であるため、「R1」に置換される。
続いて、履歴記録プログラム生成部131は、ポイントカット定義pc11に対するbeforeアドバイス定義ad11(図33参照)を、アスペクトコードac1に追加生成する(S302)。具体的には、履歴記録プログラム生成部131は、雛形データ記憶部14よりbeforeアドバイス定義雛形を取得し、beforeアドバイス定義雛形に基づいてbeforeアドバイス定義を生成する。
アドバイスとは、アスペクト指向プログラミング言語において、ジョイントポイントに対して実行される処理をいう。アドバイスのうち、beforeアドバイスは、「事前処理」を意味する。すなわち、beforeアドバイスは、ジョイントポイントの実行前に織り込まれる(組み込まれる)処理である。
図16は、beforeアドバイス定義雛形の一例を示す図である。同図のbeforeアドバイス定義t5において、ポイントカット名は、<ポイントカット名>としてパラメタ化されている。
また、beforeアドバイス定義雛形t5は、3つの処理ステップを含む。3つの処理ステップを含む。ステップs51は、現在のスレッドの識別子を取得する。ステップs52は、変数varTable(図11参照)より、現在のスレッドに対応する履歴テーブルを取得し、変数currentTableに代入する。ステップs53は、現在のスレッドに対応する履歴テーブルがまだ生成されていない場合は生成し、生成された履歴テーブルを変数currentTableに代入する。
ステップS302において、履歴記録プログラム生成部131は、beforeアドバイス定義雛形t5の<ポイントカット名>を、ステップS301において生成したポイントカット名(「callR1−c」)に置換することによりbeforeアドバイス定義を生成する。
続いて、履歴記録プログラム生成部131は、カレントルール要素の要件が満たされたことを暫定的に履歴テーブル(変数currentTable)へ記録するためのステップをbeforeアドバイス定義に対して追加する(S303)。具体的には、履歴記録プログラム生成部131は、履歴記録雛形を雛形データ記憶部14より取得し、履歴記録雛形に基づいて、履歴テーブルへの記録処理に関するステップを追加する。
図17は、履歴記録雛形の一例を示す図である。同図の履歴記録雛形t4において、履歴テーブル(変数currentTable)に記録(設定)されるキー名と値とは、それぞれ<キー名>、<値>としてパラメタ化されている。ステップS303において、履歴記録プログラム生成部131は、<キー名>を、カレントルール要素(ルール要素R1)のcメソッドに対する変数名(R1)によって置換し、<値>をtrueによって置換した結果をbeforeアドバイス定義に追加する。なお、ステップs41及びs42の詳細については後述する。
続いて、履歴記録プログラム生成部131は、aメソッドは実行されていないことを履歴テーブル(変数currentTable)へ記録するためのステップをbeforeアドバイス定義に対して追加する(S304)。具体的には、履歴記録プログラム生成部131は、履歴記録雛形t4の<キー名>を、カレントルール要素(ルール要素R1)のaメソッドに対する変数名によって置換し、<値>をfalseによって置換した結果をbeforeアドバイス定義に追加する。当該aメソッドに対する変数名は、本実施の形態において、「<カレントルール要素の変数名>−pred」という命名規則に従って生成される。したがって、ルール要素R1のaメソッドに関して、<キー名>は、「R1−pred」という値によって置換される。
ステップS304の実行により、ステップS301において生成されたポイントカット定義に対する具体的なbeforeアドバイス定義は完成する。図18は、具体的なbeforeアドバイス定義の第一の例を示す図である。
同図のbeforeアドバイス定義ad11に含まれる各ステップについて、図16又は図17と同ステップには、同一ステップ番号を付している。
ステップs51〜s53については、図16において説明した通りである。ステップs41−1は、カレントルール要素の変数名「R1」のキー名に対して、trueを履歴テーブルに記録する。すなわち、cメソッドの実行前に、ルール要素R1の要件が満たされたことが、暫定的に当該履歴テーブルに記録される。同図のbeforeアドバイス定義ad11は、ポイントカット定義pc11の作用により、当該cメソッドの実行前に実行されるからである。ステップs42−1は、現在のスレッドの識別子に対応付けて当該履歴テーブルを変数varTableに格納する。その結果、現在のスレッドにおいて、ルール要素R1の要件が満たされたことが暫定的に変数varTableに記録されたことになる。
ステップs41−2は、履歴テーブル(currentTable)に、カレントルール要素のaメソッドに対する変数名(「R1−pred」)に対してfalseを記録する。すなわち、当該aメソッドは実行されていないことが当該履歴テーブルに記録される。ステップs42−2は、現在のスレッドの識別子に対応付けて当該履歴テーブルを変数varTableに格納する。その結果、現在のスレッドにおいて、当該aメソッドは実行されていないことが変数varTableに記録されたことになる。
続いて、履歴記録プログラム生成部131は、カレントルール要素のaメソッドの呼び出しをフックするためのポイントカット定義をアスペクトコードac1に追加生成する(S305)。具体的には、履歴記録プログラム生成部131は、ポイントカット定義雛形t2(図14)の<ポイントカット名>を適当な値に置換し、<メソッド名>をカレントルール要素のaメソッドのメソッド名に置換して、当該aメソッドに対するポイントカット定義を生成する。
図19は、履歴記録プログラムにおけるポイントカット定義の第二の具体例を示す図である。同図のポイントカット定義pc12は、図14のポイントカット定義雛形t2に対して、ルール要素R1(図8)のaメソッドが当てはめられた場合に生成されるポイントカット定義である。
ポイントカット定義pc12において、ポイントカット定義雛形t2の<ポイントカット名>は、「callR1−pred」に置換されている。また、ポイントカット定義雛形t2の<メソッド名>は、ルール要素R1におけるaメソッドのメソッド名「X509TrustManager.checkServerTrusted()」に置換されている。なお、Beforeルール要素のaメソッドに対するポイントカット名は、「call<カレントルール要素の変数名>−pred」という命名規則に従って生成される。
続いて、履歴記録プログラム生成部131は、ステップS305において生成したポイントカット定義に対するafterアドバイス定義をアスペクトコードac1に追加生成する(S306)。具体的には、履歴記録プログラム生成部131は、雛形データ記憶部14よりafterアドバイス定義雛形を取得し、afterアドバイス定義雛形に基づいてafterアドバイス定義を生成する。
afterアドバイスは、「事後処理」を意味する。すなわち、afterアドバイスは、ジョイントポイントの実行後に織り込まれる(組み込まれる)処理である。
図20は、afterアドバイス定義雛形の一例を示す図である。同図のafterアドバイス定義雛形t3において、ポイントカット名は、<ポイントカット名>としてパラメタ化されている。
また、afterアドバイス定義雛形t3は、3つの処理ステップを含む。ステップs31は、現在のスレッドの識別子を取得する。ステップs32は、変数varTable(図11参照)より、現在のスレッドに対応する履歴テーブルを取得し、変数currentTableに代入する。ステップs33は、現在のスレッドに対応する履歴テーブルがまだ生成されていない場合は生成し、生成された履歴テーブルを変数currentTableに代入する。
ステップS306において、履歴記録プログラム生成部131は、afterアドバイス定義雛形t3の<ポイントカット名>を、ステップS305において生成したポイントカット名(「callR1−pred」)に置換することによりafterアドバイス定義を生成する。
続いて、履歴記録プログラム生成部131は、aメソッドが呼び出されたことを履歴テーブル(変数currentTable)へ記録するためのステップを、ステップS306において生成されたafterアドバイス定義に対して追加する(S307)。具体的には、履歴記録プログラム生成部131は、履歴記録雛形t4(図17)を雛形データ記憶部14より取得し、履歴記録雛形t4に基づいて、履歴テーブルへの記録処理に関するステップを追加する。すなわち、履歴記録プログラム生成部131は、履歴記録雛形t4の<キー名>を、カレントルール要素(ルール要素R1)のaメソッドに対する変数名(R1−pred)によって置換し、<値>をtrueによって置換した結果をafterアドバイス定義に追加する。
ステップS307の実行により、ステップS305において生成されたポイントカット定義に対する具体的なafterアドバイス定義は完成する。
図21は、具体的なafterアドバイス定義の第一の例を示す図である。同図のafterアドバイス定義ad12に含まれる各ステップについて、図17又は図20と同ステップには、同一ステップ番号を付している。
ステップs31〜s33については、図20において説明した通りである。ステップs41は、変数vaTableより取得された(s32)、又は新に生成された(s33)履歴テーブル(currentTable)に、カレントルール要素のaメソッド対する変数名(「R1−pred」)に対してtrueを記録する。すなわち、aメソッドが呼び出されたことが、¥当該履歴テーブルに記録される。ステップs42は、現在のスレッドの識別子に対応付けて当該履歴テーブルを変数varTableに格納する。その結果、現在のスレッドにおいて、aメソッドが呼び出されたことが変数varTableに記録されたことになる。
続いて、履歴記録プログラム生成部131は、カレントルール要素のbメソッドの呼び出しをフックするためのポイントカット定義をアスペクトコードac1に追加生成する(S308)。具体的には、履歴記録プログラム生成部131は、雛形データ記憶部14よりポイントカット定義雛形t2(図14)を取得し、ポイントカット定義雛形t2にカレントルール要素のbメソッドを当てはめた結果をアスペクトコードac1に追加する。その結果、図22に示されるポイントカット定義がアスペクトコードac1に追加される。
図22は、履歴記録プログラムにおけるポイントカット定義の第三の具体例を示す図である。同図のポイントカット定義pc13は、図14のポイントカット定義雛形t2に対して、ルール要素R1のbメソッドが当てはめられた場合に生成されるポイントカット定義である。
ポイントカット定義pc13において、ポイントカット定義雛形t2の<ポイントカット名>は、「callR1−succ」に置換されている。また、ポイントカット定義雛形t2の<メソッド名>は、ルール要素R1におけるbメソッドのメソッド名「SSLSocket.startHandshake ()」に置換されている。なお、本実施の形態では、Beforeルール要素のbメソッドに対するポイントカット名は、「call<カレントルール要素の変数名>−succ」という命名規則に従って生成される。
続いて、履歴記録プログラム生成部131は、ステップS308において生成したポイントカット定義に対するafterアドバイス定義をアスペクトコードac1に追加生成する(S309)。具体的には、履歴記録プログラム生成部131は、afterアドバイス定義雛形t3の<ポイントカット名>を、ステップS308において生成したポイントカット名(「callR1−succ」)に置換することによりafterアドバイス定義を生成する。
続いて、プログラム生成部13は、bメソッドより前に呼ばれているべきaメソッドに関する呼び出し履歴(実行履歴)を参照するためのステップを、ステップS309において生成されたafterアドバイス定義に追加する(S310)。当該ステップは、雛形データ記憶部14より取得される履歴参照雛形に基づいて生成される。
図23は、履歴参照雛形の一例を示す図である。同図の履歴参照雛形t6において、履歴テーブル(変数currentTable)より値を取得するキー名と、取得された値を格納する変数(参照用変数)の変数名とは、それぞれ<キー名>、<参照用変数名>としてパラメタ化されている。ステップS310において、履歴記録プログラム生成部131は、<参照用変数名>を適当な値によって置換し、<キー名>をaメソッドに対する変数名(ここでは、「R1−pred」)によって置換した結果をafterアドバイス定義に追加する。本実施の形態において、aメソッドの変数名に対応する値を参照するための変数名は、「r1」とされる。したがって、<参照用変数名>は、「r1」に置換される。なお、ステップs61及びs62の詳細については後述する。
続いて、プログラム生成部13は、履歴記録雛形t4(図17)を用いて、カレントルール要素の評価値を変数varTableに記録するためのステップを、ステップS309において生成されたafterアドバイス定義に追加する(S311)。具体的には、履歴記録雛形t4の<キー名>がカレントルール要素の変数名(「R1」)によって置換され、<値>が、履歴記録雛形t4(図23)の<参照用変数名>の置換先と同じ変数名(「r1」)に置換された結果が、当該afterアドバイスに追加される。
ステップS311の実行により、ステップS308において生成されたポイントカット定義に対する具体的なafterアドバイス定義は完成する。
図24は、具体的なafterアドバイス定義の第二の例を示す図である。同図のafterアドバイス定義ad13に含まれる各ステップについて、図16、図23、又は図17と同ステップには、同一ステップ番号を付している。
ステップs31〜s33については、図20において説明した通りである。ステップs61は、現在のスレッドに対応する履歴テーブル(変数currentTable)において、キー名「R1−pred」に対して記録されている値を取得し、変数r1に代入する。すなわち、カレントルール要素のaメソッドが実行されたか否かを示す真偽値が変数r1に代入される。
ステップs62は、変数r1の値がnull(空)である場合(すなわち、beforeアドバイス定義ad11及びafterアドバイス定義ad12が実行されていない場合)、変数r1にfalseを代入する。したがって、aメソッドが実行された後にアドバイス定義ad13が実行されている場合は、変数r1はtrueが代入された状態となる。それ以外の場合は、変数r1はfalseが代入された状態となる。なお、afterアドバイス定義ad13は、bメソッドの実行後に実行される処理である。したがって、aメソッドが実行された後にアドバイス定義ad13が実行されている場合とは、aメソッドの実行後にbメソッドが実行されている場合に相当する。これは、Before要素であるカレントルール要素の要件が満たされていることを意味する。
ステップs41は、カレントルール要素の変数名「R1」のキー名に対して、変数r1の値を履歴テーブルに記録する。すなわち、変数r1の値が、カレントルール要素の評価値として履歴テーブルに記録される。上記したように、変数r1の値は、カレントルール要素の要件が満たされているか否かを示すからである。
ステップs42は、現在のスレッドの識別子に対応付けて当該履歴テーブルを変数varTableに格納する。その結果、現在のスレッドにおいて、カレントルール要素の要件が満たされているか否かがが変数varTableに記録されたことになる。
以上で、カレントルール要素がBeforeルール要素である場合の処理手順は終了する。図8に示されるように、本実施の形態の場合、図8のルール要素一覧rL1において2番目のルール要素(ルール要素R2)もBeforeルール要素である。したがって、続けて、ルール要素R2に関して図13に示される処理手順が実行される。その結果、変数名R2に対してルール要素R2の評価値が現在のスレッドの履歴テーブルに記録され、当該履歴テーブルが変数varTableに格納される。なお、当該処理手順の内容の説明は、上記より自明であるため省略する。
続いて、図8のルール要素一覧rL1に基づいて、図9のステップS207のルール検証プログラムPc生成処理について説明する。なお、カレント要素がAfterルール要素、Callルール要素、又は型指定Callルール要素である場合の履歴記録プログラムPrの生成処理の処理手順の説明は、便宜上、後回しにする。
図25は、ルール検証プログラム生成処理の処理手順の一例を説明するためのフローチャートである。
ステップS401において、ルール検証プログラム生成部132は、ルール要素一覧rL1において、各ルール要素の最後の引数として指定されているメソッドをフック(以下、「呼出元メソッド」という。)するためのポイントカット定義を、アスペクトコードac1に追加する。すなわち、Beforeルール要素についてはcメソッド、Afterルール要素についてはfメソッド、Callルール要素についてはhメソッド、型指定Callルール要素についてはjメソッドが、呼出元メソッドに相当する。なお、本実施の形態において、一つのルール内の各ルール要素の呼出元メソッドは共通である必要がある。ルールが充足されているか否かの検証は、当該呼出元メソッドの実行後の一箇所において行われる必要があるからである。ステップS401におけるポイントカット定義の生成には、ポイントカット定義雛形t2(図14)が用いられる。
図26は、ルール検証プログラムにおけるポイントカット定義の具体例を示す図である。
同図のポイントカット定義pc17において、図14のポイントカット定義雛形t2の<ポイントカット名>は、「callLib」に置換されている。また、<メソッド名>は、ルール記述rd1の対象メソッドのメソッド名(「httpServlet.doPost()」)によって置換されている。なお、対象メソッドに対するポイントカット定義におけるポイントカット名は、本実施の形態では固定的に「callLib」に置換される。但し、当該ポイントカット名は、プログラミング言語の仕様の範囲内において任意に決定されてよい。
続いて、ルール検証プログラム生成部132は、afterアドバイス定義雛形t3を用いて、ステップS401において生成したポイントカット定義に対するafterアドバイス定義をアスペクトコードac1に追加生成する(S402)。具体的には、afterアドバイス定義雛形t3の<ポイントカット名>が、ステップS401において置換先とされたポイントカット名(「callLib」)に置換された結果が、アスペクトコードac1に追加される。
続いて、ルール検証プログラム生成部132は、ルール記述rd1の式構造(!R1||R2)内に含まれる変数名ごとに、当該変数名に対する値を参照するためのステップを、アスペクトコードac1に追加する(S403)。具体的には、ルール検証プログラム生成部132は、雛形データ記憶部14より履歴参照雛形t6(図23)を取得し、履歴参照雛形t6に当該変数名を当てはめた結果を当該変数名ごとにアスペクトコードac1に追加する。
式構造(!R1||R2)には、変数名R1及び変数名R2が含まれている。したがって、履歴参照雛形t6の<参照変数名>が「r1」に置換され、<キー名>が「R1」に置換された結果が追加される。更に、履歴参照雛形t6の<参照変数名>が「r2」に置換され、<キー名>が「R2」に置換された結果が追加される。
続いて、ルール検証プログラム生成部132は、当該式構造の各変数名に当該変数名の値を当てはめた結果として生成される式の真偽値に応じて、例外を発生させるステップをアスペクトコードac1に追加する(S404)。当該ステップは、雛形データ記憶部14より取得されるルール評価雛形を用いて生成される。
図27は、ルール評価雛形の一例を示す図である。同図のルール評価雛形t7において、<式>は、式構造の各変数名が、当該変数名に対する値が代入された参照用変数の変数名によって置換された式によって置換される。ステップs71の詳細については後述する。
ステップS404の実行により、ステップS402において生成されたafterアドバイス定義は、図28に示されるように完成する。
図28は、ルール検証プログラムにおけるafterアドバイス定義の具体例を示す図である。同図のafterアドバイス定義ad17に含まれる各ステップについて、図20、図23、又は図27と同ステップには、同一ステップ番号を付している。
ステップs31〜s33については、図20において説明した通りであり、ステップS402において生成される。ステップs61−1〜s62−2は、ステップS403において生成される。ステップs61−1は、現在のスレッドに対応する履歴テーブル(変数currentTable)において、キー名「R1」に対して記録されている値を取得し、変数r1に代入する。すなわち、ルール要素R1の評価値を示す真偽値が変数r1に代入される。ステップs62−1は、変数r1の値がnull(空)である場合、変数r1にfalseを代入する。したがって、ルール要素R1の要件が満たされている場合、変数r1にはtrueが代入され、ルール要素R1の要件が満たされていない場合、変数r1にはfalseが代入された状態となる。
ステップs61−2は、現在のスレッドに対応する履歴テーブル(変数currentTable)において、キー名「R2」に対して記録されている値を取得し、変数r2に代入する。すなわち、ルール要素R2の評価値を示す真偽値が変数r2に代入される。ステップs62−2は、変数r2の値がnull(空)である場合、変数r2にfalseを代入する。したがって、ルール要素R2の要件が満たされている場合、変数r2にはtrueが代入され、ルール要素R2の要件が満たされていない場合、変数r2にはfalseが代入された状態となる。
ステップs71は、ステップS404において生成される。ステップs71は、「!(!r1||r2)」を評価し、評価値がtrueであれば(すなわち、(!r1||r2)がfalseであれば)、例外(RuntimeException)を発生させる。評価値がfalseであれば(すなわち、(!r1||r2)がtrueであれば)、何もしない。なお、「!(!r1||r2)」は、r1の値の否定とr2の値との論理和の否定を意味する。
以上で、ルール記述rd1に対する履歴記録プログラムPr及びルール検証プログラムPcのソースコード(アスペクトコードac1)の生成は完了する。その結果、アスペクトコードac1は、図29及び図30に示されるようになる。
図29及び図30は、本実施の形態の第一のルール記述に関して生成される履歴記録プログラム及びルール検証プログラムのアスペクトコードの具体例を示す図である。図29及び図30は、一つのアスペクトコードac1を、便宜上、二つの図面に分割して示したものである。
図29において、図15、図18、図19、図21、図22、又は図24と同一のポイントカット定義又はアドバイス定義には、同一符号を付している。すなわち、図29には、ルール記述rd1より抽出されたルール要素R1に関するポイントカット定義又はアドバイス定義が示されている。
図30において、図26又は図28と同一のポイントカット定義又はアドバイス定義には、同一符号を付している。
また、図30において、ポイントカット定義pc14及びafterアドバイス定義ad14は、ルール要素R2に関して図13のステップS301〜S304が実行されることにより生成されるポイントカット定義又はアドバイス定義である。ポイントカット定義pc15及びafterアドバイス定義ad15は、ルール要素R2に関して図13のステップS305〜S307が実行されることにより生成されるポイントカット定義又はアドバイス定義である。ポイントカット定義pc16及びafterアドバイス定義ad16は、ルール要素R2に関して図13のステップS308〜S311が実行されることにより生成されるポイントカット定義又はアドバイス定義である。
同図のように生成されたアスペクトコードac1は、コンパイルされ、ライブラリを使用するアプリケーションに適用されることにより、履歴記録プログラムPr及びルール検証プログラムPcとして機能する。履歴記録プログラムPrにおけるポイントカット定義により、アプリケーションによるライブラリのメソッドの呼び出しがフックされる。当該呼び出しのフックに応じ、履歴記録プログラムPrにおけるアドバイス定義が実行され、当該呼び出しに関する履歴が変数varTableに記録される。更に、ルール記述rd1の呼出元メソッドの実行後に、ルール検証プログラムPcにおけるアドバイス定義が実行され、ルール記述rd1の要件が満たされているか否かが評価される。要件が満たされていない場合(falseである場合)、例外が発生する。例外の発生により、ユーザは、ライブラリの利用が不適切であることを認識することができる。
続いて、図5のステップS205の履歴記録プログラムPrの生成処理に関して、便宜上、説明を後回しにした、カレントルール要素がAfterルール要素である場合について説明する。ここでは、図5のステップS101において、ルール解析部12によって、図31に示されるルール記述が読み込まれたこととする。
図31は、第二のルール記述の一例を示す図である。同図に示されるルール記述rd2のルールを示す式では、二つのAfterルール要素が「||」オペレータによって接続されている。第一項のAfterルール要素は、「@After(java.io.File.delete(), java.io.File.createTempFile(), httpServlet.doPost())」であり、第二項のAfterルール要素は、「@After(java.io.File.deleteOnExit(), java.io.File.createTempFile(), httpServlet.doPost())」である。
したがって、ルール記述rd2に係る式は、「httpServlet.doPost()内でjava.io.File.createTempFile()が呼び出された場合は、java.io.File.createTempFile()の呼び出し後にjava.io.File.delete()が呼び出されなければならない。又は、httpServlet.doPost()内で、java.io.File.createTempFile()が呼び出された場合は、、java.io.File.createTempFile()の呼び出し後に、java.io.File.deleteOnExit()が呼び出されなければならない。」というルールを示す。
ルール記述rd2は、アプリケーション内においてファイルが一時的に生成された場合、当該ファイルはアプリケーションの終了時に削除されないと、情報漏洩の虞があることを考慮して本実施の形態において規定されたものである。
ファイルが適切に削除されるためには、Java.io.File#createTempFile()の実行後には、delete()又はdeleteOnExit()が実行される必要があるというルールが規定されればよい。当該ルールをルール要素及びオペレータを用いて表現したものが、ルール記述rd2である。
ルール記述rd2について、ステップS102〜S106が実行された結果、図32に示されるルール要素一覧が補助記憶装置102に記録(出力)される。
図32は、第二のルール要素一覧の例を示す図である。同図では、第一項のAfterルール要素に対して、変数名「R3」が割り当てられ(生成され)、第二項のAfterルール要素に対して、変数名「R4」が割り当てられた例が示されている。以下、第一項のAfterルール要素を「ルール要素R3」といい、第二項のAfterルール要素を「ルール要素R4」という。
続いてステップS107では、以下の式構造(2)が生成される。
R3||R4 ・・・(2)
続いて、ルール記述rd2に関してプログラム生成部13によって図9において説明した処理が実行される。ステップS202では、ルール記述rd2に関するアスペクトコードの一部が生成される。
図33及び図34は、本実施の形態の第二のルール記述に関して生成される履歴記録プログラム及びルール検証プログラムのアスペクトコードの具体例を示す図である。
同図には、ルール記述rd2に関して生成されるアスペクトコードac2の完成形が示されているが、ステップS202において生成される部分は、アスペクトの定義とステップs11である。すなわち、図12に示されるアスペクトコードac1と同様の内容である。なお、ステップs11は、図12のアスペクトコードac1におけるステップs11と同じである。すなわち、履歴を記録するためのデータ構造(図11参照)は、ルール要素のタイプに拘わらず同じである。
続いて、図9のステップS205について説明する。ルール要素一覧rL2に含まれているルール要素は、いずれもAfterルール要素である。したがって、履歴記録プログラム生成部131は、履歴記録プログラムPrの生成処理として、Afterルール要素に関する履歴記録プログラムPrを生成するための処理を実行する。当該生成処理では、要するに次のような処理を実行する履歴記憶プログラムが生成される。以下の説明において、dメソッド、eメソッド、fメソッドとは、@After(d,e,f)における、dメソッド、eメソッド、又はfメソッドをいう。
(1)fメソッドの実行をフックし、当該Afterルール要素の評価値をtrueとする。
(2)eメソッドの実行をフックし、当該評価値をfalseとする。
(3)dメソッドの実行をフックし、当該評価値をtrueとする。
以上により、eメソッドが実行された場合、その後にdメソッドが実行されなければ、当該Afterルール要素の評価値をfalseとする履歴記録プログラムPrが生成される。
以下、斯かる履歴記録プログラムPrの生成処理の詳細について説明する。
図35は、Afterルール要素に関する履歴記録プログラム生成処理の処理手順の一例を説明するためのフローチャートである。以下の説明において、ルール記述rd2に関して、図9のステップS202において生成されているアスペクトコードを、「アスペクトコードac2」という。図35の開始時点におけるアスペクトコードac2の状態は、図12に示されるアスペクトコードac1と同じである。
ステップS501において、履歴記録プログラム生成部131は、ポイントカット定義雛形t2(図14)を用いて、カレントルール要素(ルール要素R3)のfメソッドの呼び出しをフックするためのポイントカット定義pc21をアスペクトコードac2に追加生成する。具体的には、履歴記録プログラム生成部131は、ポイントカット定義雛形t2の<ポイントカット名>を「callR3−f」に置換し、<メソッド名>をカレントルール要素のfメソッドのメソッド名(「httpServlet.doPost()」)に置換して、当該fメソッドに対するポイントカット定義pc21(図33参照)を生成する。なお、本実施の形態では、Afterルール要素のfメソッドに対するポイントカット名は、「call<カレントルール要素の変数名>−f」という命名規則に従って生成される。
続いて、履歴記録プログラム生成部131は、ポイントカット定義pc21に対するbeforeアドバイス定義ad21(図33参照)を、beforeアドバイス定義雛形t5(図16)を用いて生成し、アスペクトコードac2に追加する(S502)。ステップS502では、beforeアドバイス定義ad21のうち、ステップs51〜s53が生成される。当該ステップ番号は、図16に対応する。
続いて、履歴記録プログラム生成部131は、カレントルール要素の要件が満たされたことを、暫定的に履歴テーブル(変数currentTable)へ記録するためのステップをbeforeアドバイス定義ad21に対して追加する(S503)。当該ステップの追加には、履歴記録雛形t4(図17)が使用される。追加されたステップは、アドバイス定義ad21内(図33)におけるs41及び42に相当する。
アドバイス定義ad21内のステップs41は、変数vaTableより取得された(s52)、又は新に生成された(s53)履歴テーブル(currentTable)に、カレントルール要素(ルール要素R3)の変数名(「R3」)に対してtrueを記録する。すなわち、fメソッドの実行前に、ルール要素R3の要件が満たされたことが、暫定的に当該履歴テーブルに記録される。ステップs42は、現在のスレッドの識別子に対応付けて当該履歴テーブルを変数varTableに格納する。その結果、現在のスレッドにおいて、ルール要素R3の要件が満たされたことが暫定的に変数varTableに記録されたことになる。
続いて、履歴記録プログラム生成部131は、ポイントカット定義雛形t2(図14)を用いて、カレントルール要素(ルール要素R3)のeメソッドの呼び出しをフックするためのポイントカット定義pc22をアスペクトコードac2に追加生成する(S504)。具体的には、履歴記録プログラム生成部131は、ポイントカット定義雛形t2の<ポイントカット名>を「R3−pred」に置換し、<メソッド名>をカレントルール要素のeメソッドのメソッド名(「java.io.File.createTempFile()」)に置換して、当該eメソッドに対するポイントカット定義pc22(図33参照)を生成する。なお、本実施の形態で、Afterルール要素のeメソッドに対するポイントカット名は、「call<カレントルール要素の変数名>−pred」という命名規則に従って生成される。
続いて、履歴記録プログラム生成部131は、ポイントカット定義pc22に対するafterアドバイス定義ad22(図33参照)を、afterアドバイス定義雛形t3(図20)を用いて生成し、アスペクトコードac2に追加する(S505)。ステップS505では、afterアドバイス定義ad22のうち、ステップs31〜s33が生成される。当該ステップ番号は、図20に対応する。
続いて、履歴記録プログラム生成部131は、カレントルール要素は満たされていないことを、暫定的に履歴テーブル(変数currentTable)へ記録するためのステップをafterアドバイス定義ad22に対して追加する(S506)。当該ステップの追加には、履歴記録雛形t4(図17)が使用される。追加されたステップは、アドバイス定義ad22内(図33)におけるs41及びs42に相当する。
アドバイス定義ad22内のステップs41は、変数vaTableより取得された(s32)、又は新に生成された(s33)履歴テーブル(currentTable)に、ルール要素R3の変数名(「R3」)に対してfalseを記録する。すなわち、eメソッドの実行後に、ルール要素R3の要件が満たされていないことが、暫定的に当該履歴テーブルに記録される。ステップs42は、現在のスレッドの識別子に対応付けて当該履歴テーブルを変数varTableに格納する。その結果、現在のスレッドにおいて、ルール要素R3の要件が満たされていないことが暫定的に変数varTableに記録されたことになる。
続くステップS507及びS508において、履歴記録プログラム生成部131は、dメソッドに関して、ステップS504及びS505において説明した処理を実行する。その結果、ポイントカット定義pc23及びafterアドバイス定義ad23のs31〜s33までが生成される。なお、本実施の形態では、Afterルール要素のdメソッドに対するポイントカット名は、「call<カレントルール要素の変数名>−succ」という命名規則に従って生成される。
続いて、履歴記録プログラム生成部131は、カレントルール要素は満たされていることを履歴テーブル(変数currentTable)へ記録するためのステップをafterアドバイス定義ad23に対して追加する(S509)。当該ステップの追加には、履歴記録雛形t4(図17)が使用される。追加されたステップは、アドバイス定義ad23内(図33)におけるs41及びs42に相当する。
以上で、カレントルール要素がAfterルール要素である場合の処理手順は終了する。図32に示されるように、本実施の形態の場合、図8のルール要素一覧rL2において2番目のルール要素(ルール要素R4)もAfterルール要素である。したがって、続けて、ルール要素R4に関して図13に示される処理手順が実行される。その結果、変数名R4に対してルール要素R4の評価値が現在のスレッドの履歴テーブルに記録され、当該履歴テーブルが変数varTableに格納される。なお、当該処理手順の内容の説明は、上記より自明であるため省略する。
続いて、図5のステップS205の履歴記録プログラムPrの生成処理に関して、カレントルール要素がCallルール要素である場合について説明する。
図36は、Callルール要素に関する履歴記録プログラム生成処理の処理手順の一例を説明するためのフローチャートである。以下の説明において、gメソッド、hメソッドとは、@Call(g,h)におけるgメソッド又はhメソッドをいう。
ステップS601において、履歴記録プログラム生成部131は、ポイントカット定義雛形t2(図14)を用いて、カレントルール要素のhメソッドの呼び出しをフックするためのポイントカット定義を作成中のアスペクトコードに追加生成する。
続いて、履歴記録プログラム生成部131は、ポイントカット定義に対するbeforeアドバイス定義を、beforeアドバイス定義雛形t5(図16)を用いて生成し、アスペクトコードに追加する(S602)。
続いて、履歴記録プログラム生成部131は、カレントルール要素の要件が満たされていないこと示す評価値を、暫定的に履歴テーブル(変数currentTable)へ記録するためのステップをbeforeアドバイス定義に対して追加する(S603)。
続いて、履歴記録プログラム生成部131は、ポイントカット定義雛形t2(図14)を用いて、カレントルール要素(ルール要素R3)のgメソッドの呼び出しをフックするためのポイントカット定義をアスペクトコードに追加生成する(S604)。
続いて、履歴記録プログラム生成部131は、ポイントカット定義に対するafterアドバイス定義を、afterアドバイス定義雛形t3(図20)を用いて生成し、アスペクトコードに追加する(S605)。
続いて、履歴記録プログラム生成部131は、カレントルール要素は満たされたことを示す評価値を履歴テーブル(変数currentTable)へ記録するためのステップをafterアドバイス定義に対して追加する(S606)。当該ステップの追加には、履歴記録雛形t4(図17)が使用される。
このように、Callルール要素については、hメソッドの実行の検知に応じて評価値がfalseとされ、gメソッドの実行の検知に応じて評価値がtrueとされる。したがって、当該評価値は、gメソッドが呼ばれたときに限ってtrueとなる。
なお、型指定Callルール要素に関する履歴記録プログラムPrの生成処理は、例えば、図36のhメソッドがjメソッドに置換され、gメソッドがiメソッドに置換された処理が実行されたものであればよい。
上述したように、本実施の形態の文脈違反検出支援装置10によれば、ルール記述を作成することにより、当該ルール記述に基づいて、履歴記録プログラムPr及びルール検証プログラムPcが自動生成される。当該履歴記録プログラムPr及びルール検証プログラムPcを、ライブラリを利用するアプリケーションに適用することにより、当該アプリケーションによる当該ライブラリの利用の適否を検査することができる。したがって、文脈違反検出支援装置10は、ライブラリの文脈上のルールに対する違反の検出を適切に支援することができる。
より詳しくは、履歴記録プログラムPrは、ライブラリのメソッドの呼び出し履歴を採取し、記録しておく。ルール検証プログラムPcは、履歴の内容が、ライブラリの文脈上のルールに適合しているか否かを判定する。したがって、デバッガのようにコールスタック(呼び出しの親子関係)だけではない、呼出の有無又は前後関係に関するルール違反の検出が可能になる。
また、本実施の形態では、メソッドの呼び出しに対して動的なフック機構が採用されて、アプリケーションによるライブラリの呼出が検知される。したがって、ライブラリ又はアプリケーションのソースコード等に修正を加える必要はない。その結果、例えば、ライブラリの作成後に、後付けでルールを作成し、ライブラリと一体化して提供することもできる。そうすることにより、検査ツールを別途提供されなくても、アプリケーションのテストの過程で、文脈上のルール違反を自動的に検出することができる。
以上、本発明の実施例について詳述したが、本発明は斯かる特定の実施形態に限定されるものではなく、特許請求の範囲に記載された本発明の要旨の範囲内において、種々の変形・変更が可能である。
以上の説明に関し、更に以下の項を開示する。
(付記1)
記憶手段が記憶する、メソッドの集合に関する文脈上の規則情報を、前記記憶手段から読み出して解析する規則解析手順と、
前記メソッドの集合を利用するプログラムによる前記規則情報に係る前記メソッドの実行の検知に応じて該実行の履歴を記録する履歴記録プログラムを生成する履歴記憶プログラム生成手順と、
前記履歴を前記規則情報と照合して、前記プログラムによる前記メソッドの利用が前記規則情報を満たしているか否かを判定する検証プログラムを生成するルール検証プログラム生成手順とをコンピュータが実行する文脈違反検出支援方法。
(付記2)
前記規則情報は、前記メソッドの呼び出しの要又は前記メソッドの呼び出し順に関する要件を規定するルール要素と、複数の前記ルール要素間の論理関係とを含み、
前記履歴記憶プログラム生成手順は、前記ルール要素に係る前記メソッドの実行の検知に応じて該実行の履歴を記録し、前記履歴に基づいて前記ルール要素に規定された要件が満たされているか否かを判定し、該判定結果を記録する前記履歴記録プログラムを生成し、
前記ルール検証プログラム生成手順は、該判定結果を前記論理関係に当てはめて、前記プログラムによる前記メソッドの呼び出しが前記規則情報を満たしているか否かを判定する前記検証プログラムを生成する付記1記載の文脈違反検出支援方法。
(付記3)
前記ルール要素は、cメソッド内において、bメソッドが実行される場合はbメソッドの実行前にaメソッドが実行されなければならないことを規定し、
前記履歴記憶プログラム生成手順は、cメソッドの実行の検知に応じ、aメソッドが呼び出されていないことを記録し、aメソッドの実行の検知に応じ、aメソッドが実行されたことを記録し、bメソッドの実行の検知に応じ、aメソッドが実行されたか否かに基づいて当該ルール要素に規定された要件が満たされたか否かを判定し、該判定結果を記録する前記履歴記録プログラムを生成する付記2記載の文脈違反検出支援方法。
(付記4)
前記ルール要素は、fメソッド内において、eメソッドが実行される場合はeメソッドの実行後にdメソッドが実行されなければならないことを規定し、
前記履歴記憶プログラム生成手順は、fメソッドの実行の検知に応じ、当該ルール要素に規定された要件が満たされていることを記録し、eメソッドの実行の検知に応じ、当該要件が満たされていないことを記録し、dメソッドの実行の検知に応じ、当該要件が満たされていることを記録する前記履歴記録プログラムを生成する付記2記載の文脈違反検出支援方法。
(付記5)
前記ルール要素は、hメソッド内において、gメソッドが実行されなければならないことを規定し、
前記履歴記憶プログラム生成手順は、hメソッドの実行の検知に応じ、当該ルール要素に規定された要件が満たされていないことを記録し、gメソッドの実行の検知に応じ、当該要件が満たされていることを記録する前記履歴記録プログラムを生成する付記2記載の文脈違反検出支援方法。
(付記6)
記憶手段が記憶する、メソッドの集合に関する文脈上の規則情報を、前記記憶手段から読み出して解析する規則解析手段と、
前記メソッドの集合を利用するプログラムによる前記規則情報に係る前記メソッドの実行の検知に応じて該実行の履歴を記録する履歴記録プログラムを生成する履歴記憶プログラム生成手段と、
前記履歴を前記規則情報と照合して、前記プログラムによる前記メソッドの利用が前記規則情報を満たしているか否かを判定する検証プログラムを生成するルール検証プログラム生成手段とを有する文脈違反検出支援装置。
(付記7)
前記規則情報は、前記メソッドの呼び出しの要又は前記メソッドの呼び出し順に関する要件を規定するルール要素と、複数の前記ルール要素間の論理関係とを含み、
前記履歴記憶プログラム生成手段は、前記ルール要素に係る前記メソッドの実行の検知に応じて該実行の履歴を記録し、前記履歴に基づいて前記ルール要素に規定された要件が満たされているか否かを判定し、該判定結果を記録する前記履歴記録プログラムを生成し、
前記ルール検証プログラム生成手段は、該判定結果を前記論理関係に当てはめて、前記プログラムによる前記メソッドの呼び出しが前記規則情報を満たしているか否かを判定する前記検証プログラムを生成する付記6記載の文脈違反検出支援装置。
(付記8)
前記ルール要素は、cメソッド内において、bメソッドが実行される場合はbメソッドの実行前にaメソッドが実行されなければならないことを規定し、
前記履歴記憶プログラム生成手段は、cメソッドの実行の検知に応じ、aメソッドが呼び出されていないことを記録し、aメソッドの実行の検知に応じ、aメソッドが実行されたことを記録し、bメソッドの実行の検知に応じ、aメソッドが実行されたか否かに基づいて当該ルール要素に規定された要件が満たされたか否かを判定し、該判定結果を記録する前記履歴記録プログラムを生成する付記7記載の文脈違反検出支援装置。
(付記9)
前記ルール要素は、fメソッド内において、eメソッドが実行される場合はeメソッドの実行後にdメソッドが実行されなければならないことを規定し、
前記履歴記憶プログラム生成手段は、fメソッドの実行の検知に応じ、当該ルール要素に規定された要件が満たされていることを記録し、eメソッドの実行の検知に応じ、当該要件が満たされていないことを記録し、dメソッドの実行の検知に応じ、当該要件が満たされていることを記録する前記履歴記録プログラムを生成する付記7記載の文脈違反検出支援装置。
(付記10)
前記ルール要素は、hメソッド内において、gメソッドが実行されなければならないことを規定し、
前記履歴記憶プログラム生成手段は、hメソッドの実行の検知に応じ、当該ルール要素に規定された要件が満たされていないことを記録し、gメソッドの実行の検知に応じ、当該要件が満たされていることを記録する前記履歴記録プログラムを生成する付記7記載の文脈違反検出支援装置。
(付記11)
記憶手段が記憶する、メソッドの集合に関する文脈上の規則情報を、前記記憶手段から読み出して解析する規則解析手順と、
前記メソッドの集合を利用するプログラムによる前記規則情報に係る前記メソッドの実行の検知に応じて該実行の履歴を記録する履歴記録プログラムを生成する履歴記憶プログラム生成手順と、
前記履歴を前記規則情報と照合して、前記プログラムによる前記メソッドの利用が前記規則情報を満たしているか否かを判定する検証プログラムを生成するルール検証プログラム生成手順とをコンピュータに実行させる文脈違反検出支援プログラム。
(付記12)
前記規則情報は、前記メソッドの呼び出しの要又は前記メソッドの呼び出し順に関する要件を規定するルール要素と、複数の前記ルール要素間の論理関係とを含み、
前記履歴記憶プログラム生成手順は、前記ルール要素に係る前記メソッドの実行の検知に応じて該実行の履歴を記録し、前記履歴に基づいて前記ルール要素に規定された要件が満たされているか否かを判定し、該判定結果を記録する前記履歴記録プログラムを生成し、
前記ルール検証プログラム生成手順は、該判定結果を前記論理関係に当てはめて、前記プログラムによる前記メソッドの呼び出しが前記規則情報を満たしているか否かを判定する前記検証プログラムを生成する付記11記載の文脈違反検出支援プログラム。
(付記13)
前記ルール要素は、cメソッド内において、bメソッドが実行される場合はbメソッドの実行前にaメソッドが実行されなければならないことを規定し、
前記履歴記憶プログラム生成手順は、cメソッドの実行の検知に応じ、aメソッドが呼び出されていないことを記録し、aメソッドの実行の検知に応じ、aメソッドが実行されたことを記録し、bメソッドの実行の検知に応じ、aメソッドが実行されたか否かに基づいて当該ルール要素に規定された要件が満たされたか否かを判定し、該判定結果を記録する前記履歴記録プログラムを生成する付記12記載の文脈違反検出支援プログラム。
(付記14)
前記ルール要素は、fメソッド内において、eメソッドが実行される場合はeメソッドの実行後にdメソッドが実行されなければならないことを規定し、
前記履歴記憶プログラム生成手順は、fメソッドの実行の検知に応じ、当該ルール要素に規定された要件が満たされていることを記録し、eメソッドの実行の検知に応じ、当該要件が満たされていないことを記録し、dメソッドの実行の検知に応じ、当該要件が満たされていることを記録する前記履歴記録プログラムを生成する付記12記載の文脈違反検出支援プログラム。
(付記15)
前記ルール要素は、hメソッド内において、gメソッドが実行されなければならないことを規定し、
前記履歴記憶プログラム生成手順は、hメソッドの実行の検知に応じ、当該ルール要素に規定された要件が満たされていないことを記録し、gメソッドの実行の検知に応じ、当該要件が満たされていることを記録する前記履歴記録プログラムを生成する付記12記載の文脈違反検出支援プログラム。