(57)【要約】【課題】データベースを介した変数の値の伝搬を検出する。【解決手段】ソースコード１４から、変数１４ａ，１４ｂと、変数１４ａを引数として用いて関数１３ａを呼び出す呼び出し文１４ｃと、関数１３ｂを呼び出し返り値を変数１４ｂに代入する呼び出し文１４ｄを検出する。呼び出し文１４ｃ，１４ｄの実行履歴を示すログ１５ａとクエリの実行履歴を示すログ１５ｂを取得する。呼び出し文１４ｃの実行履歴と書き込み時のクエリの実行履歴の比較に基づいて、関数１３ａの引数に対応するデータ項目１６ａを判定し、呼び出し文１４ｄの実行履歴と読み出し時のクエリの実行履歴の比較に基づいて、関数１３ｂの返り値に対応するデータ項目１６ｂを判定する。データ項目１６ａ，１６ｂが同一か否かに基づいて、変数１４ａ，１４ｂの依存関係を判定する。【選択図】図１
2018169998.tif 000002
【特許請求の範囲】
【請求項１】
データベースへのアクセスを制御するモジュールを利用するソフトウェアのソースコードを記憶する記憶部と、
前記ソースコードから、第１の変数と、前記第１の変数を引数として用いて前記モジュールの第１の関数を呼び出す第１の呼び出し文と、第２の変数と、前記モジュールの第２の関数を呼び出し前記第２の関数の返り値を前記第２の変数に代入する第２の呼び出し文とを検出し、
前記ソフトウェアを実行させた場合に生成されるログであって、前記第１の呼び出し文および前記第２の呼び出し文の実行履歴を示す第１のログと、前記モジュールの制御に基づいて生成されたクエリの実行履歴を示す第２のログとを取得し、
前記第１のログに含まれる前記第１の呼び出し文の実行履歴と前記第２のログに含まれる書き込み時のクエリの実行履歴との比較に基づいて、前記データベースに含まれる複数のデータ項目のうち前記第１の関数の前記引数に対応する第１のデータ項目を判定し、また、前記第１のログに含まれる前記第２の呼び出し文の実行履歴と前記第２のログに含まれる読み出し時のクエリの実行履歴との比較に基づいて、前記複数のデータ項目のうち前記第２の関数の前記返り値に対応する第２のデータ項目を判定し、
前記第１のデータ項目と前記第２のデータ項目とが同一か否かに基づいて、前記第１の変数と前記第２の変数の間の依存関係を判定する処理部と、
を有する解析装置。
【請求項２】
前記依存関係の判定では、前記処理部は、前記第１のデータ項目と前記第２のデータ項目とが同一である場合、前記第２の変数が前記第１の変数に依存していると判定する、
請求項１記載の解析装置。
【請求項３】
前記ソースコードからの検出では、前記処理部は、第３の変数と、前記第３の変数の値に基づいて前記第１の変数の値を更新する第１の命令文と、第４の変数と、前記第２の変数の値に基づいて前記第４の変数の値を更新する第２の命令文とを更に検出し、
前記依存関係の判定では、前記処理部は、前記第１のデータ項目と前記第２のデータ項目とが同一か否かに基づいて、前記第３の変数と前記第４の変数の間の依存関係を更に判定する、
請求項１記載の解析装置。
【請求項４】
前記第１のログの取得では、前記処理部は、前記第１の呼び出し文および前記第２の呼び出し文の検出に応じて、前記ソフトウェアの実行時に前記第１のログが生成されるように前記ソフトウェアの中のログ記録位置を設定する、
請求項１記載の解析装置。
【請求項５】
前記第２のログの実行履歴は、クエリ実行時までに連鎖的に呼び出された関数の列を示すスタックトレース情報を含み、
前記第１のデータ項目の判定では、前記処理部は、前記スタックトレース情報に前記第１の関数の識別情報が含まれている実行履歴を前記第２のログから抽出して前記第１の呼び出し文の実行履歴と比較し、前記第２のデータ項目の判定では、前記処理部は、前記スタックトレース情報に前記第２の関数の識別情報が含まれている実行履歴を前記第２のログから抽出して前記第２の呼び出し文の実行履歴と比較する、
請求項１記載の解析装置。
【請求項６】
前記処理部は、前記第１のログおよび前記第２のログを取得する前に、
実行されたクエリとクエリ実行時までに連鎖的に呼び出された関数の列を示すスタックトレース情報とをそれぞれ含む複数のレコードを含む第３のログを取得し、
前記第３のログに含まれるクエリを複数のクエリ種類に分類し、前記第３のログに含まれるスタックトレース情報を用いて複数の関数の呼び出し関係を示すグラフを生成し、
前記グラフの中から、前記複数のクエリ種類のうち１つのクエリ種類の実行に使用され他のクエリ種類の実行に使用されない特定関数を選択し、
前記特定関数の呼び出しについて前記第１のログを取得するよう制御する、
請求項１記載の解析装置。
【請求項７】
前記特定関数の選択では、前記処理部は、１つのクエリ種類の実行に使用され他のクエリ種類の実行に使用されない関数のうち、呼び出しの順序が遅い関数を優先的に前記特定関数として選択する、
請求項６記載の解析装置。
【請求項８】
前記第１のデータ項目および前記第２のデータ項目の判定では、前記処理部は、前記特定関数に対応するクエリ種類に基づいて、前記複数のデータ項目のうち前記第１のデータ項目および前記第２のデータ項目を絞り込む、
請求項６記載の解析装置。
【請求項９】
コンピュータが実行する解析方法であって、
データベースへのアクセスを制御するモジュールを利用するソフトウェアのソースコードから、第１の変数と、前記第１の変数を引数として用いて前記モジュールの第１の関数を呼び出す第１の呼び出し文と、第２の変数と、前記モジュールの第２の関数を呼び出し前記第２の関数の返り値を前記第２の変数に代入する第２の呼び出し文とを検出し、
前記ソフトウェアを実行させた場合に生成されるログであって、前記第１の呼び出し文および前記第２の呼び出し文の実行履歴を示す第１のログと、前記モジュールの制御に基づいて生成されたクエリの実行履歴を示す第２のログとを取得し、
前記第１のログに含まれる前記第１の呼び出し文の実行履歴と前記第２のログに含まれる書き込み時のクエリの実行履歴との比較に基づいて、前記データベースに含まれる複数のデータ項目のうち前記第１の関数の前記引数に対応する第１のデータ項目を判定し、また、前記第１のログに含まれる前記第２の呼び出し文の実行履歴と前記第２のログに含まれる読み出し時のクエリの実行履歴との比較に基づいて、前記複数のデータ項目のうち前記第２の関数の前記返り値に対応する第２のデータ項目を判定し、
前記第１のデータ項目と前記第２のデータ項目とが同一か否かに基づいて、前記第１の変数と前記第２の変数の間の依存関係を判定する、
解析方法。
【請求項１０】
コンピュータに、
データベースへのアクセスを制御するモジュールを利用するソフトウェアのソースコードから、第１の変数と、前記第１の変数を引数として用いて前記モジュールの第１の関数を呼び出す第１の呼び出し文と、第２の変数と、前記モジュールの第２の関数を呼び出し前記第２の関数の返り値を前記第２の変数に代入する第２の呼び出し文とを検出し、
前記ソフトウェアを実行させた場合に生成されるログであって、前記第１の呼び出し文および前記第２の呼び出し文の実行履歴を示す第１のログと、前記モジュールの制御に基づいて生成されたクエリの実行履歴を示す第２のログとを取得し、
前記第１のログに含まれる前記第１の呼び出し文の実行履歴と前記第２のログに含まれる書き込み時のクエリの実行履歴との比較に基づいて、前記データベースに含まれる複数のデータ項目のうち前記第１の関数の前記引数に対応する第１のデータ項目を判定し、また、前記第１のログに含まれる前記第２の呼び出し文の実行履歴と前記第２のログに含まれる読み出し時のクエリの実行履歴との比較に基づいて、前記複数のデータ項目のうち前記第２の関数の前記返り値に対応する第２のデータ項目を判定し、
前記第１のデータ項目と前記第２のデータ項目とが同一か否かに基づいて、前記第１の変数と前記第２の変数の間の依存関係を判定する、
処理を実行させる解析プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は解析装置、解析方法および解析プログラムに関する。
【背景技術】
【０００２】
コンピュータソフトウェアの開発では、既存のソースコードを修正することで、ソフトウェアへの新規機能の追加やソフトウェアの既存機能の変更を行うことがある。このとき、ソースコードの一部分の修正によって、正常に動作していた既存機能に不具合が発生するなど、変更する予定のない既存機能が意図せず変わってしまう可能性がある。そこで、既存のソースコードを修正する際には、開発者が修正の影響範囲を確認しながら修正作業を行えるように、ソフトウェア開発を支援することが好ましい。
【０００３】
例えば、ソースコードを静的に解析して、ある変数に依存している他の変数を検出する影響解析装置が提案されている。提案の影響解析装置は、変数に値を代入する命令文および変数を参照する命令文をソースコードから抽出し、変数名と代入・参照の区別と命令文の位置とを対応付けた変数情報を生成する。影響解析装置は、ユーザから変数が指定されると、指定された変数を参照している命令文の位置を検索し、検索された位置と同じ位置で値が代入されている他の変数を検索し、検索された他の変数を参照している命令文の位置を検索する。影響解析装置は、以上を反復的に実行することで、ユーザから指定された変数の影響を受ける他の変数を連鎖的に検出する。
【０００４】
また、例えば、データベースの変更によるソースコードへの影響を検出する仕様変更支援システムが提案されている。提案の仕様変更支援システムは、ユーザからテーブルのデータ項目が指定されると、指定されたデータ項目を含むＳＱＬ文をソースコードから検索する。仕様変更支援システムは、検索されたＳＱＬ文において更新対象として記載された他のデータ項目を抽出し、抽出された他のデータ項目を含むＳＱＬ文をソースコードから検索する。仕様変更支援システムは、以上を反復的に実行することで、ユーザから指定されたデータ項目の影響を受ける他のデータ項目を連鎖的に検出する。
【０００５】
また、例えば、ソースコードを静的に解析して、ある変数の変更によって影響を受けるメソッドの範囲を特定する影響範囲特定方法が提案されている。提案の影響範囲特定方法では、ソースコードに記載されたメソッド呼び出しに基づいて複数のメソッドの間における変数の値の受け渡しを検出し、それら複数のメソッドの間の依存関係を示す依存関係グラフを生成する。あるメソッドで使用されている変数がユーザから指定されると、指定された変数に格納される値の伝搬を依存関係グラフに基づいて追跡し、値が伝搬するメソッドの範囲を当該指定された変数の影響範囲として判定する。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開２００２−８２８０２号公報
【特許文献２】特開２０１１−６００６２号公報
【特許文献３】特開２０１２−２１２２８１号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
変数の値の伝搬が全て直接的にソースコードに表現されていれば、ソースコードの静的解析によって、ある変数の影響を受けるソースコードの範囲を網羅的に判定することができる。しかし、データベースにアクセスするソフトウェアの中には、Ｏ／Ｒ（Object-Relational）マッパーのようなデータベースアクセス用のライブラリを使用しているものがある。ライブラリの挙動はソースコード外部の設定ファイルで定義されることがあり、また、ライブラリ自体のソースコードを入手できないこともある。このため、ソースコードレベルで見るとライブラリの内部処理がブラックボックスになってしまうことがある。
【０００８】
この場合、ソースコードの静的解析だけでは、データベースを介した変数の値の伝搬を完全に追跡できないという問題がある。例えば、アプリケーションソフトウェアのソースコードに、ある変数を引数として与えて、データベースを更新するライブラリメソッドを呼び出す命令文が記載されているとする。また、当該ソースコードに、データベースを検索するライブラリメソッドを呼び出し、検索結果を他の変数に代入する命令文が記載されているとする。この場合、ライブラリメソッドの実装態様によっては、前者のメソッド呼び出しによってデータベースに書き込まれる値が、後者のメソッド呼び出しによって読み出されるのか否か判定することが難しいことがある。このため、後者の変数が前者の変数の影響を受けているか否か判定できないことがある。
【０００９】
１つの側面では、本発明は、データベースを介した変数の値の伝搬を検出できる解析装置、解析方法および解析プログラムを提供することを目的とする。
【課題を解決するための手段】
【００１０】
１つの態様では、記憶部と処理部とを有する解析装置が提供される。記憶部は、データベースへのアクセスを制御するモジュールを利用するソフトウェアのソースコードを記憶する。処理部は、ソースコードから、第１の変数と、第１の変数を引数として用いてモジュールの第１の関数を呼び出す第１の呼び出し文と、第２の変数と、モジュールの第２の関数を呼び出し第２の関数の返り値を第２の変数に代入する第２の呼び出し文とを検出する。処理部は、ソフトウェアを実行させた場合に生成されるログであって、第１の呼び出し文および第２の呼び出し文の実行履歴を示す第１のログと、モジュールの制御に基づいて生成されたクエリの実行履歴を示す第２のログとを取得する。処理部は、第１のログに含まれる第１の呼び出し文の実行履歴と第２のログに含まれる書き込み時のクエリの実行履歴との比較に基づいて、データベースに含まれる複数のデータ項目のうち第１の関数の引数に対応する第１のデータ項目を判定し、また、第１のログに含まれる第２の呼び出し文の実行履歴と第２のログに含まれる読み出し時のクエリの実行履歴との比較に基づいて、複数のデータ項目のうち第２の関数の返り値に対応する第２のデータ項目を判定する。処理部は、第１のデータ項目と第２のデータ項目とが同一か否かに基づいて、第１の変数と第２の変数の間の依存関係を判定する。
【００１１】
また、１つの態様では、コンピュータが実行する解析方法が提供される。また、１つの態様では、コンピュータに実行させる解析プログラムが提供される。
【発明の効果】
【００１２】
１つの側面では、データベースを介した変数の値の伝搬を検出できる。
【図面の簡単な説明】
【００１３】
【図１】第１の実施の形態の解析装置の例を示す図である。
【図２】第２の実施の形態の情報処理システムの例を示す図である。
【図３】解析装置のハードウェア例を示すブロック図である。
【図４】解析対象のソースコードの例を示す図である。
【図５】データベースを介した影響範囲の例を示す図である。
【図６】影響テーブルの例を示す図である。
【図７】未追跡テーブルの例を示す図である。
【図８】呼び出しログテーブルの例を示す図である。
【図９】ＤＢアクセスログテーブルの例を示す図である。
【図１０】対応候補テーブルの例を示す図である。
【図１１】対応テーブルの例を示す図である。
【図１２】追加影響テーブルの例を示す図である。
【図１３】解析装置の機能例を示すブロック図である。
【図１４】影響範囲解析の手順例を示すフローチャートである。
【図１５】動的解析の手順例を示すフローチャートである。
【図１６】解析装置の他の機能例を示すブロック図である。
【図１７】ラベルテーブルの例を示す図である。
【図１８】ＳＱＬ文とスタックトレースの第１の例を示す図である。
【図１９】ＳＱＬ文とスタックトレースの第２の例を示す図である。
【図２０】ＳＱＬ文とスタックトレースの第３の例を示す図である。
【図２１】呼び出しグラフの生成例を示す図である。
【図２２】呼び出しグラフの例を示す図である。
【図２３】呼び出しグラフの探索例を示す第１の図である。
【図２４】呼び出しグラフの探索例を示す第２の図である。
【図２５】ログ採取点決定の手順例を示すフローチャートである。
【図２６】呼び出しグラフ生成の手順例を示すフローチャートである。
【図２７】呼び出しグラフ探索の手順例を示すフローチャートである。
【図２８】未追跡テーブルの他の例を示す図である。
【図２９】対応候補テーブルの他の例を示す図である。
【図３０】検査テーブルの例を示す図である。
【発明を実施するための形態】
【００１４】
以下、本実施の形態を図面を参照して説明する。
［第１の実施の形態］
第１の実施の形態を説明する。
【００１５】
図１は、第１の実施の形態の解析装置の例を示す図である。
第１の実施の形態の解析装置１０は、既存ソフトウェアのソースコードを解析して変数の間の依存関係を判定し、ソースコードの修正作業を支援する。以下に説明するように、解析装置１０は、ソースコードの静的解析と実行ログを用いた動的解析とを組み合わせることで、データベースを介した変数の値の伝搬を追跡できるようにする。解析装置１０は、クライアントコンピュータでもよいしサーバコンピュータでもよい。
【００１６】
解析装置１０は、記憶部１１および処理部１２を有する。記憶部１１は、ＲＡＭ（Random Access Memory）などの揮発性の半導体メモリでもよいし、ＨＤＤ（Hard Disk Drive）やフラッシュメモリなどの不揮発性のストレージでもよい。処理部１２は、例えば、ＣＰＵ（Central Processing Unit）やＤＳＰ（Digital Signal Processor）などのプロセッサである。ただし、処理部１２は、ＡＳＩＣ（Application Specific Integrated Circuit）やＦＰＧＡ（Field Programmable Gate Array）などの特定用途の電子回路を含んでもよい。プロセッサは、ＲＡＭなどのメモリ（記憶部１１でもよい）に記憶されたプログラムを実行する。プログラムには解析プログラムが含まれる。複数のプロセッサの集合を「マルチプロセッサ」または単に「プロセッサ」と言うことがある。
【００１７】
記憶部１１は、ソースコード１４を記憶する。ソースコード１４は、モジュール１３を利用してデータベース１６にアクセスするソフトウェアのソースコードである。ソースコード１４は、例えば、オブジェクト指向言語などの高級言語で記述されている。
【００１８】
モジュール１３は、例えば、オブジェクト型データと関係型データとを相互に変換するＯ／Ｒマッパーなど、データベースアクセス用のライブラリモジュールである。解析装置１０は、モジュール１３のソースコードを有していないことがある。また、モジュール１３の挙動は、ソースコード外の独自の設定ファイルによって制御されることがある。よって、ソースコード１４から見てモジュール１３の内部処理はブラックボックスになることがある。データベース１６は、複数のデータ項目を有する。例えば、データベース１６は、データ項目として複数のカラムを有する関係型データベースである。ただし、データベース１６は、複数のデータ項目を識別できるようにデータフォーマットが規定されていればよく、ツリー型やオブジェクト型などの他の種類のデータベースでもよい。
【００１９】
処理部１２は、ソースコード１４に対して静的解析を行う。このとき、処理部１２は、ソースコード１４から変数１４ａ，１４ｂおよび呼び出し文１４ｃ，１４ｄを検出する。呼び出し文１４ｃは、変数１４ａを引数として用いて、モジュール１３が有する関数１３ａを呼び出す命令文である。呼び出し文１４ｄは、モジュール１３が有する関数１３ｂを呼び出し、関数１３ｂの返り値を変数１４ｂに代入する命令文である。
【００２０】
関数１３ａ，１３ｂは、モジュール１３の外部から呼び出し可能な処理単位であり、メソッド・手続き・セクションなど他の名称で呼ばれることもある。関数１３ａとしては、引数として受け付けた値を用いてデータベース１６を更新する機能を実装した処理単位が想定される。関数１３ｂとしては、データベース１６からデータを検索して検索結果を返り値として出力する機能を実装した処理単位が想定される。
【００２１】
上記の静的解析では、関数１３ａ，１３ｂの内部処理が不明であるため、呼び出し文１４ｃの引数がデータベース１６の何れのデータ項目に対応するか不明であり、また、呼び出し文１４ｄの返り値がデータベース１６の何れのデータ項目に対応するか不明である。このため、上記の静的解析のみでは、呼び出し文１４ｃにより書き込まれた値が呼び出し文１４ｄにより読み出されることがあるのか、呼び出し文１４ｃにより書き込まれる値と呼び出し文１４ｄにより読み出される値とが無関係であるのか、判定することが難しい。
【００２２】
そこで、解析装置１０は、このソフトウェアを実行させた場合に生成されるログを取得して動的解析を追加的に行う。好ましくは、解析装置１０は、上記の静的解析の結果に基づいてログ採取位置を限定的に設定して、当該ソフトウェアを実行させる。ソフトウェアを実行する装置は解析装置１０自身でもよいし他の装置でもよい。ただし、解析装置１０は、上記の静的解析の前に採取されたログを使用することも可能である。
【００２３】
処理部１２は、呼び出し文１４ｃ，１４ｄの実行履歴を示すログ１５ａを取得する。ログ１５ａは、例えば、関数１３ａ，１３ｂの呼び出し元をログ採取位置に設定することで取得できる。ログ１５ａは、例えば、関数１３ａを呼び出したときに指定された引数の値や、関数１３ｂを呼び出したときに得られた返り値を含む。
【００２４】
更に、処理部１２は、モジュール１３の制御に基づいて生成されたクエリの実行履歴を示すログ１５ｂを取得する。ログ１５ｂは、例えば、モジュール１３またはモジュール１３から利用される他のモジュールの中のクエリ生成機能をログ採取位置に設定することで取得できる。ログ１５ｂは、例えば、生成されたクエリ文と当該クエリ文に対するデータベース１６からの出力とを含む。クエリ文は、ＳＱＬなどデータベース１６の種類に応じたクエリ言語で記述されている。データベース１６に対する値の書き込みを示すクエリ文は、例えば、データ項目と対応付けて書き込み値を含んでいる。データベース１６からの値の読み出しを示すクエリ文は、例えば、読み出す値が格納されているデータ項目の識別情報を含み、読み出された値が当該クエリ文に付加されている。
【００２５】
一例として、ログ１５ａは、引数「２３」を指定して関数１３ａを呼び出したことを示すレコードと、関数１３ｂを呼び出して返り値「２３」を取得したことを示すレコードとを含む。ログ１５ｂは、データ項目「ｃ１」の値が「２３」でありデータ項目「ｃ２」の値が「０」であるデータを挿入するクエリ文を示すレコードを含む。また、ログ１５ｂは、データ項目「ｃ１」と「ｃ２」の値を読み出すクエリ文を示し、読み出された値がそれぞれ「２３」と「０」であることを示すレコードを含む。
【００２６】
処理部１２は、ログ１５ａに含まれる呼び出し文１４ｃの実行履歴とログ１５ｂに含まれる書き込み時のクエリの実行履歴とを比較し、関数１３ａの引数に対応するデータ項目１６ａを判定する。例えば、処理部１２は、関数１３ａの引数の値をログ１５ａから抽出し、クエリ文の中の各データ項目の書き込み値をログ１５ｂから抽出し、引数の値と一致する書き込み値が指定されたデータ項目を検出する。
【００２７】
また、処理部１２は、ログ１５ａに含まれる呼び出し文１４ｄの実行履歴とログ１５ｂに含まれる読み出し時のクエリの実行履歴とを比較し、関数１３ｂの返り値に対応するデータ項目１６ｂを判定する。データ項目１６ｂは、データ項目１６ａと同一であることもあるし同一でないこともある。例えば、処理部１２は、関数１３ｂの返り値をログ１５ａから抽出し、クエリ文に対応する出力の中の各データ項目の読み出し値をログ１５ｂから抽出し、返り値と一致する読み出し値が得られたデータ項目を検出する。
【００２８】
一例として、関数１３ａの引数の値として「２３」がログ１５ａから抽出され、データ項目「ｃ１」および「ｃ２」の書き込み値として「２３」および「０」がログ１５ｂから抽出される。この場合、引数の値とデータ項目「ｃ１」の書き込み値が一致するため、関数１３ａの引数に対応するデータ項目１６ａは「ｃ１」であると判定される。また、関数１３ｂの返り値として「２３」がログ１５ａから抽出され、データ項目「ｃ１」および「ｃ２」の読み出し値として「２３」および「０」がログ１５ｂから抽出される。この場合、返り値とデータ項目「ｃ１」の読み出し値が一致するため、関数１３ｂの返り値に対応するデータ項目１６ｂは「ｃ１」であると判定される。
【００２９】
処理部１２は、判定したデータ項目１６ａとデータ項目１６ｂとが同一か否かに基づいて、変数１４ａと変数１４ｂの間の依存関係を判定する。例えば、データ項目１６ａとデータ項目１６ｂが同一である場合、変数１４ａの値は呼び出し文１４ｃを介してデータベース１６の所定のデータ項目に書き込まれ、呼び出し文１４ｄを介してデータベース１６の当該データ項目から読み出されることがある。この場合、変数１４ａの値は変数１４ｂに伝搬することがあり、変数１４ｂは変数１４ａの影響を受けると判定される。
【００３０】
第１の実施の形態の解析装置１０によれば、ソースコード１４から変数１４ａ，１４ｂおよび呼び出し文１４ｃ，１４ｄが検出され、ログ１５ａ，１５ｂが取得される。ログ１５ａに含まれる呼び出し文１４ｃの実行履歴とログ１５ｂに含まれる書き込み時のクエリの実行履歴との比較に基づいて、関数１３ａの引数に対応するデータ項目１６ａが判定される。また、ログ１５ａに含まれる呼び出し文１４ｄの実行履歴とログ１５ｂに含まれる読み出し時のクエリの実行履歴との比較に基づいて、関数１３ｂの返り値に対応するデータ項目１６ｂが判定される。データ項目１６ａとデータ項目１６ｂとが同一か否かに基づいて、変数１４ａと変数１４ｂの間の依存関係が判定される。
【００３１】
これにより、モジュール１３を利用してデータベース１６にアクセスする場合であっても、関数の引数や返り値に対応するデータベース１６のデータ項目を判定でき、ソースコード１４の静的解析の限界を補うことができる。よって、データベース１６を介した変数の値の伝搬を高精度で追跡することが可能となり、ある変数の影響を受ける他の変数の判定精度を向上できる。その結果、ソースコード１４の修正作業を効率化できる。
【００３２】
［第２の実施の形態］
次に、第２の実施の形態を説明する。
図２は、第２の実施の形態の情報処理システムの例を示す図である。
【００３３】
第２の実施の形態の情報処理システムは、アプリケーションソフトウェアの既存ソースコードを修正して機能追加または機能変更を行う開発作業を支援する。情報処理システムは、解析装置１００およびサーバ装置２００を有する。解析装置１００およびサーバ装置２００は、ＬＡＮ（Local Area Network）などのネットワーク３０に接続されている。
【００３４】
解析装置１００は、ユーザが使用するクライアントコンピュータである。解析装置１００は、アプリケーションソフトウェアのソースコードをディスプレイに表示し、ユーザによるソースコードの修正作業を支援する。このとき、解析装置１００は、ソースコードに記載された変数の間の依存関係を解析し、ある変数の影響を受けるソースコードの範囲を判定する。例えば、解析装置１００は、ユーザから１つの変数が指定されると、指定された変数の影響を受ける他の変数やメソッドをソースコード上で強調表示する。また、例えば、解析装置１００は、影響を受ける他の変数やメソッドのリストを表示する。
【００３５】
サーバ装置２００は、アプリケーションソフトウェアを試験的に実行するサーバコンピュータである。第２の実施の形態のアプリケーションソフトウェアはデータベースを利用するため、サーバ装置２００にはデータベースが構築されている。解析装置１００の影響範囲解析では、ソースコードに加えて、アプリケーションソフトウェアを実行することで生成されるログが使用される。そこで、解析装置１００からの指示に応じてサーバ装置２００でアプリケーションソフトウェアが実行され、サーバ装置２００で生成されたログが解析装置１００に転送される。ただし、アプリケーションソフトウェアをサーバ装置２００で実行する代わりに、解析装置１００で実行するようにしてもよい。
【００３６】
図３は、解析装置のハードウェア例を示すブロック図である。
解析装置１００は、ＣＰＵ１０１、ＲＡＭ１０２、ＨＤＤ１０３、画像信号処理部１０４、入力信号処理部１０５、媒体リーダ１０６および通信インタフェース１０７を有する。上記のユニットはバスに接続されている。サーバ装置２００も、解析装置１００と同様のハードウェアを用いて実装することができる。
【００３７】
ＣＰＵ１０１は、プログラムの命令を実行する演算回路を含むプロセッサである。ＣＰＵ１０１は、ＨＤＤ１０３に記憶されたプログラムやデータの少なくとも一部をＲＡＭ１０２にロードし、プログラムを実行する。なお、ＣＰＵ１０１は複数のプロセッサコアを備えてもよく、解析装置１００は複数のプロセッサを備えてもよく、以下の処理を複数のプロセッサまたはプロセッサコアを用いて並列に実行してもよい。また、複数のプロセッサの集合を「マルチプロセッサ」または単に「プロセッサ」と言うことがある。
【００３８】
ＲＡＭ１０２は、ＣＰＵ１０１が実行するプログラムやＣＰＵ１０１が演算に用いるデータを一時的に記憶する揮発性の半導体メモリである。なお、解析装置１００は、ＲＡＭ以外の種類のメモリを備えてもよく、複数個のメモリを備えてもよい。
【００３９】
ＨＤＤ１０３は、ＯＳ（Operating System）やアプリケーションソフトウェアなどのソフトウェアのプログラム、および、データを記憶する不揮発性の記憶装置である。なお、解析装置１００は、フラッシュメモリやＳＳＤ（Solid State Drive）などの他の種類の記憶装置を備えてもよく、複数の不揮発性の記憶装置を備えてもよい。
【００４０】
画像信号処理部１０４は、ＣＰＵ１０１からの命令に従って、解析装置１００に接続されたディスプレイ１１１に画像を出力する。ディスプレイ１１１としては、ＣＲＴ（Cathode Ray Tube）ディスプレイ、液晶ディスプレイ（ＬＣＤ：Liquid Crystal Display）、プラズマディスプレイ、有機ＥＬ（ＯＥＬ：Organic Electro-Luminescence）ディスプレイなど、任意の種類のディスプレイを用いることができる。
【００４１】
入力信号処理部１０５は、解析装置１００に接続された入力デバイス１１２から入力信号を取得し、ＣＰＵ１０１に出力する。入力デバイス１１２としては、マウスやタッチパネルやタッチパッドやトラックボールなどのポインティングデバイス、キーボード、リモートコントローラ、ボタンスイッチなどを用いることができる。また、解析装置１００に複数の種類の入力デバイスが接続されていてもよい。
【００４２】
媒体リーダ１０６は、記録媒体１１３に記録されたプログラムやデータを読み取る読み取り装置である。記録媒体１１３として、例えば、磁気ディスク、光ディスク、光磁気ディスク（ＭＯ：Magneto-Optical disk）、半導体メモリなどを使用できる。磁気ディスクには、フレキシブルディスク（ＦＤ：Flexible Disk）やＨＤＤが含まれる。光ディスクには、ＣＤ（Compact Disc）やＤＶＤ（Digital Versatile Disc）が含まれる。
【００４３】
媒体リーダ１０６は、例えば、記録媒体１１３から読み取ったプログラムやデータを、ＲＡＭ１０２やＨＤＤ１０３などの他の記録媒体にコピーする。読み取られたプログラムは、例えば、ＣＰＵ１０１によって実行される。なお、記録媒体１１３は可搬型記録媒体であってもよく、プログラムやデータの配布に用いられることがある。また、記録媒体１１３やＨＤＤ１０３を、コンピュータ読み取り可能な記録媒体と言うことがある。
【００４４】
通信インタフェース１０７は、ネットワーク３０に接続され、ネットワーク３０を介してサーバ装置２００と通信を行うインタフェースである。通信インタフェース１０７は、例えば、スイッチなどの通信装置とケーブルで接続される有線通信インタフェースである。ただし、基地局と無線リンクで接続される無線通信インタフェースでもよい。
【００４５】
次に、解析装置１００による影響範囲解析について説明する。
図４は、解析対象のソースコードの例を示す図である。
ソースコード１３１は、解析対象とするソースコードの一例である。図４に示すソースコード１３１は、オブジェクト指向に基づく擬似的なソースコードである。ソースコード１３１には、「ＳａｍｐｌｅＣｌａｓｓＡ」，「ＳａｍｐｌｅＣｌａｓｓＢ」および「ＤＢＡｃｃｅｓｓ」の３つのクラスが記載されている。クラス「ＳａｍｐｌｅＣｌａｓｓＡ」はメソッド「ｍｅｔｈｏｄＡ（）」を含む。クラス「ＳａｍｐｌｅＣｌａｓｓＢ」はメソッド「ｍｅｔｈｏｄＤ（）」を含む。クラス「ＤＢＡｃｃｅｓｓ」はメソッド「ｍｅｔｈｏｄＢ（ｉｎｔ）」，「ｍｅｔｈｏｄＥ（）」を含む。
【００４６】
メソッド「ｍｅｔｈｏｄＡ（）」は、ローカル変数として整数型の変数ｘを有し、変数ｘを引数としてメソッド「ｍｅｔｈｏｄＢ（ｉｎｔ）」を呼び出している。メソッド「ｍｅｔｈｏｄＤ（）」は、ローカル変数として配列型の変数ｚを有し、メソッド「ｍｅｔｈｏｄＥ（）」を呼び出してその返り値を変数ｚに代入している。ここで使用する配列はＡｒｒａｙＬｉｓｔ＜Ｂｅａｎ＞型であり、Ｂｅａｎ型の要素を任意の数格納できる。
【００４７】
クラス「ＤＢＡｃｃｅｓｓ」は、クラスメンバとして文字列型の変数ｂを有し、クラス「ＵｒｌＭａｐｐｅｒ」を参照している。クラス「ＵｒｌＭａｐｐｅｒ」は、オブジェクト型データと関係型データとを相互に変換するＯ／Ｒマッパーであり、関係データベースへのアクセスを容易にするライブラリである。クラス「ＵｒｌＭａｐｐｅｒ」の挙動は設定ファイルによって別途定義されるため、ソースコード１３１から見てクラス「ＵｒｌＭａｐｐｅｒ」の中身はブラックボックスである。
【００４８】
メソッド「ｍｅｔｈｏｄＢ（ｉｎｔ）」は、引数として整数型の変数ａを有する。また、メソッド「ｍｅｔｈｏｄＢ（ｉｎｔ）」は、変数ａ，ｂを引数としてクラス「ＵｒｌＭａｐｐｅｒ」のメソッド「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」を呼び出している。メソッド「ｍｅｔｈｏｄＥ（）」は、ローカル変数として配列型の変数ｙを有し、クラス「ＵｒｌＭａｐｐｅｒ」のメソッド「ｍｅｔｈｏｄＦ（）」を呼び出してその返り値を変数ｙに代入している。また、メソッド「ｍｅｔｈｏｄＥ（）」は、変数ｙの値を返り値として呼び出し元に対して出力している。
【００４９】
図５は、データベースを介した影響範囲の例を示す図である。
ここでは、上記のソースコード１３１に記載された複数のメソッドの間の呼び出し関係をグラフで表現している。メソッド１３２ａは「ｍｅｔｈｏｄＡ（）」であり、整数型の変数ｘを有する。メソッド１３２ｂは「ｍｅｔｈｏｄＢ（ｉｎｔ）」であり、整数型の変数ａを有する。メソッド１３２ａは、変数ｘを引数として用いてメソッド１３２ｂを呼び出している。メソッド１３２ｃは「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」であり、整数型の変数ａと文字列型の変数ｂを有する。メソッド１３２ｂは、変数ａを引数として用いてメソッド１３２ｃを呼び出している。
【００５０】
また、メソッド１３２ｄは「ｍｅｔｈｏｄＤ（）」であり、配列型の変数ｚを有する。メソッド１３２ｅは「ｍｅｔｈｏｄＥ（）」であり、配列型の変数ｙを有し、変数ｙの値を返り値として用いる。メソッド１３２ｄはメソッド１３２ｅを呼び出し、その返り値を変数ｚに代入している。メソッド１３２ｆは「ｍｅｔｈｏｄＦ（）」である。メソッド１３２ｅはメソッド１３２ｆを呼び出し、その返り値を変数ｙに代入している。
【００５１】
メソッド１３２ｃ，１３２ｆはＯ／Ｒマッパーのメソッドであり、メソッド１３２ｃ，１３２ｆが呼び出されると何段階かのメソッド呼び出しを経由してＪＤＢＣ（Java(登録商標) Database Connectivity）メソッド１３２ｇが呼び出される。ＪＤＢＣは、関係データベースとコネクションを確立し関係データベースに対してクエリを発行するモジュールである。ＪＤＢＣメソッド１３２ｇが呼び出されると、データベーステーブル１３２ｈを操作するＳＱＬ文が出力される。以下の説明では、データベーステーブル１３２ｈの名称を「Ｔ１」と表記することがある。データベーステーブル１３２ｈは、カラムｃ１，ｃ２，ｃ３を有する。
【００５２】
第２の実施の形態では、メソッド１３２ｃを経由するメソッド呼び出しに応じて、ＪＤＢＣメソッド１３２ｇは、データベーステーブル１３２ｈにレコードを挿入するＳＱＬ文（ｉｎｓｅｒｔ文）を出力する。挿入されるレコードのカラムｃ１の値はメソッド１３２ｃの変数ａの値であり、カラムｃ２の値はメソッド１３２ｃの変数ｂの値である。カラムｃ３の値は変数ａ，ｂの値に依存しない。また、メソッド１３２ｆを経由するメソッド呼び出しに応じて、ＪＤＢＣメソッド１３２ｇは、データベーステーブル１３２ｈからレコードを検索するＳＱＬ文（ｓｅｌｅｃｔ文）を出力し、検索されたレコードを取得する。取得する各レコードにはカラムｃ１，ｃ２の値が含まれる。
【００５３】
ここで、ソースコード１３１の静的解析によれば、メソッド１３２ａの変数ｘがメソッド１３２ｂの変数ａに影響を与え、メソッド１３２ｂの変数ａがメソッド１３２ｃの変数ａに影響を与えることを検出できる。すなわち、メソッド１３２ｃの変数ａはメソッド１３２ｂの変数ａに依存し、メソッド１３２ｂの変数ａはメソッド１３２ａの変数ｘに依存する。また、静的解析によれば、メソッド１３２ｆの返り値がメソッド１３２ｅの変数ｙに影響を与え、メソッド１３２ｅの変数ｙがメソッド１３２ｄの変数ｚに影響を与えることを検出できる。すなわち、メソッド１３２ｄの変数ｚはメソッド１３２ｅの変数ｙに依存し、メソッド１３２ｅの変数ｙはメソッド１３２ｆの返り値に依存する。
【００５４】
しかし、ソースコード１３１の静的解析だけでは、メソッド１３２ｃ，１３２ｆより先のメソッド呼び出しを追跡できない。このため、メソッド１３２ｃの変数ａ，ｂが、関係データベースを介してメソッド１３２ｆの返り値に影響を与えるか否か判定できない。実際には、メソッド１３２ｃの変数ａ，ｂは、データベーステーブル１３２ｈのカラムｃ１，ｃ２を介してメソッド１３２ｆの返り値に影響を与えている。よって、メソッド１３２ａの変数ｘはメソッド１３２ｄの変数ｚに影響を与えることになる。
【００５５】
このような関係データベースを介した変数の依存関係を解析するため、解析装置１００は、ソースコードを用いた静的解析とログを用いた動的解析とを組み合わせて実行する。解析装置１００は、サーバ装置２００にソフトウェアを実行させ、追跡不能であるメソッド１３２ｃを呼び出すメソッド１３２ｂのログと、追跡不能であるメソッド１３２ｆを呼び出すメソッド１３２ｅのログとを採取する。また、解析装置１００は、クエリを発行するＪＤＢＣメソッド１３２ｇのログを採取する。ログを採取する位置は上記の位置に限定することができる。そして、解析装置１００は、後述する方法によってログを解析し、メソッド１３２ｃの変数ａ，ｂとメソッド１３２ｆの返り値との間の関係を判定する。
【００５６】
ログの採取は、例えば、次のような方法で行われる。解析装置１００は、ソースコード１３１をコンパイルしたコンパイル済みのアプリケーションプログラムをサーバ装置２００に配置する。また、解析装置１００は、ログの採取方法を示すエージェントプログラムを作成してサーバ装置２００に配置する。解析装置１００は、アプリケーションプログラムを起動するためのコマンドをサーバ装置２００に送信する。このとき、解析装置１００は、コマンドにオプションを付与して、アプリケーションプログラムにエージェントプログラムが挿入されるようにする。エージェントプログラムの挿入は、起動時にプログラムを部分的に書き換えるバイトコードインジェクションの技術を用いて実現できる。すなわち、サーバ装置２００は、アプリケーションプログラムをＲＡＭにロードする際に、エージェントプログラムに従ってアプリケーションプログラムを書き換える。これにより、ソースコード１３１を改変せずに、指定した位置でログを採取することができる。
【００５７】
なお、第２の実施の形態ではデータベースとして関係データベースを使用したが、ＸＭＬ（Extensible Markup Language）データベースなど他の種類のデータベースを使用してもよい。使用するデータベースは、複数のデータ項目が予め定義されており、所定のフォーマットのクエリによってデータ操作が行われるものであればよい。その場合、ＪＤＢＣに代えてデータベースの種類に応じたモジュールを用いてコネクションが確立される。
【００５８】
次に、影響範囲解析の手順について説明する。
図６は、影響テーブルの例を示す図である。
解析装置１００は、ソースコード１３１の静的解析により影響テーブル１４１（テーブル１）を生成する。影響テーブル１４１は、影響元の変数について、変数名、クラス名、メソッド名および変数型の項目を有する。また、影響テーブル１４１は、影響先の変数について、変数名、クラス名、メソッド名および変数型の項目を有する。変数名は、メソッドで使用されているローカル変数の名称である。クラス名は、メソッドが属するクラスの名称である。メソッド名は、メソッドの名称である。変数型は、変数の型である。
【００５９】
影響テーブル１４１には、２つの変数の間の直接的な影響関係（依存関係）が登録される。影響テーブル１４１に登録された複数の影響関係を連鎖的に組み合わせることで、ある変数の影響を受ける他の変数の範囲を判定することができる。
【００６０】
例えば、影響テーブル１４１には、メソッド「ｍｅｔｈｏｄＡ（）」の変数ｘが影響元、メソッド「ｍｅｔｈｏｄＢ（ｉｎｔ）」の変数ａが影響先である影響関係が登録される。また、メソッド「ｍｅｔｈｏｄＢ（ｉｎｔ）」の変数ａが影響元、メソッド「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」の変数ａが影響先である影響関係が登録される。また、メソッド「ｍｅｔｈｏｄＦ（）」の返り値（ｒｅｔｕｒｎ）が影響元、メソッド「ｍｅｔｈｏｄＥ（）」の変数ｙが影響先である影響関係が登録される。また、メソッド「ｍｅｔｈｏｄＥ（）」の変数ｙが影響元、メソッド「ｍｅｔｈｏｄＤ（）」の変数ｚが影響先である影響関係が登録される。なお、図６では、「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」と「ｍｅｔｈｏｄＦ（）」のソースコードが存在せず追跡不能であるため、そのクラス名を「ＤＢＡｃｃｅｓｓ」として記載している。
【００６１】
図７は、未追跡テーブルの例を示す図である。
解析装置１００は、ソースコード１３１の静的解析によって、上記の影響テーブル１４１と併せて未追跡テーブル１４２（テーブル２）を生成する。未追跡テーブル１４２は、ソースコード１３１の中に定義されておらず静的解析で未追跡となったメソッドを示す。未追跡テーブル１４２は、クラス名、メソッド名および呼び出し元の項目を有する。クラス名は、呼び出し元が属するクラスの名称である。メソッド名は、未追跡であるメソッドの名称である。呼び出し元は、未追跡のメソッドを呼び出したメソッドの名称である。
【００６２】
例えば、未追跡テーブル１４２には、クラス「ＤＢＡｃｃｅｓｓ」のメソッド「ｍｅｔｈｏｄＢ（ｉｎｔ）」が、メソッド「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」を呼び出したことが登録される。また、クラス「ＤＢＡｃｃｅｓｓ」のメソッド「ｍｅｔｈｏｄＥ（）」が、メソッド「ｍｅｔｈｏｄＦ（）」を呼び出したことが登録される。
【００６３】
図８は、呼び出しログテーブルの例を示す図である。
解析装置１００は、未追跡テーブル１４２に登録された呼び出し元におけるログ（呼び出しログ）をサーバ装置２００に採取させ、サーバ装置２００から呼び出しログを取得する。解析装置１００は、取得した呼び出しログから動的解析に使用するデータを抽出して呼び出しログテーブル１４３（テーブル３）を生成する。呼び出しログテーブル１４３は、クラス名、メソッド名、時刻、引数および返り値の項目を有する。
【００６４】
クラス名は、呼び出し元が属するクラスの名称である。メソッド名は、呼び出された未追跡のメソッドの名称である。時刻は、未追跡のメソッドが呼び出された時刻である。引数は、呼び出し先のメソッドに渡した引数の値である。引数のないメソッドを呼び出した場合は引数はｎｕｌｌとなる。返り値は、呼び出し先のメソッドから取得された返り値である。返り値のないメソッドを呼び出した場合は返り値はｎｕｌｌとなる。
【００６５】
一例として、アプリケーションソフトウェアを実行することで、メソッド「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」が３回呼び出され、メソッド「ｍｅｔｈｏｄＦ（）」が１回呼び出されたとする。「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」は、時刻１１：２２：３３に引数の値を（５０，α）として呼び出されている。また、時刻１１：２２：４３に引数の値を（３５，β）として呼び出され、時刻１１：２２：５５に引数の値を（２０，γ）として呼び出されている。「ｍｅｔｈｏｄＦ（）」は、時刻１１：２７：５９に呼び出され、返り値として｛（５０，α），（３５，β），（２０，γ）｝という配列が取得されている。なお、配列の要素である（５０，α），（３５，β），（２０，γ）はそれぞれＢｅａｎ型のオブジェクトである。
【００６６】
図９は、ＤＢアクセスログテーブルの例を示す図である。
解析装置１００は、ＪＤＢＣメソッド１３２ｇのログ（ＤＢアクセスログ）をサーバ装置２００に採取させ、サーバ装置２００からＤＢアクセスログを取得する。採取するＪＤＢＣメソッド１３２ｇのログは、関係データベースに対するコネクションがオープンしてからクローズするまでの間のＪＤＢＣメソッド１３２ｇの処理を示す。解析装置１００は、取得したＤＢアクセスログから動的解析に使用するデータを抽出してＤＢアクセスログテーブル１４４（テーブル４）を生成する。ＤＢアクセスログテーブル１４４は、時刻、ＳＱＬ文、スタックトレースおよび出力の項目を有する。
【００６７】
時刻は、ＪＤＢＣメソッド１３２ｇが呼び出された時刻である。ＳＱＬ文は、関係データベースに対して出力したクエリとしてのＳＱＬ文である。スタックトレースは、ＪＤＢＣメソッド１３２ｇが呼び出された時点におけるメソッド呼び出しのスタックトレース、すなわち、それまでに階層的に呼び出された複数のメソッドの名称を列挙したものである。メソッド「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」を経由してＪＤＢＣメソッド１３２ｇが呼び出された場合、スタックトレースには「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」の名称が含まれている。メソッド「ｍｅｔｈｏｄＦ（）」を経由してＪＤＢＣメソッド１３２ｇが呼び出された場合、スタックトレースには「ｍｅｔｈｏｄＦ（）」の名称が含まれている。出力は、ＳＱＬ文に対する応答として関係データベースから取得したデータである。関係データベースへの書き込みを示すＳＱＬ文（ｉｎｓｅｒｔ文やｕｐｄａｔｅ文など）に対しては、返り値はｎｕｌｌとなる。
【００６８】
一例として、上記の「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」の３回の呼び出しと「ｍｅｔｈｏｄＦ（）」の１回の呼び出しに対応して、ＪＤＢＣメソッド１３２ｇが４回呼び出されたとする。時刻１１：２２：３４に、書き込み値を（５０，α，５０）とするｉｎｓｅｒｔ文が発行されている。時刻１１：２２：４５に、書き込み値を（３５，β，０）とするｉｎｓｅｒｔ文が発行されている。時刻１１：２３：００に、書き込み値を（２０，γ，０）とするｉｎｓｅｒｔ文が発行されている。また、時刻１１：２８：００に、カラムｃ１，ｃ２の値を検索するｓｅｌｅｃｔ文が発行され、｛（５０，α），（３５，β），（２０，γ）｝という検索結果が取得されている。
【００６９】
図１０は、対応候補テーブルの例を示す図である。
解析装置１００は、呼び出しログテーブル１４３とＤＢアクセスログテーブル１４４を照合し、メソッドの変数と関係データベースのカラムとの対応関係の候補を抽出し、対応候補テーブル１４５（テーブル５）を生成する。対応候補テーブル１４５は、種別、変数名、クラス名、メソッド名、変数型、テーブル名、カラム名および時刻の項目を有する。
【００７０】
種別は、関係データベースに対するアクセスの種別であり、書き込みを示す「Ｗｒｉｔｅ」または読み出しを示す「Ｒｅａｄ」である。種別はＳＱＬ文から判断できる。ｉｎｓｅｒｔ文やｕｐｄａｔｅ文の種別は「Ｗｒｉｔｅ」であり、ｓｅｌｅｃｔ文の種別は「Ｒｅａｄ」である。変数名は、呼び出しログテーブル１４３に記載されたメソッドの引数または返り値としての変数の名称である。クラス名は、メソッドが属するクラスの名称である。メソッド名は、未追跡のメソッドの名称である。変数型は、変数名の項目に登録された変数の型である。テーブル名は、変数に対応する可能性があるカラムの属するデータベーステーブルの名称である。カラム名は、変数に対応する可能性があるカラムの名称である。時刻は、ＤＢアクセスログテーブル１４４の時刻である。
【００７１】
解析装置１００は、次のようにして呼び出しログテーブル１４３およびＤＢアクセスログテーブル１４４から対応候補テーブル１４５を生成する。解析装置１００は、ＤＢアクセスログテーブル１４４からレコード（ＤＢアクセスレコード）を１つ選択し、選択したＤＢアクセスレコードに含まれるスタックトレースの中から未追跡のメソッドを検出する。解析装置１００は、呼び出しログテーブル１４３から、検出した未追跡のメソッドをＤＢアクセスの直前に呼び出しているレコード（呼び出しレコード）を選択する。
【００７２】
選択したＤＢアクセスレコードに含まれるＳＱＬ文がＷｒｉｔｅ型である場合、解析装置１００は、当該ＳＱＬ文に記載された書き込み値と選択した呼び出しレコードに含まれる引数の値とを比較する。何れかの書き込み値と何れかの引数の値とが一致する場合、解析装置１００は、当該書き込み値が書き込まれるカラムと当該引数の値が格納されている変数とを、対応付け候補として対応候補テーブル１４５に登録する。
【００７３】
選択したＤＢアクセスレコードに含まれるＳＱＬ文がＲｅａｄ型である場合、解析装置１００は、選択したＤＢアクセスレコードに含まれる出力の中の各カラムの値と選択した呼び出しレコードに含まれる返り値とを比較する。返り値の中に要素として何れかのカラムの値が含まれている場合、解析装置１００は、当該カラムと返り値を示す変数とを、対応付け候補として対応候補テーブル１４５に登録する。
【００７４】
対応候補テーブル１４５のレコードは、選択したＤＢアクセスレコードと選択した呼び出しレコードから生成できる。なお、呼び出しログテーブル１４３には引数に対応する変数名は記載されていないが、解析装置１００は、静的解析を通じて変数名を取得することができる。また、ＤＢアクセスログテーブル１４４には書き込み値に対応するカラム名が記載されていないことがあるが、解析装置１００は、動的解析の中でＪＤＢＣに設定されたクエリテンプレート（プリペアードステートメント）からカラム名を取得できる。
【００７５】
一例として、解析装置１００は、図９のＤＢアクセスログテーブル１４４から１行目のＤＢアクセスレコードを選択する。選択したＤＢアクセスレコードのスタックトレースには、メソッド「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」の名称が含まれている。すると、解析装置１００は、図８の呼び出しログテーブル１４３から、当該メソッド名を含み、選択したＤＢアクセスレコードの直前の時刻を含む１行目の呼び出しレコードを選択する。「直前の時刻」は、呼び出しログテーブル１４３に記載された時刻のうち、ＤＢアクセスレコードの時刻より前であってＤＢアクセスレコードの時刻に最も近い時刻である。
【００７６】
ＤＢアクセスレコードに含まれるＳＱＬ文がＷｒｉｔｅ型であるため、解析装置１００は、呼び出しレコードに含まれる引数の値（５０，α）とＤＢアクセスレコードに含まれる書き込み値（５０，α，５０）とを比較する。１番目の引数の値が１番目・３番目の書き込み値と一致するため、解析装置１００は、変数ａとカラムｃ１の対応関係と、変数ａとカラムｃ３の対応関係を候補とする。また、２番目の引数の値が２番目の書き込み値と一致するため、解析装置１００は、変数ｂとカラムｃ２の対応関係を候補とする。
【００７７】
また、一例として、解析装置１００は、図９のＤＢアクセスログテーブル１４４から４行目のＤＢアクセスレコードを選択する。選択したＤＢアクセスレコードのスタックトレースには、メソッド「ｍｅｔｈｏｄＦ（）」の名称が含まれている。すると、解析装置１００は、図８の呼び出しログテーブル１４３から、当該メソッド名を含み、選択したＤＢアクセスレコードの直前の時刻を含む４行目の呼び出しレコードを選択する。
【００７８】
ＤＢアクセスレコードに含まれるＳＱＬ文がＲｅａｄ型であるため、解析装置１００は、呼び出しレコードに含まれる返り値｛（５０，α），（３５，β），（２０，γ）｝とＤＢアクセスレコードに含まれる出力の値｛（５０，α），（３５，β），（２０，γ）｝とを比較する。１番目のカラムの値と２番目のカラムの値がメソッドの返り値の要素として含まれているため、解析装置１００は、返り値を示す変数とカラムｃ１の対応関係と、返り値を示す変数とカラムｃ２の対応関係を候補とする。
【００７９】
図１１は、対応テーブルの例を示す図である。
解析装置１００は、対応候補テーブル１４５に記載された各時刻における対応関係の候補を一般化して、全時刻を通じた変数とカラムの対応関係を判定し、対応テーブル１４６（テーブル６）を生成する。対応テーブル１４６は、種別、変数名、クラス名、メソッド名、変数型、テーブル名およびカラム名の項目を有する。対応テーブル１４６が有するこれらの項目は、対応候補テーブル１４５の同名の項目に相当する。
【００８０】
解析装置１００は、対応候補テーブル１４５から、種別と変数名とクラス名とメソッド名と変数型が同じレコードを抽出し、全ての時刻において共通に出現するテーブル名とカラム名の組を採用し、対応テーブル１４６に登録する。解析装置１００は、一部の時刻においてのみ出現するテーブル名とカラム名の組は採用せずに破棄する。
【００８１】
一例として、解析装置１００は、種別と変数名とクラス名とメソッド名と変数型が同じレコードとして、図１０の対応候補テーブル１４５から１行目・３行目・４行目・６行目のレコードを抽出する。抽出したレコードの集合には３つの時刻が存在する。（テーブルＴ１，カラムｃ１）は３つの時刻に共通に現れる一方、（テーブルＴ１，カラムｃ３）は１つの時刻にのみ現れる。よって、解析装置１００は、変数ａが（テーブルＴ１，カラムｃ１）に対応し、（テーブルＴ１，カラムｃ３）には対応しないと判定する。
【００８２】
同様にして、解析装置１００は、種別と変数名とクラス名とメソッド名と変数型が同じレコードとして、図１０の対応候補テーブル１４５から２行目・５行目・７行目のレコードを抽出する。抽出したレコードの集合には３つの時刻が存在する。（テーブルＴ１，カラムｃ２）は３つの時刻に共通に現れるため、解析装置１００は、変数ｂが（テーブルＴ１，カラムｃ２）に対応すると判定する。
【００８３】
図１２は、追加影響テーブルの例を示す図である。
解析装置１００は、対応テーブル１４６に登録された変数とカラムの対応関係を辿ることで２つの変数の間の影響関係を抽出し、追加影響テーブル１４７（テーブル７）を生成する。追加影響テーブル１４７は、影響テーブル１４１と同様に、影響元の変数について変数名、クラス名、メソッド名および変数型の項目を有する。また、追加影響テーブル１４７は、影響先の変数について変数名、クラス名、メソッド名および変数型の項目を有する。追加影響テーブル１４７は、静的解析では検出できなかったものの動的解析によって検出された影響関係を示している。追加影響テーブル１４７のレコードを影響テーブル１４１に加えることで、関係データベースを介した変数間の影響関係が完成する。
【００８４】
解析装置１００は、対応テーブル１４６からＷｒｉｔｅ型のレコードを１つ選択し、選択したＷｒｉｔｅ型のレコードのテーブル名とカラム名を抽出する。解析装置１００は、抽出したテーブル名とカラム名を含むＲｅａｄ型のレコードを対応テーブル１４６から検索する。該当するＲｅａｄ型のレコードが検索された場合、解析装置１００は、Ｗｒｉｔｅ型のレコードの変数を影響元とし、Ｒｅａｄ型のレコードの変数を影響先とする影響関係を追加影響テーブル１４７に登録する。これは、データベーステーブルの同一のカラムを介して、影響元の変数の値が影響先の変数に伝搬することを意味する。
【００８５】
一例として、解析装置１００は、図１１の対応テーブル１４６から１行目のＷｒｉｔｅ型のレコードを選択し、選択したＷｒｉｔｅ型のレコードから（テーブルＴ１，カラムｃ１）を抽出する。解析装置１００は、（テーブルＴ１，カラムｃ１）を含む３行目のＲｅａｄ型のレコードを対応テーブル１４６から検索し、変数ａを影響元とし「ｍｅｔｈｏｄＦ（）」の戻り値を影響先とする影響関係を検出する。
【００８６】
また、解析装置１００は、図１１の対応テーブル１４６から２行目のＷｒｉｔｅ型のレコードを選択し、選択したＷｒｉｔｅ型のレコードから（テーブルＴ１，カラムｃ２）を抽出する。解析装置１００は、（テーブルＴ１，カラムｃ２）を含む４行目のＲｅａｄ型のレコードを対応テーブル１４６から検索し、変数ｂを影響元とし「ｍｅｔｈｏｄＦ（）」の戻り値を影響先とする影響関係を検出する。
【００８７】
このような追加影響テーブル１４７のレコードを図６の影響テーブル１４１に追加することで、次のような影響関係の連鎖が影響テーブル１４１に表現される。
「ｍｅｔｈｏｄＡ（）」の変数ｘは「ｍｅｔｈｏｄＢ（ｉｎｔ）」の変数ａに影響を与え、「ｍｅｔｈｏｄＢ（ｉｎｔ）」の変数ａは「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」の変数ａに影響を与える。また、「ｍｅｔｈｏｄＣ（ｉｎｔ，Ｓｔｒｉｎｇ）」の変数ａは「ｍｅｔｈｏｄＦ（）」の戻り値に影響を与える。また、「ｍｅｔｈｏｄＦ（）」の戻り値は「ｍｅｔｈｏｄＥ（）」の変数ｙに影響を与え、「ｍｅｔｈｏｄＥ（）」の変数ｙは「ｍｅｔｈｏｄＤ（）」の変数ｚに影響を与える。
【００８８】
これらの影響関係を連結すると、「ｍｅｔｈｏｄＡ（）」の変数ｘは「ｍｅｔｈｏｄＤ（）」の変数ｚに影響を与えることになる。すなわち、「ｍｅｔｈｏｄＡ（）」の変数ｘの値が「ｍｅｔｈｏｄＤ（）」の変数ｚに伝搬する。このように、関係データベースを介した変数の値の伝搬を表現することが可能となる。
【００８９】
次に、解析装置１００の機能について説明する。
図１３は、解析装置の機能例を示すブロック図である。
解析装置１００は、ソースコード記憶部１２１、静的解析部１２２、ログ収集部１２３、ログ記憶部１２４、動的解析部１２５、中間データ記憶部１２６、解析結果記憶部１２７および影響範囲出力部１２８を有する。ソースコード記憶部１２１、ログ記憶部１２４、中間データ記憶部１２６および解析結果記憶部１２７は、例えば、ＲＡＭ１０２またはＨＤＤ１０３に確保した記憶領域を用いて実装される。静的解析部１２２、ログ収集部１２３、動的解析部１２５および影響範囲出力部１２８は、例えば、ＣＰＵ１０１が実行するプログラムモジュールを用いて実装される。
【００９０】
ソースコード記憶部１２１は、アプリケーションソフトウェアのソースコード１３１を記憶する。静的解析部１２２は、ソースコード記憶部１２１に記憶されたソースコード１３１に対して静的解析を行い、ソースコード１３１から検出された変数の値の伝搬を示す影響テーブル１４１（テーブル１）を生成する。アプリケーションソフトウェアがライブラリを利用してデータベースにアクセスする場合、静的解析部１２２はデータベースを介した変数の値の伝搬を完全に追跡できないことがある。静的解析部１２２は、静的解析によって生成した影響テーブル１４１を解析結果記憶部１２７に格納する。また、静的解析部１２２は、解析できなかったメソッドを示す未追跡テーブル１４２（テーブル２）を生成して中間データ記憶部１２６に格納する。
【００９１】
ログ収集部１２３は、未追跡テーブル１４２に１以上の未追跡メソッドが登録されている場合、動的解析に使用するログを収集する。例えば、ログ収集部１２３は、アプリケーションプログラムとログ採取のためのエージェントプログラムとをサーバ装置２００に配置し、サーバ装置２００にアプリケーションプログラムを実行させる。プログラムの中のログ採取位置は、静的解析の結果に基づいて最小限に限定することができる。ログ収集部１２３は、サーバ装置２００が生成したログをサーバ装置２００から取得する。ログ収集部１２３は、ログの内容を示す呼び出しログテーブル１４３（テーブル３）およびＤＢアクセスログテーブル１４４（テーブル４）を生成してログ記憶部１２４に格納する。
【００９２】
ログ記憶部１２４は、ログ収集部１２３が生成した呼び出しログテーブル１４３およびＤＢアクセスログテーブル１４４を記憶する。動的解析部１２５は、ログ記憶部１２４に記憶された呼び出しログテーブル１４３とＤＢアクセスログテーブル１４４を使用して動的解析を行い、静的解析で追跡できなかった変数の値の伝搬を補完する。
【００９３】
動的解析部１２５は、呼び出しログテーブル１４３とＤＢアクセスログテーブル１４４とを比較して、未追跡メソッドの変数とデータベーステーブルのカラムの対応関係の候補を示す対応候補テーブル１４５（テーブル５）を生成し、中間データ記憶部１２６に格納する。動的解析部１２５は、生成した対応候補テーブル１４５を一般化して対応テーブル１４６（テーブル６）を生成し、中間データ記憶部１２６に格納する。動的解析部１２５は、生成した対応テーブル１４６を用いて、同じカラムを介して値が伝搬する変数の組を示す追加影響テーブル１４７（テーブル７）を生成し、中間データ記憶部１２６に格納する。動的解析部１２５は、追加影響テーブル１４７が示す変数の値の伝搬を、解析結果記憶部１２７に記憶された影響テーブル１４１に転記する。
【００９４】
中間データ記憶部１２６は、静的解析部１２２が生成した未追跡テーブル１４２を記憶する。また、中間データ記憶部１２６は、動的解析部１２５が生成した対応候補テーブル１４５、対応テーブル１４６および追加影響テーブル１４７を記憶する。解析結果記憶部１２７は、静的解析部１２２が生成した影響テーブル１４１を記憶する。影響テーブル１４１は動的解析部１２５によって更新されることがある。
【００９５】
影響範囲出力部１２８は、解析結果記憶部１２７に記憶された影響テーブル１４１に基づいて、影響範囲解析の結果を出力する。例えば、影響範囲出力部１２８は、影響範囲解析の結果をディスプレイ１１１に表示させる。このとき、影響範囲出力部１２８は、影響テーブル１４１に記載されたテキストをディスプレイ１１１に表示させてもよい。また、影響範囲出力部１２８は、影響範囲解析の結果を反映した態様でソースコード１３１をディスプレイ１１１に表示させてもよい。例えば、影響範囲出力部１２８は、ユーザが１つの変数を選択すると、選択された変数から影響を受ける他の変数およびメソッドを検索し、検索した他の変数およびメソッドをハイライト表示することが考えられる。
【００９６】
図１４は、影響範囲解析の手順例を示すフローチャートである。
（Ｓ１０）静的解析部１２２は、ソースコード１３１を読み込む。
（Ｓ１１）静的解析部１２２は、読み込んだソースコード１３１に対して静的解析を実行する。このとき、静的解析部１２２は、ソースコード１３１からメソッドとメソッド内のローカル変数を抽出し、メソッド呼び出しを介した変数の値の伝搬を追跡する。
【００９７】
（Ｓ１２）静的解析部１２２は、ステップＳ１１の静的解析によって検出された変数の値の伝搬を影響テーブル１４１（テーブル１）に記録する。
（Ｓ１３）静的解析部１２２は、ステップＳ１１の静的解析において、Ｏ／Ｒマッパーのメソッドなどソースコード１３１に内容が定義されていないため未追跡となったメソッドがある場合、未追跡メソッドを未追跡テーブル１４２（テーブル２）に記録する。
【００９８】
（Ｓ１４）ログ収集部１２３は、未追跡テーブル１４２に１以上のレコードが記録されているか判断する。１以上のレコードが記録されている場合はステップＳ１５に処理が進み、１つのレコードも記録されていない場合はステップＳ２１に処理が進む。
【００９９】
（Ｓ１５）ログ収集部１２３は、未追跡メソッドの呼び出し元に対して（例えば、未追跡メソッドを呼び出す直前の位置に）、呼び出しログを採取するためのログ採取モジュールを付加する。例えば、ログ収集部１２３は、バイトコードインジェクションに用いる呼び出しログ採取用のエージェントプログラムを生成する。
【０１００】
（Ｓ１６）ログ収集部１２３は、データベースとコネクションを確立しＳＱＬ文を発行するＪＤＢＣに対して、ＤＢアクセスログを採取するためのログ採取モジュールを付加する。例えば、ログ収集部１２３は、バイトコードインジェクションに用いるＤＢアクセスログ採取用のエージェントプログラムを生成する。
【０１０１】
（Ｓ１７）ログ収集部１２３は、サーバ装置２００にアプリケーションプログラムを実行させる。実行させるアプリケーションプログラムは、予めコンパイルされたものでもよいし、解析装置１００またはサーバ装置２００がソースコード１３１からコンパイルしたものでもよい。例えば、ログ収集部１２３は、アプリケーションプログラムおよびエージェントプログラムをサーバ装置２００に配置し、ロード時にアプリケーションプログラムを書き換えるオプションを付加した起動コマンドをサーバ装置２００に送信する。
【０１０２】
（Ｓ１８）ログ収集部１２３は、サーバ装置２００によるアプリケーションプログラムの実行が終了すると、サーバ装置２００から呼び出しログおよびＤＢアクセスログを読み出す。ログ収集部１２３は、呼び出しログの内容を呼び出しログテーブル１４３（テーブル３）に記録する。また、ログ収集部１２３は、ＤＢアクセスログの内容をＤＢアクセスログテーブル１４４（テーブル４）に記録する。
【０１０３】
（Ｓ１９）動的解析部１２５は、呼び出しログテーブル１４３およびＤＢアクセスログテーブル１４４を用いて動的解析を行い、動的解析の結果を追加影響テーブル１４７（テーブル７）に記録する。動的解析の手順については後述する。
【０１０４】
（Ｓ２０）動的解析部１２５は、追加影響テーブル１４７を影響テーブル１４１に統合する。すなわち、動的解析部１２５は、追加影響テーブル１４７に記録された変数の値の伝搬を影響テーブル１４１に転記する。これにより、影響テーブル１４１には、未追跡メソッドを呼び出すまでの区間の伝搬と未追跡メソッドを呼び出して関係データベースにアクセスする区間の伝搬との両方が記録され、両者の連携が表現される。
【０１０５】
（Ｓ２１）影響範囲出力部１２８は、影響テーブル１４１に基づいて影響範囲解析の結果を出力する。例えば、影響範囲出力部１２８は、ある１つの変数から開始して、影響テーブル１４１に記録された複数のレコードを連続的に辿ることで、当該１つの変数の影響を受ける全ての他の変数や全てのメソッドを網羅的に検索することができる。
【０１０６】
図１５は、動的解析の手順例を示すフローチャートである。
この動的解析は、前述のステップＳ１９で実行される。
（Ｓ３０）動的解析部１２５は、ＤＢアクセスログテーブル１４４（テーブル４）に記録されているＤＢアクセスレコードを１つ選択する。
【０１０７】
（Ｓ３１）動的解析部１２５は、ステップＳ３０で選択したＤＢアクセスレコードに含まれるスタックトレースの中から、未追跡テーブル１４２（テーブル２）に記録されている未追跡メソッドの名称を検索する。
【０１０８】
（Ｓ３２）動的解析部１２５は、スタックトレースから何れかの未追跡メソッドが検出されたか判断する。何れかの未追跡メソッドが検出された場合はステップＳ３３に処理が進み、検出されなかった場合はステップＳ３７に処理が進む。
【０１０９】
（Ｓ３３）動的解析部１２５は、呼び出しログテーブル１４３（テーブル３）から、ステップＳ３２の未追跡メソッドの呼び出しを示しており、選択したＤＢアクセスレコードの直前に生成された呼び出しレコードを選択する。
【０１１０】
（Ｓ３４）動的解析部１２５は、ステップＳ３０で選択したＤＢアクセスレコードに含まれるＳＱＬ文が、関係データベースを更新するＷｒｉｔｅ型であるか判断する。ｉｎｓｅｒｔ文やｕｐｄａｔｅ文はＷｒｉｔｅ型であり、ｓｅｌｅｃｔ文はＲｅａｄ型である。ＳＱＬ文がＷｒｉｔｅ型である場合はステップＳ３５に処理が進み、ＳＱＬ文がＲｅａｄ型である場合はステップＳ３６に処理が進む。
【０１１１】
（Ｓ３５）動的解析部１２５は、選択した呼び出しレコードに含まれる引数の値と選択したＤＢアクセスレコードに含まれるＳＱＬ文の中の書き込み値とを比較し、引数に相当する変数とデータベーステーブルのカラムとの対応関係の候補を生成する。動的解析部１２５は、生成した対応関係の候補を対応候補テーブル１４５（テーブル５）に記録する。そして、ステップＳ３７に処理が進む。
【０１１２】
（Ｓ３６）動的解析部１２５は、選択した呼び出しレコードに含まれる返り値と選択したＤＢアクセスレコードに含まれるＳＱＬ文に対する出力値とを比較し、返り値に相当する変数とデータベーステーブルのカラムとの対応関係の候補を生成する。動的解析部１２５は、生成した対応関係の候補を対応候補テーブル１４５に記録する。
【０１１３】
（Ｓ３７）動的解析部１２５は、ステップＳ３０においてＤＢアクセスログテーブル１４４から全てのＤＢアクセスレコードを選択したか判断する。全てのＤＢアクセスレコードを選択した場合はステップＳ３８に処理が進み、未選択のＤＢアクセスレコードがある場合はステップＳ３０に処理が進む。
【０１１４】
（Ｓ３８）動的解析部１２５は、対応候補テーブル１４５から全時刻に共通に現れる変数とカラムの対応関係の候補を抽出し、正しい対応関係として採用する。動的解析部１２５は、採用した対応関係を対応テーブル１４６（テーブル６）に記録する。
【０１１５】
（Ｓ３９）動的解析部１２５は、対応テーブル１４６から、テーブル名およびカラム名が共通するＷｒｉｔｅ型のレコードとＲｅａｄ型のレコードの組み合わせを検索する。動的解析部１２５は、検索されたＷｒｉｔｅ型のレコードとＲｅａｄ型のレコードとを結合して、前者に記載された変数を影響元とし後者に記載された変数を影響先とする伝搬関係を決定する。動的解析部１２５は、決定した変数の値の伝搬を追加影響テーブル１４７（テーブル７）に記録する。そして、動的解析が終了する。
【０１１６】
第２の実施の形態の情報処理システムによれば、既存ソースコードの修正作業の際に、ある変数の影響を受ける他の変数やメソッドを可視化することができる。よって、意図しない不具合の発生を抑制でき、修正作業を効率化することができる。また、ソースコードの静的解析だけでは追跡できないメソッドを呼び出して関係データベースにアクセスしている場合であっても、動的解析を併用して変数とカラムの対応関係を判定できる。よって、関係データベースを介した変数の値の伝搬を精度よく追跡することができる。
【０１１７】
また、静的解析で不足する情報のみを動的解析によって補完すればよいため、動的解析のみで全ての変数の値の伝搬を追跡する場合と比べて、ログを採取する位置を限定することができる。また、ソースコードを用いた静的解析をベースとするため、変数の値の伝搬を網羅的に抽出することが容易となる。よって、影響範囲分析を効率化できる。
【０１１８】
［第３の実施の形態］
次に、第３の実施の形態を説明する。第２の実施の形態との違いを中心に説明し、第２の実施の形態と同様の内容については説明を省略することがある。
【０１１９】
第２の実施の形態では、図８の呼び出しログを採取する対象メソッド（ログ採取点）は、ソースコードの静的解析によって追跡できなかった未追跡メソッドである。この未追跡メソッドは、関係データベースに対してＳＱＬ文を実行するＪＤＢＣメソッドにできる限り近いメソッドである。しかし、アプリケーションソフトウェアによっては、複数のデータベーステーブルや複数種類のＳＱＬ文が使用されることがあり、ログ採取点の設定が不適切であると、データベーステーブルのカラムとソースコード上の変数との対応付けの精度が低下することがある。そこで、第３の実施の形態では、呼び出しログを採取するログ採取点をＳＱＬ文の種類毎に適切に設定できるようにする。
【０１２０】
まず、データベーステーブルのカラムとソースコード上の変数とを対応付ける精度に影響を与える状況について説明する。ユーザが作成したソースコードに、複数のデータベーステーブルへのアクセスに使用される共通メソッド（ＤＢアクセッサ）が定義されているとする。ＤＢアクセッサに対してＳＱＬ文の種類を示す引数を指定することで、このＤＢ
アクセッサを介して異なるデータベーステーブルにアクセスすることが可能となる。
【０１２１】
例えば、データベースには、カラムＣ１を含むテーブルＴａと、カラムＣ２を含むテーブルＴｂが含まれているとする。また、ソースコードには、ＤＢアクセッサであるメソッドｍｃと、変数ａを用いてメソッドｍｃを呼び出すメソッドｍａと、変数ｂを用いてメソッドｍｃを呼び出すメソッドｍｂが記載されているとする。メソッドｍａはメソッドｍｃを介してテーブルＴａにアクセスしており、変数ａはテーブルＴａのカラムＣ１に影響を与える。また、メソッドｍｂはメソッドｍｃを介してテーブルＴｂにアクセスしており、変数ｂはテーブルＴｂのカラムＣ２に影響を与える。
【０１２２】
メソッドｍａ，ｍｂよりもメソッドｍｃの方がＪＤＢＣメソッドに近いことから、ＤＢアクセッサであるメソッドｍｃをログ採取点に設定することが考えられる。しかし、その場合にはメソッドｍａからの呼び出しとメソッドｍｂからの呼び出しとが区別されず、誤った依存関係を判定してしまう可能性がある。例えば、メソッドｍａの変数ａがテーブルＴｂのカラムＣ２に影響を与えるという依存関係や、メソッドｍｂの変数ｂがテーブルＴａのカラムＣ１に影響を与えるという依存関係を判定してしまう可能性がある。
【０１２３】
一方で、ソースコード上で複数のメソッドから呼び出される共通メソッドを常にログ採取点から除外してしまうと、ログ採取点がＪＤＢＣメソッドから遠く離れてしまう可能性がある。ログ採取点とＪＤＢＣメソッドが離れていると、ログ採取点における変数の値がＪＤＢＣメソッドに伝搬するまでに加工されてしまい、呼び出しログとＤＢアクセスログを比較してもカラムと変数を対応付けることができない場合がある。
【０１２４】
そこで、第３の実施の形態では、複数種類のＳＱＬ文それぞれに対して、他の種類のＳＱＬ文と区別できる範囲でＪＤＢＣメソッドにできる限り近いメソッドをログ採取点として設定する。このために、第３の実施の形態では２段階でログ採取を行う。第１段階ではＪＤＢＣメソッドにログ採取モジュールを付加して、データベースアクセス毎にＳＱＬ文とスタックトレースを取得する。取得したＳＱＬ文とスタックトレースに基づいて、呼び出しログを採取するログ採取点をＳＱＬ文の種類毎に決定する。第２段階では決定したログ採取点の呼び出し元とＪＤＢＣメソッドにログ採取モジュールを付加して、第２の実施の形態と同様に呼び出しログとＤＢアクセスログを取得する。このように、第３の実施の形態では動的解析を通じて呼び出しログのログ採取点を決定する。決定したログ採取点は、第２の実施の形態の未追跡メソッドとして取り扱われる。
【０１２５】
次に、第３の実施の形態の解析装置１００ａを説明する。解析装置１００ａは、第２の実施の形態の解析装置１００に代えて使用される。なお、解析装置１００ａは、図３と同様のハードウェアを用いて実装することができる。
【０１２６】
図１６は、解析装置の他の機能例を示すブロック図である。
解析装置１００ａは、ソースコード記憶部１２１、静的解析部１２２ａ、ログ収集部１２３ａ、ログ記憶部１２４、動的解析部１２５、中間データ記憶部１２６、解析結果記憶部１２７、影響範囲出力部１２８およびログ採取点決定部１２９を有する。静的解析部１２２ａ、ログ収集部１２３ａおよびログ採取点決定部１２９は、例えば、ＣＰＵ１０１が実行するプログラムモジュールを用いて実装される。
【０１２７】
静的解析部１２２ａは、第２の実施の形態の静的解析部１２２と同様に、ソースコード記憶部１２１に記憶されたソースコードに対して静的解析を行う。ただし、図７の未追跡テーブル１４２（テーブル２）のメソッドはログ採取点決定部１２９によって決定されるため、静的解析部１２２ａは未追跡テーブル１４２を生成しなくてもよい。
【０１２８】
ログ収集部１２３ａは、静的解析部１２２ａによる静的解析の後、第１段階として、ログ採取点決定部１２９によって使用されるログを収集する。第１段階のログには、ＪＤＢＣメソッドを実行した際のＳＱＬ文とスタックトレースが含まれる。また、ログ収集部１２３ａは、ログ採取点決定部１２９によってログ採取点が決定されると、第２段階として、動的解析部１２５によって使用されるログを収集する。第２段階のログには、ログ採取点決定部１２９によって決定されたログ採取点における呼び出しログと、ＤＢアクセスログが含まれる。例えば、ログ収集部１２３ａは、アプリケーションプログラムとログ採取のためのエージェントプログラムとをサーバ装置２００に配置し、サーバ装置２００にアプリケーションプログラムを実行させる。ログ収集部１２３ａは、サーバ装置２００が生成したログをサーバ装置２００から取得する。なお、ログ収集部１２３ａは、静的解析部１２２ａによる静的解析の前に第１段階のログ採取を行ってもよい。
【０１２９】
ログ採取点決定部１２９は、ログ収集部１２３ａが収集した第１段階のログを分析して、第２の実施の形態の未追跡メソッドに相当するログ採取点（「ＤＢ対応付けログ採取メソッド」などと言うこともできる）を決定する。このとき、ログ採取点決定部１２９は、ログに含まれるＳＱＬ文を複数の種類に分類すると共に、ログに含まれるスタックトレースから複数のメソッドの呼び出し関係を示す呼び出しグラフを生成する。ログ採取点決定部１２９は、ＳＱＬ文の種類と呼び出しグラフ上での実行経路との関係を分析し、動的解析に適したメソッドをＳＱＬ文の種類毎に選択する。ある種類のＳＱＬ文にとって動的解析に適したメソッドとは、他の種類のＳＱＬ文と区別することが容易なメソッドのうちＪＤＢＣメソッドにできる限り近いメソッドである。
【０１３０】
図１７は、ラベルテーブルの例を示す図である。
ラベルテーブル１４８（テーブル８）は、ログ採取点決定部１２９によって生成されて中間データ記憶部１２６に記憶される。上記のように、ログ採取点決定部１２９は第１段階のログに含まれるＳＱＬ文を複数種類に分類する。ラベルテーブル１４８は、ＳＱＬ文の種類とラベルとを対応付けている。
【０１３１】
ＳＱＬ文の種類は、データベース操作のコマンド種別（ＩＮＳＥＲＴやＳＥＬＥＣＴ）と操作対象テーブルのテーブル名と操作対象カラムのカラム名に基づいて決定される。コマンド種別とテーブル名とカラム名の全てが同じＳＱＬ文は同じ種類のＳＱＬ文であり、コマンド種別とテーブル名とカラム名の少なくとも１つが異なるＳＱＬ文は異なる種類のＳＱＬ文である。ＷＨＥＲＥ句のような条件情報は、ＳＱＬ文の種類に影響しない。
【０１３２】
ＳＱＬ文の中の一部の文字列が、そのＳＱＬ文の種類を示す種類部分として抽出される。種類部分が同じＳＱＬ文は同じ種類のＳＱＬ文である。例えば、ＳＥＬＥＣＴ文の場合、先頭からＷＨＥＲＥ句の前までの文字列が種類部分として抽出される。「ＳＥＬＥＣＴ  Ｃ１，Ｃ２，Ｃ３  ＦＲＯＭ  Ｔ１  ＷＨＥＲＥ  Ｃ１＝０」というＳＱＬ文からは、「ＳＥＬＥＣＴ  Ｃ１，Ｃ２，Ｃ３  ＦＲＯＭ  Ｔ１」が種類部分として抽出される。また、例えば、ＩＮＳＥＲＴ文の場合、先頭からＶＡＬＵＥＳの前までの文字列が種類部分として抽出される。「ＩＮＳＥＲＴ  ＩＮＴＯ  Ｔ１（Ｃ１，Ｃ２，Ｃ３）  ＶＡＬＵＥＳ（１０，２０，３０）」というＳＱＬ文からは、「ＩＮＳＥＲＴ  ＩＮＴＯ  Ｔ１（Ｃ１，Ｃ２，Ｃ３）」が種類部分として抽出される。
【０１３３】
ＳＱＬ文の種類部分に対して、簡潔な文字列としてラベルが付与される。例えば、「ＳＥＬＥＣＴ  ｐｆａ＿ｕｓｅｒ＿ｐａｓｓｗｏｒｄ＿ｉｄ，ｕｓｅｒ＿ｉｄ，ｃｈａｎｇｅ＿ｄａｔｅ，ｐａｓｓｗｏｒｄ，ｄｅｌｅｔｅ＿ｆｌａｇ，ｉｎｓｅｒｔ＿ｄａｔｅ，ｉｎｓｅｒｔ＿ｕｓｅｒ，ｕｐｄａｔｅ＿ｄａｔｅ，ｕｐｄａｔｅ＿ｕｓｅｒ  ＦＲＯＭ  ｐｆａ＿ｕｓｅｒ＿ｐａｓｓｗｏｒｄ」に対してラベルＳ１が付与される。
【０１３４】
図１８は、ＳＱＬ文とスタックトレースの第１の例を示す図である。
ログ収集部１２３ａによって収集される第１段階のログは複数のレコードを含む。これら複数のレコードはログ記憶部１２４に記憶される。１つのレコードはＪＤＢＣメソッドの１回の実行によって生成され、実行されたＳＱＬ文とＪＤＢＣメソッドが呼び出されるまでに経由したメソッドの列を示すスタックトレースとを含む。
【０１３５】
一例として、ＳＱＬ文１５１とスタックトレース１５２を含むレコードがログ記憶部１２４に記憶される。ＳＱＬ文１５１はＳＥＬＥＣＴ文であり、１個のテーブル名と９個のカラム名を含む。ＳＱＬ文１５１はラベルＳ１に分類される。スタックトレース１５２は、ＳＱＬ文１５１を実行する際に呼び出されたメソッドをＪＤＢＣメソッドに近い順に列挙したものである。スタックトレース１５２は、ＪＤＢＣメソッドと画面制御メソッドの間に４個のメソッドのメソッド名を含んでいる。クラスＢａｓｅＤａｏのメソッドｅｘｅｃｕｔｅＱｕｅｒｙ、クラスＰｆａＵｓｅｒＰａｓｓｗｏｒｄＤａｏのメソッドｆｉｎｄＦｏｒＩｎｆｏ、クラスＡｕｔｈＢｅａｎのメソッドａｕｔｈｅｎｔｉｃａｔｅ、クラスＡｕｔｈＡｃｔｉｏｎのメソッドａｕｔｈが記載されている。
【０１３６】
図１９は、ＳＱＬ文とスタックトレースの第２の例を示す図である。
更に一例として、ＳＱＬ文１５３とスタックトレース１５４を含むレコードがログ記憶部１２４に記憶される。ＳＱＬ文１５３はＳＥＬＥＣＴ文であり、１個のテーブル名と１１個のカラム名を含む。ＳＱＬ文１５３はラベルＳ２に分類される。スタックトレース１５４は、ＳＱＬ文１５３を実行する際に呼び出されたメソッドをＪＤＢＣメソッドに近い順に列挙したものである。スタックトレース１５４は、ＪＤＢＣメソッドと画面制御メソッドの間に４個のメソッドのメソッド名を含んでいる。クラスＢａｓｅＤａｏのメソッドｅｘｅｃｕｔｅＱｕｅｒｙ、クラスＰｆｍＵｓｅｒＤａｏのメソッドｆｉｎｄＦｏｒＩｎｆｏ、クラスＵｓｅｒＣｈｅｃｋＢｅａｎのメソッドｃｈｅｃｋＵｓｅｒＲｏｌｅ、クラスＡｕｔｈＡｃｔｉｏｎのメソッドａｕｔｈが記載されている。
【０１３７】
図２０は、ＳＱＬ文とスタックトレースの第３の例を示す図である。
更に一例として、ＳＱＬ文１５５とスタックトレース１５６を含むレコードがログ記憶部１２４に記憶される。ＳＱＬ文１５５はＳＥＬＥＣＴ文であり、ＳＱＬ文１５３と同じテーブル名とカラム名を含む。ＳＱＬ文１５５はラベルＳ２に分類される。スタックトレース１５６は、ＳＱＬ文１５５を実行する際に呼び出されたメソッドをＪＤＢＣメソッドに近い順に列挙したものである。スタックトレース１５６は、ＪＤＢＣメソッドと画面制御メソッドの間に４個のメソッドのメソッド名を含んでいる。クラスＢａｓｅＤａｏのメソッドｅｘｅｃｕｔｅＱｕｅｒｙ、クラスＰｆｍＵｓｅｒＤａｏのメソッドｆｉｎｄＦｏｒＩｎｆｏ、クラスＵｓｅｒＭａｓｔｅｒＲｅｆｅｒｅｎｃｅＢｅａｎのメソッドｇｅｔＵｓｅｒＩｎｆｏ、クラスＡｕｔｈＡｃｔｉｏｎのメソッドａｕｔｈが記載されている。
【０１３８】
図２１は、呼び出しグラフの生成例を示す図である。
ログ記憶部１２４に記憶された１つのレコードからは１つの部分グラフを生成することができる。各部分グラフは、スタックトレースに記載されたメソッドを表すノードとメソッド間の呼び出し関係を表すリンクとを含む有向グラフである。各ノードに対しては、ＳＱＬ文の種類を示すラベルが付加される。複数のレコードに対応する複数の部分グラフを合成することで、全体のメソッド呼び出し関係を示す呼び出しグラフが生成される。
【０１３９】
上記のＳＱＬ文１５１とスタックトレース１５２からは部分グラフ１６１が生成される。部分グラフ１６１は、スタックトレース１５２に記載された４個のメソッドを表す４個のノードを含む。部分グラフ１６１の各ノードにはラベルＳ１が付加されている。また、上記のＳＱＬ文１５３とスタックトレース１５４からは部分グラフ１６２が生成される。部分グラフ１６２は、スタックトレース１５４に記載された４個のメソッドを表す４個のノードを含む。部分グラフ１６２の各ノードにはラベルＳ２が付加されている。上記のＳＱＬ文１５５とスタックトレース１５６からは部分グラフ１６３が生成される。部分グラフ１６３は、スタックトレース１５６に記載された４個のメソッドを表す４個のノードを含む。部分グラフ１６３の各ノードにはラベルＳ２が付加されている。
【０１４０】
部分グラフ１６１，１６２，１６３を合成することで呼び出しグラフ１６４が生成される。部分グラフ１６１，１６２，１６３の間で同じメソッドを表すノードは単一のノードに集約される。このとき、集約したノードに付加されるラベルは、集約前のノードに付加されていたラベルの和集合となる。例えば、クラスＡｕｔｈＡｃｔｉｏｎのメソッドａｕｔｈを表すノードは部分グラフ１６１，１６２，１６３に共通に含まれている。呼び出しグラフ１６４は、クラスＡｕｔｈＡｃｔｉｏｎのメソッドａｕｔｈを表す単一のノードを含み、そのノードにはラベルＳ１，Ｓ２が付加される。
【０１４１】
生成される呼び出しグラフは、ＪＤＢＣメソッドを表すノードを終点ノードとしてもつグラフであるが、ツリー構造になるとは限らない。ノード間のリンクは、画面制御メソッドを表すノードからＪＤＢＣメソッドを表すノードに向かう方向をもつ。ＪＤＢＣメソッド側が下流であり、画面制御メソッド側が上流である。
【０１４２】
図２２は、呼び出しグラフの例を示す図である。
呼び出しグラフ１６５は、更に他のＳＱＬ文およびスタックトレースを用いて呼び出しグラフ１６４を拡張したものである。呼び出しグラフ１６５は、ノード１６５ａ，１６５ｂ，１６５ｃ，１６５ｄ，１６５ｅ，１６５ｆ，１６５ｇ，１６５ｈ，１６５ｉ，１６５ｊ，１６５ｋ，１６５ｌ，１６５ｍ，１６５ｎを含む。
【０１４３】
ノード１６５ａ，１６５ｂは、ＪＤＢＣメソッドを示す終点ノードから距離１のノードである。ノード１６５ａは、クラスＢａｓｅＤａｏのメソッドｅｘｅｃｕｔｅＱｕｅｒｙを示し、ラベルＳ１，Ｓ２，Ｓ５をもつ。ノード１６５ａの次段は終点ノードである。ノード１６５ｂは、クラスＢａｓｅＤａｏのメソッドｅｘｅｃｕｔｅＵｐｄａｔｅを示し、ラベルＳ３，Ｓ４をもつ。ノード１６５ｂの次段は終点ノードである。
【０１４４】
ノード１６５ｃ，１６５ｄ，１６５ｅ，１６５ｆは、終点ノードから距離２のノードである。ノード１６５ｃは、クラスＰｆｍＵｓｅｒＰａｓｓｗｏｒｄＤａｏのメソッドｆｉｎｄＦｏｒＩｎｆｏを示し、ラベルＳ１をもつ。ノード１６５ｃの次段はノード１６５ａである。ノード１６５ｄは、クラスＰｆｍＵｓｅｒＤａｏのメソッドｆｉｎｄＦｏｒＩｎｆｏを示し、ラベルＳ２をもつ。ノード１６５ｄの次段はノード１６５ａである。ノード１６５ｅは、クラスＴｍｄＴｉｍｅＲｅｃｏｒｄＤａｏのメソッドｆｉｎｄＦｏｒＫｅｙを示し、ラベルＳ５をもつ。ノード１６５ｅの次段はノード１６５ａである。ノード１６５ｆは、クラスＢａｓｅＤａｏのメソッドｉｎｓｅｒｔを示し、ラベルＳ３，Ｓ４をもつ。ノード１６５ｆの次段はノード１６５ｂである。
【０１４５】
ノード１６５ｇ，１６５ｈ，１６５ｉ，１６５ｊ，１６５ｋは、終点ノードから距離３のノードである。ノード１６５ｇは、クラスＡｕｔｈＢｅａｎのメソッドａｕｔｈｅｎｔｉｃａｔｅを示し、ラベルＳ１をもつ。ノード１６５ｇの次段はノード１６５ｃである。ノード１６５ｈは、クラスＵｓｅｒＣｈｅｃｋＢｅａｎのメソッドｃｈｅｃｋＵｓｅｒＲｏｌｅを示し、ラベルＳ２をもつ。ノード１６５ｈの次段はノード１６５ｄである。ノード１６５ｉは、クラスＵｓｅｒＭａｓｔｅｒＲｅｆｅｒｅｎｃｅＢｅａｎのメソッドｇｅｔＵｓｅｒＩｎｆｏを示し、ラベルＳ２をもつ。ノード１６５ｉの次段はノード１６５ｄである。ノード１６５ｊは、クラスＴｉｍｅＲｅｃｏｒｄＲｅｇｉｓｔＢｅａｎのメソッドｃｈｅｃｋＩｎｓｅｒｔを示し、ラベルＳ５をもつ。ノード１６５ｊの次段はノード１６５ｅである。ノード１６５ｋは、クラスＲｅｓｔＲｅｇｉｓｔＢｅａｎのメソッドｉｎｓｅｒｔを示し、ラベルＳ３をもつ。ノード１６５ｋの次段はノード１６５ｆである。
【０１４６】
ノード１６５ｌ，１６５ｍは、終点ノードから距離４のノードである。ノード１６５ｌは、クラスＡｕｔｈＡｃｔｉｏｎのメソッドａｕｔｈを示し、ラベルＳ１，Ｓ２をもつ。ノード１６５ｌの次段はノード１６５ｇ，１６５ｈ，１６５ｉである。ノード１６５ｍは、クラスＴｉｍｅＲｅｃｏｒｄＲｅｇｉｓｔＢｅａｎのメソッドｉｎｓｅｒｔを示し、ラベルＳ４，Ｓ５をもつ。ノード１６５ｍの次段はノード１６５ｆ，１６５ｊである。
【０１４７】
ノード１６５ｎは、終点ノードから距離５のノードである。ノード１６５ｎは、クラスＴｉｍｅＲｅｃｏｒｄＢｅａｎのメソッドｒｅｃｏｒｄＰｏｒｔａｌＴｉｍｅを示し、ラベルＳ３，Ｓ４，Ｓ５をもつ。ノード１６５ｎの次段はノード１６５ｍ，１６５ｋである。呼び出しグラフ１６５は、画面制御メソッドを示す始点ノードを含む。ノード１６５ｌ，１６５ｎの前段は、例えば、始点ノードである。
【０１４８】
次に、上記の呼び出しグラフ１６５を用いて、ＳＱＬ文の種類毎に適切なログ採取点を決定する方法、すなわち、ラベル毎に適切なノードを選択する方法を説明する。
図２３は、呼び出しグラフの探索例を示す第１の図である。
【０１４９】
ログ採取点決定部１２９は、ＪＤＢＣメソッドを示す終点ノードから近い順に、単一のラベルをもつノードを探索する。単一のラベルをもつノードが検出された場合、ログ採取点決定部１２９は、当該ノードがもつラベルに対して当該ノードが示すメソッドを対応付ける。これにより、ＳＱＬ文の種類１つに対して１つのメソッドがログ採取点として割り当てられる。また、ログ採取点決定部１２９は、当該ノードから上流（始点ノード方向）に向かって、他のノードから当該ラベルを削除する。原則として、全てのラベルに対してメソッドが対応付けられるまでこれを繰り返す。
【０１５０】
上記の呼び出しグラフ１６５に対しては、まずログ採取点決定部１２９は、距離１のノード１６５ａ，１６５ｂを検査する。ノード１６５ａ，１６５ｂがもつラベルは何れも単一のラベルではない。次にログ採取点決定部１２９は、距離２のノード１６５ｃ，１６５ｄ，１６５ｅ，１６５ｆを検査する。ノード１６５ｆがもつラベルは単一のラベルではない一方、ノード１６５ｃ，１６５ｄ，１６５ｅがもつラベルは単一のラベルである。
【０１５１】
ログ採取点決定部１２９は、ラベルＳ１に対してノード１６５ｃのメソッドを対応付け、ノード１６５ｃより上流に位置するノード１６５ｇ，１６５ｌからラベルＳ１を削除する。また、ログ採取点決定部１２９は、ラベルＳ２に対してノード１６５ｄのメソッドを対応付け、ノード１６５ｄより上流に位置するノード１６５ｈ，１６５ｉ，１６５ｌからラベルＳ２を削除する。また、ログ採取点決定部１２９は、ラベルＳ５に対してノード１６５ｅのメソッドを対応付け、ノード１６５ｅより上流に位置するノード１６５ｊ，１６５ｍ，１６５ｎからラベルＳ５を削除する。
【０１５２】
この時点ではまだラベルＳ３，Ｓ４に対してメソッドが対応付けられていないため、ログ採取点決定部１２９は呼び出しグラフ１６５の探索を継続する。
図２４は、呼び出しグラフの探索例を示す第２の図である。
【０１５３】
次にログ採取点決定部１２９は、距離３のノード１６５ｇ，１６５ｈ，１６５ｉ，１６５ｊ，１６５ｋを検査する。ノード１６５ｇ，１６５ｈ，１６５ｉ，１６５ｊがもつラベルは単一のラベルではない一方、ノード１６５ｋがもつラベルは単一のラベルである。ログ採取点決定部１２９は、ラベルＳ３に対してノード１６５ｋのメソッドを対応付け、ノード１６５ｋより上流に位置するノード１６５ｎからラベルＳ３を削除する。
【０１５４】
次にログ採取点決定部１２９は、距離４のノード１６５ｌ，１６５ｍを検査する。ノード１６５ｌがもつラベルは単一のラベルではない一方、ノード１６５ｍがもつラベルは単一のラベルである。ログ採取点決定部１２９は、ラベルＳ４に対してノード１６５ｍのメソッドを対応付け、ノード１６５ｍより上流に位置するノード１６５ｎからラベルＳ４を削除する。これにより全てのラベルに対してメソッドが対応付けられたため、ログ採取点決定部１２９は呼び出しグラフ１６５の探索を終了する。
【０１５５】
以上により、異なる種類のＳＱＬ文に対して異なるメソッドがログ採取点として割り当てられる。ノード１６５ｃ，１６５ｄ，１６５ｅ，１６５ｋ，１６５ｍのメソッドがログ採取点である。よって、第２段階のログ採取では、ノード１６５ｇのメソッドからノード１６５ｃのメソッドが呼び出される際の呼び出しログが採取される。また、ノード１６５ｈ，１６５ｉのメソッドからノード１６５ｄのメソッドが呼び出される際の呼び出しログが採取される。また、ノード１６５ｊのメソッドからノード１６５ｅのメソッドが呼び出される際の呼び出しログが採取される。また、ノード１６５ｎのメソッドからノード１６５ｋのメソッドが呼び出される際の呼び出しログが採取される。また、ノード１６５ｎのメソッドからノード１６５ｍのメソッドが呼び出される際の呼び出しログが採取される。
【０１５６】
ログ採取点決定部１２９は、上記のラベルとメソッドの対応付けに基づいて、未追跡テーブル１４２を生成することができる。
次に、解析装置１００ａの処理手順について説明する。解析装置１００ａによる影響範囲解析は、図１４に示した第２の実施の形態の影響範囲解析のうちステップＳ１３が異なる。解析装置１００ａは、ステップＳ１３に代えて以下のログ採取点決定を実行する。
【０１５７】
図２５は、ログ採取点決定の手順例を示すフローチャートである。
（Ｓ４０）ログ収集部１２３ａは、データベースとコネクションを確立しＳＱＬ文を発行するＪＤＢＣに対して、ＤＢアクセスログを採取するためのログ採取モジュールを付加する。例えば、ログ収集部１２３ａは、バイトコードインジェクションに用いるＤＢアクセスログ採取用のエージェントプログラムを生成する。
【０１５８】
（Ｓ４１）ログ収集部１２３ａは、サーバ装置２００にアプリケーションプログラムを実行させる。実行させるアプリケーションプログラムは、予めコンパイルされたものでもよいし、解析装置１００ａまたはサーバ装置２００がソースコードからコンパイルしたものでもよい。例えば、ログ収集部１２３ａは、アプリケーションプログラムおよびエージェントプログラムをサーバ装置２００に配置し、ロード時にアプリケーションプログラムを書き換えるオプションを付加した起動コマンドをサーバ装置２００に送信する。
【０１５９】
（Ｓ４２）ログ収集部１２３ａは、サーバ装置２００によるアプリケーションプログラムの実行が終了すると、サーバ装置２００からＳＱＬ文とスタックトレースを含むログを読み出す。ログ収集部１２３ａは、読み出したログをログ記憶部１２４に格納する。
【０１６０】
（Ｓ４３）ログ採取点決定部１２９は、ステップＳ４２のＳＱＬ文およびスタックトレースを分析して呼び出しグラフを生成する。呼び出しグラフ生成の詳細は後述する。
（Ｓ４４）ログ採取点決定部１２９は、ステップＳ４３の呼び出しグラフを探索してログ採取点を決定する。呼び出しグラフ探索の詳細は後述する。
【０１６１】
（Ｓ４５）ログ採取点決定部１２９は、ステップＳ４４で決定したログ採取点を未追跡テーブル１４２（テーブル２）に記録する。
図２６は、呼び出しグラフ生成の手順例を示すフローチャートである。
【０１６２】
この呼び出しグラフ生成は上記のステップＳ４３で実行される。
（Ｓ５０）ログ採取点決定部１２９は、ログのレコードを１つ選択する。
（Ｓ５１）ログ採取点決定部１２９は、選択したレコードに含まれるスタックトレースから部分グラフを生成する。部分グラフは、スタックトレースに記載されたメソッドに対応するノードと、それらメソッドの呼び出し順序を示すリンク（エッジ）とを含む。リンクの遷移元は呼び出し元メソッドを表し、リンクの遷移先は呼び出し先メソッドを表す。よって、部分グラフの終点ノードはＪＤＢＣメソッドを示す。ＪＤＢＣメソッドに近付く方向が下流であり、ＪＤＢＣメソッドから遠ざかる方向が上流である。
【０１６３】
（Ｓ５２）ログ採取点決定部１２９は、選択したレコードに含まれるＳＱＬ文から、ＳＱＬ文の種類の識別に適した文字列を種類部分として抽出する。抽出する種類部分は、例えば、コマンド種別とテーブル名とカラム名を含み、具体的なカラム値を含まない。
【０１６４】
（Ｓ５３）ログ採取点決定部１２９は、ステップＳ５２で抽出した種類部分に対応するラベルを定義済みであるか否か判断する。抽出した種類部分がラベルテーブル１４８に記録されている場合は定義済みであり、ラベルテーブル１４８に記録されていない場合は未定義である。ラベルが定義済みである場合はステップＳ５５に処理が進み、ラベルが未定義である場合はステップＳ５４に処理が進む。
【０１６５】
（Ｓ５４）ログ採取点決定部１２９は、ステップＳ５２で抽出した種類部分に対応する新しいラベルを定義してラベルテーブル１４８（テーブル８）に記録する。
（Ｓ５５）ログ採取点決定部１２９は、ステップＳ５１で生成した部分グラフに含まれるノードそれぞれに対して、抽出した種類部分に対応するラベルを付加する。
【０１６６】
（Ｓ５６）ログ採取点決定部１２９は、ラベルを付加した部分グラフを、現在の呼び出しグラフに統合する。なお、呼び出しグラフの初期状態は空である。よって、１つ目の部分グラフを生成したときは、当該部分グラフが呼び出しグラフとして保持される。２つ目以降の部分グラフを生成したときは、当該部分グラフと現在の呼び出しグラフとの間で共通するノードを検出することで、ノードやラベルやリンクが集約される。
【０１６７】
（Ｓ５７）ログ採取点決定部１２９は、ステップＳ５０において、ログに含まれる全てのレコードを選択したか判断する。全てのレコードを選択した場合は呼び出しグラフ生成が終了し、未選択のレコードがある場合はステップＳ５０に処理が進む。
【０１６８】
図２７は、呼び出しグラフ探索の手順例を示すフローチャートである。
この呼び出しグラフ生成は上記のステップＳ４４で実行される。
（Ｓ６０）ログ採取点決定部１２９は、距離ｘを１に設定する。
【０１６９】
（Ｓ６１）ログ採取点決定部１２９は、ＪＤＢＣメソッドを示す終点ノード（ＪＤＢＣノード）からの距離がｘであるノードを１つ選択する。
（Ｓ６２）ログ採取点決定部１２９は、ステップＳ６１で選択したノード（選択ノード）が単一のラベルをもつか判断する。単一のラベルをもつ場合はステップＳ６３に処理が進み、ラベルをもたないか２以上のラベルをもつ場合はステップＳ６５に処理が進む。
【０１７０】
（Ｓ６３）ログ採取点決定部１２９は、選択ノードがもつラベルと選択ノードが示すメソッドとを対応付ける。１つのラベルには高々１つのメソッドが対応付けられる。
（Ｓ６４）ログ採取点決定部１２９は、選択ノードから上流（ＪＤＢＣノードから遠ざかる方向）に向かって他のノードを辿り、当該他のノードがもつラベルのうち選択ノードがもつラベルを削除する。ここで言う他のノードは、ＪＤＢＣノードから選択ノードまでの経路を共有しているノードである。よって、選択ノードより下流（ＪＤＢＣノードに近付く方向）に存在するノードのラベルは削除されない。また、ＪＤＢＣノードから選択ノードまでの経路を共有していない異なる枝上のノードのラベルは削除されない。
【０１７１】
（Ｓ６５）ログ採取点決定部１２９は、ＪＤＢＣノードからの距離がｘであるノードのうち、ステップＳ６１で未選択のノードがあるか判断する。距離がｘである未選択のノードがある場合はステップＳ６１に処理が進み、ない場合はステップＳ６６に処理が進む。
【０１７２】
（Ｓ６６）ログ採取点決定部１２９は、ＪＤＢＣノードからの距離がｘより大きいノードであって、ステップＳ６１で未選択のノードがあるか判断する。未選択のノードがある場合はステップＳ６７に処理が進み、ない場合はステップＳ６８に処理が進む。
【０１７３】
（Ｓ６７）ログ採取点決定部１２９は、距離ｘを１だけ増やす。そして、ステップＳ６１に処理が進み、更新後の距離ｘについてステップＳ６１〜Ｓ６５が実行される。
（Ｓ６８）ログ採取点決定部１２９は、呼び出しグラフに現れるラベルのうちメソッドを対応付けていないラベルがあるか判断する。メソッドを対応付けていないラベルがある場合はステップＳ６９に処理が進み、ない場合は呼び出しグラフ探索が終了する。
【０１７４】
（Ｓ６９）ログ採取点決定部１２９は、呼び出しグラフに現れるラベルのうちメソッドを対応付けていないラベルの数（残りラベル数）をカウントする。ログ採取点決定部１２９は、今回のステップＳ６０〜Ｓ６７の探索によって残りラベル数が減少したか判断する。すなわち、今回のステップＳ６０〜Ｓ６７の探索の間に、少なくとも１つのラベルに対してメソッドが対応付けられたか判断する。残りラベル数が減少した場合、ステップＳ６０に戻ってステップＳ６０〜Ｓ６７の探索を再実行する。残りラベル数が減少していない場合、呼び出しグラフ探索が終了する。なお、ステップＳ６０〜Ｓ６７の探索を繰り返し実行するのは、２以上のラベルをもっていたノードがステップＳ６４のラベル削除によって単一のラベルをもつノードに変化することがあり、ステップＳ６２の条件を満たすノードが増える可能性があるためである。
【０１７５】
このようにして、解析装置１００ａは、決定したログ採取点を示す未追跡テーブル１４２（テーブル２）を生成することができる。未追跡テーブル１４２を生成した後の影響範囲解析の手順は第２の実施の形態と同様である。ただし、解析装置１００ａは、ＳＱＬ文の種類とメソッドとの対応関係を示す情報を参照して、対応候補テーブル１４５（テーブル５）から対応テーブル１４６（テーブル６）を生成する処理（図１５のステップＳ３８）の精度を向上させることもできる。以下、そのような変形例について説明する。
【０１７６】
図２８は、未追跡テーブルの他の例を示す図である。
ログ採取点決定部１２９は、第２の実施の形態の未追跡テーブル１４２に代えて、未追跡テーブル１４２ａを生成することもできる。未追跡テーブル１４２ａは、クラス名、メソッド名、呼び出し元およびラベルの項目を含む。クラス名、メソッド名および呼び出し元の項目は、図７の未追跡テーブル１４２と同様である。未追跡テーブル１４２ａのクラス名とメソッド名は、ログ採取点決定部１２９が決定したログ採取点のクラス名とメソッド名である。未追跡テーブル１４２ａのラベルは、ログ採取点に対応付けられたラベルであり、ラベルテーブル１４８に登録されたＳＱＬ文の種類を識別する。
【０１７７】
次に、図２２〜２４の呼び出しグラフ１６５を用いて、図１５の動的解析のステップＳ３８の精度に影響を与える状況について説明する。
図２９は、対応候補テーブルの他の例を示す図である。
【０１７８】
対応候補テーブル１４５ａは、第２の実施の形態の対応候補テーブル１４５と同様の方法で生成される。図２９の対応候補テーブル１４５ａでは、カラムｒｅｃｏｒｄ＿ｔｉｍｅの読み出しに対して、メソッドｉｎｓｅｒｔとメソッドｆｉｎｄＦｏｒＫｅｙの２つが対応付けられている。これは、ラベルＳ５に属するＳＱＬ文が実行されたときのスタックトレースに、ラベルＳ５に対応付けられたメソッドｆｉｎｄＦｏｒＫｅｙに加えて、ラベルＳ４に対応付けられたメソッドｉｎｓｅｒｔも含まれているためである。
【０１７９】
これは、図２４において、ラベルＳ５の実行経路上にラベルＳ４のログ採取点が存在することからも説明される。このように、第３の実施の形態の呼び出しグラフ探索によっても、ある種類のＳＱＬ文の実行経路上に他の種類のＳＱＬ文に対応するログ採取点が設定される場合がある。その場合には不要な伝搬関係が出力されてしまうことがある。対応候補テーブル１４５ａでは、カラムｒｅｃｏｒｄ＿ｔｉｍｅの読み出しとメソッドｆｉｎｄＦｏｒＫｅｙの対応付けが正しく、カラムｒｅｃｏｒｄ＿ｔｉｍｅの読み出しとメソッドｉｎｓｅｒｔの対応付けは誤りである。
【０１８０】
そこで、解析装置１００ａは、対応候補テーブル１４５ａから対応テーブル１４６を生成する際に、ＳＱＬ文の種類の情報を用いて、対応候補テーブル１４５ａに登録されたレコードのうち不適切なレコードをフィルタリングする。
【０１８１】
図３０は、検査テーブルの例を示す図である。
動的解析部１２５は、ラベルテーブル１４８から検査テーブル１４９を生成する。検査テーブル１４９は、ラベル、種別、テーブル名およびカラム名の項目を含む。ラベルテーブル１４８の１つのレコードから、検査テーブル１４９の１つのレコードが生成される。
【０１８２】
検査テーブル１４９のラベルは、ラベルテーブル１４８のラベルである。検査テーブル１４９の種別は、ＲｅａｄまたはＷｒｉｔｅであり、ラベルテーブル１４８のＳＱＬ文に含まれるコマンド種別から判断される。ＳＥＬＥＣＴ文の種別はＲｅａｄであり、ＩＮＳＥＲＴ文の種別はＷｒｉｔｅである。検査テーブル１４９のテーブル名は、ラベルテーブル１４８のＳＱＬ文に含まれるテーブル名である。検査テーブル１４９のカラム名は、ラベルテーブル１４８のＳＱＬ文に含まれるカラム名である。
【０１８３】
動的解析部１２５は、未追跡テーブル１４２ａと検査テーブル１４９を照合して、クラス名とメソッド名に対応する種別とテーブル名とカラム名を判断する。動的解析部１２５は、この対応関係と整合しない対応候補テーブル１４５ａのレコードを無視する。
【０１８４】
未追跡テーブル１４２ａと検査テーブル１４９からは、例えば、ラベルＳ４について、クラスＴｉｍｅＲｅｃｏｒｄＲｅｇｉｓｔＢｅａｎのメソッドｉｎｓｅｒｔに対して、テーブルｔｍｄ＿ｔｉｍｅ＿ｒｅｃｏｒｄのカラムｒｅｃｏｒｄ＿ｔｉｍｅの書き込みが対応付けられる。また、ラベルＳ５について、クラスＴｍｄＴｉｍｅＲｅｃｏｒｄＤａｏのメソッドｆｉｎｄＦｏｒＫｅｙに対して、テーブルｔｍｄ＿ｔｉｍｅ＿ｒｅｃｏｒｄのカラムｒｅｃｏｒｄ＿ｔｉｍｅの読み出しが対応付けられる。
【０１８５】
対応候補テーブル１４５ａには、種別がＷｒｉｔｅ、クラス名がＴｉｍｅＲｅｃｏｒｄＲｅｇｉｓｔＢｅａｎ、メソッド名がｉｎｓｅｒｔ、テーブル名がｔｍｄ＿ｔｉｍｅ＿ｒｅｃｏｒｄ、カラム名がｒｅｃｏｒｄ＿ｔｉｍｅのレコードが含まれており、このレコードは有効である。また、対応候補テーブル１４５ａには、種別がＲｅａｄ、クラス名がＴｉｍｅＲｅｃｏｒｄＲｅｇｉｓｔＢｅａｎ、メソッド名がｉｎｓｅｒｔ、テーブル名がｔｍｄ＿ｔｉｍｅ＿ｒｅｃｏｒｄ、カラム名がｒｅｃｏｒｄ＿ｔｉｍｅのレコードが含まれており、このレコードは有効である。一方、対応候補テーブル１４５ａには、種別がＲｅａｄ、クラス名がＴｍｄＴｉｍｅＲｅｃｏｒｄＤａｏ、メソッド名がｆｉｎｄＦｏｒＫｅｙ、テーブル名がｔｍｄ＿ｔｉｍｅ＿ｒｅｃｏｒｄ、カラム名がｒｅｃｏｒｄ＿ｔｉｍｅのレコードが含まれており、このレコードは上記と矛盾するため無効である。
【０１８６】
このように、未追跡テーブル１４２ａにラベルを付加することで、対応候補テーブル１４５ａから対応テーブル１４６を生成する際に、対応候補テーブル１４５ａの不適切なレコードをフィルタリングすることができ精度を向上させることができる。
【０１８７】
第３の実施の形態の解析装置１００ａによれば、第２の実施の形態の解析装置１００と同様の効果が得られる。更に、解析装置１００ａによれば、予備的なログ採取を通じて、ＳＱＬ文の種類とメソッド呼び出しとの関係が分析される。そして、引数や返り値などを含む呼び出しログを採取するログ採取点が、ＳＱＬ文の種類毎に適切に設定される。よって、複数種類のＳＱＬ文の実行に使用される共有メソッドをログ採取点として設定することによる誤った伝搬関係の推定を抑制できる。また、ＪＤＢＣメソッドから遠いメソッドをログ採取点として設定することによる対応付け失敗を抑制できる。
【符号の説明】
【０１８８】
１０  解析装置
１１  記憶部
１２  処理部
１３  モジュール
１３ａ，１３ｂ  関数
１４  ソースコード
１４ａ，１４ｂ  変数
１４ｃ，１４ｄ  呼び出し文
１５ａ，１５ｂ  ログ
１６  データベース
１６ａ，１６ｂ  データ項目
【図１】
2018169998.tif 000003
【図２】
2018169998.tif 000004
【図３】
2018169998.tif 000005
【図４】
2018169998.tif 000006
【図５】
2018169998.tif 000007
【図６】
2018169998.tif 000008
【図７】
2018169998.tif 000009
【図８】
2018169998.tif 000010
【図９】
2018169998.tif 000011
【図１０】
2018169998.tif 000012
【図１１】
2018169998.tif 000013
【図１２】
2018169998.tif 000014
【図１３】
2018169998.tif 000015
【図１４】
2018169998.tif 000016
【図１５】
2018169998.tif 000017
【図１６】
2018169998.tif 000018
【図１７】
2018169998.tif 000019
【図１８】
2018169998.tif 000020
【図１９】
2018169998.tif 000021
【図２０】
2018169998.tif 000022
【図２１】
2018169998.tif 000023
【図２２】
2018169998.tif 000024
【図２３】
2018169998.tif 000025
【図２４】
2018169998.tif 000026
【図２５】
2018169998.tif 000027
【図２６】
2018169998.tif 000028
【図２７】
2018169998.tif 000029
【図２８】
2018169998.tif 000030
【図２９】
2018169998.tif 000031
【図３０】
2018169998.tif 000032