(57)【要約】【課題】データベースクエリの抽出を容易にする。【解決手段】解析対象プログラムに含まれる複数のモジュールの間の呼び出し関係を検出する。複数のモジュールのうち第１のモジュールを起動する。第１のモジュールの起動によってデータベースに対して生成されたクエリを取得し、取得したクエリが所定のフォーマットを満たしているか判定する。所定のフォーマットを満たしていない場合、複数のモジュールのうち第１のモジュールの呼び出し元である第２のモジュールを起動する。所定のフォーマットを満たすクエリが取得されるまで、起動するモジュールを呼び出し元に向かって遡ることで、所定のフォーマットを満たすクエリと当該クエリが生成されたときに起動されたモジュールとを示す解析結果を出力する。【選択図】図１２
2020119348.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータに、
解析対象プログラムに含まれる複数のモジュールの間の呼び出し関係を検出し、
前記複数のモジュールのうち第１のモジュールを起動し、
前記第１のモジュールの起動によってデータベースに対して生成されたクエリを取得し、前記取得したクエリが所定のフォーマットを満たしているか判定し、
前記所定のフォーマットを満たしていない場合、前記複数のモジュールのうち前記第１のモジュールの呼び出し元である第２のモジュールを起動し、
前記所定のフォーマットを満たすクエリが取得されるまで、起動するモジュールを呼び出し元に向かって遡ることで、前記所定のフォーマットを満たすクエリと当該クエリが生成されたときに起動されたモジュールとを示す解析結果を出力する、
処理を実行させる解析プログラム。
【請求項２】
前記第１のモジュールは、クエリを受け付けて前記データベースに対してデータ操作を実行するデータベースアクセスプログラムの呼び出し元である、
請求項１記載の解析プログラム。
【請求項３】
前記第１のモジュールの起動によって生成されたクエリは、クエリを受け付けて前記データベースに対してデータ操作を実行するデータベースアクセスプログラムを、受け付けたクエリを記録するダミープログラムに置換することで取得する、
請求項１記載の解析プログラム。
【請求項４】
前記所定のフォーマットを満たすクエリは、前記データベースに対するデータ操作の種類を示すコマンド名と、操作対象のテーブルを示すテーブル名とを含むクエリである、
請求項１記載の解析プログラム。
【請求項５】
コンピュータが、
解析対象プログラムに含まれる複数のモジュールの間の呼び出し関係を検出し、
前記複数のモジュールのうち第１のモジュールを起動し、
前記第１のモジュールの起動によってデータベースに対して生成されたクエリを取得し、前記取得したクエリが所定のフォーマットを満たしているか判定し、
前記所定のフォーマットを満たしていない場合、前記複数のモジュールのうち前記第１のモジュールの呼び出し元である第２のモジュールを起動し、
前記所定のフォーマットを満たすクエリが取得されるまで、起動するモジュールを呼び出し元に向かって遡ることで、前記所定のフォーマットを満たすクエリと当該クエリが生成されたときに起動されたモジュールとを示す解析結果を出力する、
解析方法。
【請求項６】
解析対象プログラムを記憶する記憶部と、
前記解析対象プログラムに含まれる複数のモジュールの間の呼び出し関係を検出し、前記複数のモジュールのうち第１のモジュールを起動し、前記第１のモジュールの起動によってデータベースに対して生成されたクエリを取得し、前記取得したクエリが所定のフォーマットを満たしているか判定し、前記所定のフォーマットを満たしていない場合、前記複数のモジュールのうち前記第１のモジュールの呼び出し元である第２のモジュールを起動し、前記所定のフォーマットを満たすクエリが取得されるまで、起動するモジュールを呼び出し元に向かって遡ることで、前記所定のフォーマットを満たすクエリと当該クエリが生成されたときに起動されたモジュールとを示す解析結果を出力する処理部と、
を有する解析装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は解析プログラム、解析方法および解析装置に関する。
【背景技術】
【０００２】
コンピュータソフトウェアの開発では、既存のソースコードを修正することで、ソフトウェアへの新規機能の追加やソフトウェアの既存機能の変更を行うことがある。このとき、ソースコードの一部分の修正によって、正常に動作していた既存機能に不具合が発生するなど、変更する予定のない既存機能が意図せず変わってしまう可能性がある。そこで、既存のソースコードを修正する際には、開発者が修正の影響範囲を確認しながら修正作業を行えるように、ソフトウェア開発を支援することが好ましい。
【０００３】
あるソフトウェアモジュールが他のソフトウェアモジュールに影響を与える関係の１つとして、データベースを介したデータ依存関係が挙げられる。一方のソフトウェアモジュールが、ＳＱＬ文などのデータベースクエリを発行してデータベースにデータを書き込む。他方のソフトウェアモジュールが、データベースクエリを発行して当該データベースからデータを読み出す。前者のソフトウェアモジュールの動作が変わると、データベースに記憶されるデータが変化し、後者のソフトウェアモジュールの動作が変わることがある。
【０００４】
なお、データベースアクセスの性能に関する情報を収集する方法として、ソフトウェアを実行して実際にデータベースクエリを発行する動的解析方法と、データベースクエリを発行せずにソースコードを分析する静的解析方法とが提案されている。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２０１１−８７８１号公報
【発明の概要】
【発明が解決しようとする課題】
【０００６】
影響範囲分析など既存ソフトウェアの動作分析では、連携する複数のソフトウェアモジュールのうち、何れのソフトウェアモジュールがどの様なデータベースクエリを発行しているかを抽出したいことがある。しかし、ソフトウェアによっては、アクセス要求が発生してからデータベースに実際にアクセスするまでに、様々なソフトウェアモジュールが階層的に呼び出されてデータベースクエリが動的に生成されることがある。その場合、それらソフトウェアモジュールの中から、データベースクエリの内容を実質的に決定しているソフトウェアモジュールを判定することが容易でないという問題がある。
【０００７】
１つの側面では、本発明は、データベースクエリの抽出を容易にする解析プログラム、解析方法および解析装置を提供することを目的とする。
【課題を解決するための手段】
【０００８】
１つの態様では、コンピュータに以下の処理を実行させる解析プログラムが提供される。解析対象プログラムに含まれる複数のモジュールの間の呼び出し関係を検出する。複数のモジュールのうち第１のモジュールを起動する。第１のモジュールの起動によってデータベースに対して生成されたクエリを取得し、取得したクエリが所定のフォーマットを満たしているか判定する。所定のフォーマットを満たしていない場合、複数のモジュールのうち第１のモジュールの呼び出し元である第２のモジュールを起動する。所定のフォーマットを満たすクエリが取得されるまで、起動するモジュールを呼び出し元に向かって遡ることで、所定のフォーマットを満たすクエリと当該クエリが生成されたときに起動されたモジュールとを示す解析結果を出力する。
【０００９】
また、１つの態様では、コンピュータが実行する解析方法が提供される。また、１つの態様では、記憶部と処理部とを有する解析装置が提供される。
【発明の効果】
【００１０】
１つの側面では、データベースクエリの抽出が容易になる。
【図面の簡単な説明】
【００１１】
【図１】第１の実施の形態の解析装置の例を説明する図である。
【図２】第２の実施の形態の解析装置のハードウェア例を示す図である。
【図３】複数の業務ロジックの連携例を示す図である。
【図４】複数のメソッドの階層的呼び出し例を示す図である。
【図５】クエリ決定メソッドの例を示す図である。
【図６】クエリ決定メソッドの調査例を示す図である。
【図７】解析装置の機能例を示すブロック図である。
【図８】ソースコードの例を示す図である。
【図９】呼び出し関係テーブルの例を示す図である。
【図１０】呼び出し関係グラフの例を示す図である。
【図１１】ＳＱＬ文の生成例を示す図である。
【図１２】解析結果画面の表示例を示す図である。
【図１３】呼び出し関係解析の手順例を示すフローチャートである。
【図１４】クエリ抽出の手順例を示すフローチャートである。
【図１５】クエリ決定メソッド探索の手順例を示すフローチャートである。
【発明を実施するための形態】
【００１２】
以下、本実施の形態を図面を参照して説明する。
［第１の実施の形態］
第１の実施の形態を説明する。
【００１３】
図１は、第１の実施の形態の解析装置の例を説明する図である。
第１の実施の形態の解析装置１０は、既存ソフトウェアによるデータベースクエリの発行を解析する。解析装置１０をコンピュータや情報処理装置と言うこともできる。解析装置１０は、クライアント装置でもよいしサーバ装置でもよい。
【００１４】
解析装置１０は、記憶部１１および処理部１２を有する。記憶部１１は、ＲＡＭ（Random Access Memory）などの揮発性の半導体メモリでもよいし、ＨＤＤ（Hard Disk Drive）やフラッシュメモリなどの不揮発性のストレージでもよい。処理部１２は、例えば、ＣＰＵ（Central Processing Unit）、ＧＰＵ（Graphics Processing Unit）、ＤＳＰ（Digital Signal Processor）などのプロセッサである。ただし、処理部１２は、ＡＳＩＣ（Application Specific Integrated Circuit）やＦＰＧＡ（Field Programmable Gate Array）などの特定用途の電子回路を含んでもよい。プロセッサは、ＲＡＭなどのメモリ（記憶部１１でもよい）に記憶されたプログラムを実行する。複数のプロセッサの集合を「マルチプロセッサ」または単に「プロセッサ」と言うことがある。
【００１５】
記憶部１１は、解析対象プログラム１３を記憶する。解析対象プログラム１３は、高水準言語で記述されたソースコードでもよいし、中間言語で記述されたバイトコードや低水準言語で記述されたオブジェクトコードなどコンパイル済みコードでもよい。解析対象プログラム１３は、モジュール１５，１６，１７などの複数のモジュールを含む。モジュールは、他のモジュールから呼び出すことができる単位プログラムである。モジュールは、関数や手続き（プロシージャ）やメソッドなどであってもよい。また、解析対象プログラム１３は、データベース１４を使用するプログラムである。
【００１６】
処理部１２は、解析対象プログラム１３を解析し、解析対象プログラム１３によってデータベース１４に対して生成され得るクエリと、解析対象プログラム１３に含まれるモジュールのうち当該クエリの内容を決定しているモジュールとを判定する。例えば、データベース１４は関係データベースであり、クエリはＳＱＬ文である。解析装置１０による解析は、例えば、解析対象プログラム１３を修正する際の影響範囲分析の一環として行う。この影響範囲分析の結果は、データベース１４を介したモジュール間のデータ依存関係を示す。あるモジュールがクエリを発行してデータベース１４にデータを格納し、他のモジュールがクエリを発行してデータベース１４から当該データを抽出することがある。その場合、前者のモジュールが後者のモジュールに影響を与えている。
【００１７】
まず、処理部１２は、解析対象プログラム１３に含まれる複数のモジュールの間の呼び出し関係を検出する。呼び出し関係は、ソースコードやバイトコードの静的解析によって検出することが可能である。例えば、モジュール１５がモジュール１６から呼び出され、モジュール１６がモジュール１７から呼び出されるという呼び出し関係が検出される。
【００１８】
次に、処理部１２は、解析対象プログラム１３に含まれる複数のモジュールのうち１つのモジュール（第１のモジュール）を選択し、第１のモジュールを起動する。すなわち、処理部１２は、第１のモジュールを起動点に設定し、第１のモジュールから処理が開始するように解析対象プログラム１３を実行する。第１のモジュールから解析対象プログラム１３が実行されるようにするため、例えば、第１のモジュールが受け付ける引数やグローバル変数に、空文字列や「０」やｎｕｌｌなどの所定の値を設定する。
【００１９】
選択する第１のモジュールは、クエリを受け付けてデータベース１４に対してデータ操作を実行するデータベースアクセスプログラムに近い下流のモジュールであることが好ましい。データベースアクセスプログラムは、例えば、プログラミング言語が用意するデータベースアクセスＡＰＩ（Application Programming Interface）や、ＯＲＭ（Object Relational Mapper）などのデータベース操作ライブラリなどである。選択する第１のモジュールは、データベースアクセスプログラムの呼び出し元であってもよい。例えば、処理部１２は、モジュール１５〜１７のうちモジュール１５を選択して起動する。
【００２０】
次に、処理部１２は、第１のモジュールの起動によってデータベース１４に対して生成されたクエリを取得する。クエリの取得は、データベースアクセスプログラムが受け付けるクエリを監視することで行ってもよい。また、クエリの取得は、データベースアクセスプログラムを、受け付けたクエリを記録するダミープログラムに置換することで行ってもよい。処理部１２は、取得したクエリが、ＳＱＬの構文などの所定のフォーマットを満たしているか判定する。例えば、取得したクエリが、データベース１４に対するデータ操作の種類を示すコマンド名と、操作対象のテーブルを示すテーブル名とを少なくとも含んでいる場合、当該クエリが所定のフォーマットを満たすと判定される。コマンド名は、ＳＥＬＥＣＴ、ＩＮＳＥＲＴ、ＵＰＤＡＴＥ、ＤＥＬＥＴＥなどである。
【００２１】
取得したクエリが所定のフォーマットを満たしていない場合、処理部１２は、解析対象プログラム１３に含まれる複数のモジュールのうち、第１のモジュールを呼び出すことがある呼び出し元モジュール（第２のモジュール）を選択し、第２のモジュールを起動する。処理部１２は、第１のモジュールの場合と同様、第２のモジュールの起動によってデータベース１４に対して生成されたクエリを取得し、取得したクエリが所定のフォーマットを満たしているか判定する。このように、処理部１２は、所定のフォーマットを満たすクエリが取得されるまで、起動するモジュールを呼び出し元に向かって遡る。
【００２２】
所定のフォーマットを満たすクエリが取得されると、処理部１２は、呼び出し元のモジュールを選択して起動することを停止してよい。例えば、処理部１２は、モジュール１５から呼び出し関係を遡ってモジュール１６を起動し、クエリ１８を取得する。クエリ１８が所定のフォーマットを満たすクエリである場合、処理部１２は、モジュール１６から呼び出し関係を遡ってモジュール１７を起動しなくてよい。
【００２３】
そして、処理部１２は、所定のフォーマットを満たすクエリと、当該クエリが生成されたときに起動点として設定されたモジュールとを示す解析結果１９を生成して出力する。呼び出し関係を遡っている間に、所定のフォーマットを満たすクエリが初めて生成されたときの起動点は、クエリの内容を実質的に決定しているモジュールと言える。例えば、処理部１２は、クエリ１８とモジュール１６とを対応付けた解析結果１９を生成して出力する。処理部１２は、解析結果１９を表示装置に表示してもよい。
【００２４】
第１の実施の形態の解析装置１０によれば、解析対象プログラム１３に含まれる複数のモジュールの間の呼び出し関係が検出される。それらモジュールの間の１つのモジュールが起動され、データベース１４に対して生成されたクエリが監視される。生成されたクエリが所定のフォーマットを満たしているか判定され、所定のフォーマットを満たすクエリが得られるまで、起動するモジュールが呼び出し元に向かって遡って選択される。これにより、解析対象プログラム１３によって生成され得るクエリと、そのクエリの内容を実質的に決定しているモジュールとを効率的に判定することができる。
【００２５】
また、ソースコードのみを解析する静的解析方法と異なり、複数のモジュールが連携して動的にクエリが生成される場合であってもクエリを抽出することが可能となる。また、様々な引数を与えながら解析対象プログラム１３の全体を試行錯誤的に実行する単純な動的解析方法と異なり、クエリの生成と無関係なモジュールの実行を抑制でき解析時間を短縮できる。また、データベースアクセスプログラムをダミープログラムに置換することで、データベース１４を構築しなくてもクエリを抽出することが可能となる。
【００２６】
［第２の実施の形態］
次に、第２の実施の形態を説明する。
図２は、第２の実施の形態の解析装置のハードウェア例を示す図である。
【００２７】
第２の実施の形態の解析装置１００は、データベースを利用する既存ソフトウェアを解析し、データベースに対して発行されるＳＱＬ文と当該ＳＱＬ文の内容を決定するメソッドとの対応関係を示す解析結果を出力する。解析装置１００をコンピュータや情報処理装置と言うこともできる。解析装置１００は、ユーザが操作するクライアント装置でもよいし、複数のユーザにより共有されるサーバ装置でもよい。
【００２８】
解析装置１００は、ＣＰＵ１０１、ＲＡＭ１０２、ＨＤＤ１０３、画像インタフェース１０４、入力インタフェース１０５、媒体リーダ１０６および通信インタフェース１０７を有する。上記のユニットはバスに接続されている。解析装置１００は、第１の実施の形態の解析装置１０に対応する。ＣＰＵ１０１は、第１の実施の形態の処理部１２に対応する。ＲＡＭ１０２またはＨＤＤ１０３は、第１の実施の形態の記憶部１１に対応する。
【００２９】
ＣＰＵ１０１は、プログラムの命令を実行する演算回路を含むプロセッサである。ＣＰＵ１０１は、ＨＤＤ１０３に記憶されたプログラムやデータの少なくとも一部をＲＡＭ１０２にロードし、プログラムを実行する。なお、ＣＰＵ１０１は複数のプロセッサコアを備えてもよく、解析装置１００は複数のプロセッサを備えてもよく、以下の処理を複数のプロセッサまたはプロセッサコアを用いて並列に実行してもよい。また、複数のプロセッサの集合を「マルチプロセッサ」または単に「プロセッサ」と言うことがある。
【００３０】
ＲＡＭ１０２は、ＣＰＵ１０１が実行するプログラムやＣＰＵ１０１が演算に用いるデータを一時的に記憶する揮発性の半導体メモリである。なお、解析装置１００は、ＲＡＭ以外の種類のメモリを備えてもよく、複数個のメモリを備えてもよい。
【００３１】
ＨＤＤ１０３は、ＯＳ（Operating System）やアプリケーションソフトウェアなどのソフトウェアのプログラム、および、データを記憶する不揮発性の記憶装置である。なお、解析装置１００は、フラッシュメモリやＳＳＤ（Solid State Drive）などの他の種類の記憶装置を備えてもよく、複数の不揮発性の記憶装置を備えてもよい。
【００３２】
画像インタフェース１０４は、ＣＰＵ１０１からの命令に従って、解析装置１００に接続された表示装置１１１に画像を出力する。表示装置１１１として、ＣＲＴ（Cathode Ray Tube）ディスプレイ、液晶ディスプレイ（ＬＣＤ：Liquid Crystal Display）、有機ＥＬ（ＯＥＬ：Organic Electro-Luminescence）ディスプレイ、プロジェクタなど、任意の種類の表示装置を用いることができる。
【００３３】
入力インタフェース１０５は、解析装置１００に接続された入力デバイス１１２から入力信号を取得し、ＣＰＵ１０１に出力する。入力デバイス１１２として、マウス、タッチパネル、タッチパッド、キーボードなど、任意の種類の入力デバイスを用いることができる。また、解析装置１００に複数の種類の入力デバイスが接続されていてもよい。
【００３４】
媒体リーダ１０６は、記録媒体１１３に記録されたプログラムやデータを読み取る読み取り装置である。記録媒体１１３として、例えば、磁気ディスク、光ディスク、光磁気ディスク（ＭＯ：Magneto-Optical disk）、半導体メモリなどを使用できる。磁気ディスクには、フレキシブルディスク（ＦＤ：Flexible Disk）やＨＤＤが含まれる。光ディスクには、ＣＤ（Compact Disc）やＤＶＤ（Digital Versatile Disc）が含まれる。
【００３５】
媒体リーダ１０６は、例えば、記録媒体１１３から読み取ったプログラムやデータを、ＲＡＭ１０２やＨＤＤ１０３などの他の記録媒体にコピーする。読み取られたプログラムは、例えば、ＣＰＵ１０１によって実行される。なお、記録媒体１１３は可搬型記録媒体であってもよく、プログラムやデータの配布に用いられることがある。また、記録媒体１１３やＨＤＤ１０３を、コンピュータ読み取り可能な記録媒体と言うことがある。
【００３６】
通信インタフェース１０７は、ネットワーク１１４を介して他の情報処理装置と通信を行うインタフェースである。通信インタフェース１０７は、スイッチやルータなどの有線通信装置とケーブルで接続される有線通信インタフェースでもよいし、基地局やアクセスポイントと無線リンクで接続される無線通信インタフェースでもよい。
【００３７】
次に、業務ロジックの間の依存関係について説明する。
図３は、複数の業務ロジックの連携例を示す図である。
解析対象のアプリケーションソフトウェアは、複数の業務ロジックを含む。１つの業務ロジックは、１つの業務機能を実現するソフトウェア部品であり、他のメソッドから呼び出し可能なメソッドの集合である。複数の業務ロジックは、グローバル変数やデータベースなどのデータストアを介してデータ依存関係をもつことがある。
【００３８】
ある業務ロジックがグローバル変数に値を書き込み、他の業務ロジックが当該グローバル変数から値を読み出す場合、この２つの業務ロジックはデータ依存関係をもつ。前者の業務ロジックは後者の業務ロジックに影響を与えることがあるため、前者の業務ロジックを修正する場合には後者の業務ロジックの動作を確認することが好ましい。同様に、ある業務ロジックが関係データベースのテーブルにデータを書き込み、他の業務ロジックが当該テーブルからデータを読み出す場合、この２つの業務ロジックはデータ依存関係をもつ。前者の業務ロジックは後者の業務ロジックに影響を与えることがあるため、前者の業務ロジックを修正する場合には後者の業務ロジックの動作を確認することが好ましい。
【００３９】
一例として、データベース３１を使用するアプリケーションソフトウェアを考える。データベース３１は、複数のテーブルを含む関係データベースである。このアプリケーションソフトウェアは、業務ロジック３２，３３，３４，３５を含む。
【００４０】
業務ロジック３２（業務ロジック＃１）と業務ロジック３３（業務ロジック＃２）は、グローバル変数を共有する。よって、業務ロジック３２と業務ロジック３３は、グローバル変数を介して相互に影響を与える。すなわち、業務ロジック３２の影響範囲に業務ロジック３３が含まれ、業務ロジック３３の影響範囲に業務ロジック３２が含まれる。
【００４１】
また、業務ロジック３２は、ＳＱＬ文４１を発行してデータベース３１のテーブルＢにデータを書き込むことがある。ＳＱＬ文４１は、テーブルＢに新規レコードを挿入するＩＮＳＥＲＴ命令を示すクエリである。業務ロジック３４（業務ロジック＃３）は、ＳＱＬ文４２を発行してデータベース３１のテーブルＢからデータを読み出すことがある。ＳＱＬ文４２は、テーブルＢからレコードを検索するＳＥＬＥＣＴ命令を示すクエリである。同様に、業務ロジック３５（業務ロジック＃４）は、ＳＱＬ文を発行してデータベース３１のテーブルＢからデータを読み出すことがある。よって、業務ロジック３２は、データベース３１を介して業務ロジック３４，３５に影響を与える。すなわち、業務ロジック３２の影響範囲に業務ロジック３４，３５が含まれる。
【００４２】
第２の実施の形態の解析装置１００は、影響範囲分析の一環として、業務ロジック３２，３４，３５のようなデータベース３１を利用する業務ロジックから、発行され得るＳＱＬ文と当該ＳＱＬ文の内容を実質的に決定しているメソッドとを検出する。
【００４３】
図４は、複数のメソッドの階層的呼び出し例を示す図である。
データベース３１を利用する業務ロジックは、最終的にＤＢアクセッサ３６にデータベース３１のテーブル操作を依頼する。ＤＢアクセッサ３６は、ＳＱＬ文を受け付け、受け付けたＳＱＬ文に従ってレコードの検索、挿入、更新、削除などのテーブル操作を実行するデータベースアクセスプログラムである。ＤＢアクセッサ３６は、プログラミング言語が用意するＤＢＣ（Database Connectivity）などデータベースアクセスＡＰＩでもよいし、ＯＲＭなどのデータベースアクセスライブラリでもよい。
【００４４】
ＤＢアクセッサ３６を介してデータベース３１にアクセスする業務ロジックは、様々なメソッドを階層的に呼び出す複雑な構造をもつことがある。１つの業務ロジックに含まれるメソッドには、データベースアクセスに関与するメソッドもあるし、データベースアクセスに関与しないメソッドもある。データベースアクセスを要する契機（アクセス要求）が発生すると、業務ロジックに含まれる一部のメソッドが階層的に呼び出され、一連のメソッド呼び出しを通じてＳＱＬ文が組み立てられる。すなわち、２以上のメソッドが連携してＳＱＬ文が組み立てられ、最終的にＤＢアクセッサ３６が呼び出される。ただし、１つの業務ロジックにおいて引数に応じて異なる種類のＳＱＬ文が生成されることがある。例えば、１つの業務ロジックが、ＳＥＬＥＣＴ命令とＩＮＳＥＲＴ命令の２種類のＳＱＬ文を生成することがある。また、生成されるＳＱＬ文の種類毎に、そのＳＱＬ文の内容を実質的に決定している支配的なメソッド（クエリ決定メソッド）が存在する。
【００４５】
一例として、メソッド５１，５２，５３，５４などの複数のメソッドを含む業務ロジック５０を考える。メソッド５１は、業務ロジック５０の外部から呼び出されることがある始点メソッドである。メソッド５１が呼び出されたことが、データベースアクセスの契機となることがある。メソッド５１は、メソッド５２を呼び出すことがある。メソッド５２が実行されると、１以上の他のメソッドを経由してメソッド５３が呼び出されることがある。メソッド５３は、メソッド５４を呼び出すことがある。メソッド５４は、ＤＢアクセッサ３６を呼び出すことがある。よって、業務ロジック５０の始点メソッドであるメソッド５１が呼び出されると、業務ロジック５０内の複数のメソッドが連鎖的に呼び出されてＳＱＬ文が組み立てられ、ＤＢアクセッサ３６にＳＱＬ文が渡されることがある。
【００４６】
第２の実施の形態では、ソースコードの静的解析のみでは抽出することが難しい動的に生成されるＳＱＬ文も抽出できるようにする。また、データベース３１を実際に構築せずデータベース３１の無い実行環境でもＳＱＬ文を抽出できるようにする。また、業務ロジックに含まれるメソッドの中からクエリ決定メソッドを効率的に検出できるようにする。
【００４７】
そこで、第２の実施の形態では、アプリケーションソフトウェアを実行して、ＤＢアクセッサ３６が呼び出される位置におけるＤＢアクセッサ３６に渡されるべきＳＱＬ文を抽出するようにする。また、ＤＢアクセッサ３６を、受け付けたＳＱＬ文を記録するダミーＤＢアクセッサに置換して、データベース３１への実際のアクセスが発生しないようにする。また、アプリケーションソフトウェアを実行する際の実行開始位置を始点メソッドとせず、ＤＢアクセッサ３６に近い下流のメソッドとすることで、データベースアクセスに関与しないメソッドが無駄に実行されることを抑制する。このとき、正しい構文のＳＱＬ文が生成されるまで、ＤＢアクセッサ３６に近い下流のメソッドから始点メソッドに近い上流のメソッドに向かって実行開始位置を変更していく。クエリ決定メソッドより下流のメソッドを実行開始位置に設定すると、ＳＱＬ文の内容が不定になるため正しい構文のＳＱＬ文が生成されない。下流から上流に向かう間に最初に正しい構文のＳＱＬ文が生成されたときの実行開始位置が、クエリ決定メソッドであると推定される。
【００４８】
図５は、クエリ決定メソッドの例を示す図である。
データベース３１を使用する業務ロジック６０を解析することを考える。解析装置１００は、ＤＢアクセッサ３６をダミーＤＢアクセッサ３７に置換して業務ロジック６０を実行する。ダミーＤＢアクセッサ３７は、ＳＱＬ文を受け付け、受け付けたＳＱＬ文に応じたデータベース３１のテーブル操作を実行せず、受け付けたＳＱＬ文を記録するダミープログラムである。例えば、ダミーＤＢアクセッサ３７は、テーブルＢに新規レコードを挿入するＩＮＳＥＲＴ命令を示すＳＱＬ文４１を受け付け、受け付けたＳＱＬ文４１を記録する。このとき、ダミーＤＢアクセッサ３７は、データベース３１に対して、テーブルＢに新規レコードを挿入するテーブル操作を実行しない。
【００４９】
一例として、業務ロジック６０は、メソッド６１，６２，６３，６４，６５，６６，６７，６８，６９などの複数のメソッドを含む。メソッド６１は、業務ロジック６０の外部から呼び出し可能な始点メソッドである。メソッド６１より下流のメソッドが調査対象となる。メソッド６２，６３，６４は、ＤＢアクセッサ３６を直接呼び出すことがあるメソッドである。ＤＢアクセッサ３６がダミーＤＢアクセッサ３７に置換された後は、メソッド６２，６３，６４はダミーＤＢアクセッサ３７を呼び出すことがある。
【００５０】
メソッド６５は、メソッド６２を呼び出すことがある。メソッド６６は、メソッド６３を呼び出すことがある。メソッド６７は、メソッド６４を呼び出すことがある。メソッド６８は、メソッド６６を呼び出すことがある。メソッド６９は、メソッド６７を呼び出すことがある。メソッド間の呼び出し関係は、ソースコードまたはバイトコードの静的解析によって検出できる。メソッド６２，６３，６４は、実行開始位置を上流に向かって移動していくにあたって最初に実行開始位置とする基点メソッドである。メソッド６８，６９は、ＳＱＬ文の内容を実質的に決定するクエリ決定メソッドである。
【００５１】
クエリ決定メソッドの探索では、解析装置１００は、基点メソッドであるメソッド６２を実行開始位置に設定して業務ロジック６０を実行する。メソッド６２を起動した場合にダミーＤＢアクセッサ３７が正しい構文のＳＱＬ文を出力しないため、解析装置１００は、実行開始位置を呼び出し元のメソッド６５に変更して業務ロジック６０を実行する。
【００５２】
同様に、解析装置１００は、基点メソッドであるメソッド６３を実行開始位置に設定して業務ロジック６０を実行する。メソッド６３を起動した場合にダミーＤＢアクセッサ３７が正しい構文のＳＱＬ文を出力しないため、解析装置１００は、実行開始位置を呼び出し元のメソッド６６に変更して業務ロジック６０を実行する。メソッド６６を起動した場合もダミーＤＢアクセッサ３７が正しい構文のＳＱＬ文を出力しないため、解析装置１００は、実行開始位置を呼び出し元のメソッド６８に変更して業務ロジック６０を実行する。メソッド６８を起動した場合にダミーＤＢアクセッサ３７が正しい構文のＳＱＬ文を出力するため、解析装置１００は、ダミーＤＢアクセッサ３７が出力した当該ＳＱＬ文について、メソッド６８をクエリ決定メソッドであると判定する。
【００５３】
また、解析装置１００は、基点メソッドであるメソッド６４を実行開始位置に設定して業務ロジック６０を実行する。メソッド６４を起動した場合にダミーＤＢアクセッサ３７が正しい構文のＳＱＬ文を出力しないため、解析装置１００は、実行開始位置を呼び出し元のメソッド６７に変更して業務ロジック６０を実行する。メソッド６７を起動した場合もダミーＤＢアクセッサ３７が正しい構文のＳＱＬ文を出力しないため、解析装置１００は、実行開始位置を呼び出し元のメソッド６９に変更して業務ロジック６０を実行する。メソッド６９を起動した場合にダミーＤＢアクセッサ３７が正しい構文のＳＱＬ文を出力するため、解析装置１００は、ダミーＤＢアクセッサ３７が出力した当該ＳＱＬ文について、メソッド６９をクエリ決定メソッドであると判定する。
【００５４】
図６は、クエリ決定メソッドの調査例を示す図である。
正しい構文のＳＱＬ文は、テーブル操作の種類を示すコマンド名と、操作対象テーブルを示すテーブル名とを少なくとも含むＳＱＬ文である。コマンド名は、ＳＥＬＥＣＴ、ＩＮＳＥＲＴ、ＵＰＤＡＴＥ、ＤＥＬＥＴＥなどである。カラム名を要するコマンドについては、正しい構文のＳＱＬ文は、コマンド名とテーブル名とカラム名を少なくとも含むＳＱＬ文である。一方、正しい構文のＳＱＬ文は、挿入するレコードのカラム値、更新後のレコードのカラム値、レコード検索条件であるＷＨＥＲＥ句のカラム値など、具体的なカラム値を含まなくてよい。具体的なカラム値は、クエリ決定メソッドに対して適切な引数を与えればＳＱＬ文に設定されると考えられるためである。
【００５５】
例えば、メソッド６３を実行開始位置に設定した場合、ダミーＤＢアクセッサ３７はＳＱＬ文４３を出力する。ＳＱＬ文４３は、空文字列である。よって、ＳＱＬ文４３は正しい構文のＳＱＬ文ではなく、メソッド６３はクエリ決定メソッドではない。メソッド６６を実行開始位置に設定した場合、ダミーＤＢアクセッサ３７はＳＱＬ文４４を出力する。ＳＱＬ文４４は、コマンド名「ＩＮＳＥＲＴ」を含むものの、テーブル名やカラム名を含まない。これは、メソッド６６より上流のメソッドにおいて操作対象テーブルが決定されるためである。よって、ＳＱＬ文４４は正しい構文のＳＱＬ文ではなく、メソッド６６はクエリ決定メソッドではない。メソッド６８を実行開始位置に設定した場合、ダミーＤＢアクセッサ３７はＳＱＬ文４５を出力する。ＳＱＬ文４５は、コマンド名とテーブル名とカラム名を含み、具体的なカラム値を含まない。よって、ＳＱＬ文４５は正しい構文のＳＱＬ文であり、メソッド６８はクエリ決定メソッドである。ただし、具体的なカラム値は、メソッド６８の引数に依存している。
【００５６】
なお、業務ロジックを始点メソッド以外のメソッドから開始するにあたり、解析装置１００は、実行開始位置のメソッドの引数に値を代入する。また、解析装置１００は、実行開始位置のメソッドおよびそれより下流のメソッドにとってのグローバル変数（実行開始位置のメソッドより上流のメソッドのローカル変数を含む）に値を代入する。引数やグローバル変数に代入する値は、原則として空を示す値でよい。例えば、解析装置１００は、数値型の引数やグローバル変数に「０」を代入し、文字列型の引数やグローバル変数に空文字列を代入し、オブジェクト型の引数やグローバル変数にｎｕｌｌを代入する。
【００５７】
ただし、解析装置１００は、ＤＢアクセッサを指定する変数には、ダミーＤＢアクセッサ３７へのポインタを代入する。これにより、ＤＢアクセッサ３６に代えてダミーＤＢアクセッサ３７が呼び出される。また、実行開始位置のメソッド内に条件分岐が存在する場合、解析装置１００は、メソッド内の複数の実行経路（パス）の全てが試行されるように、分岐条件に使用される引数やグローバル変数の値を複数セット用意する。この場合、解析装置１００は、引数やグローバル変数の値を変えながら、同一の実行開始位置のメソッドを繰り返し起動することになる。これは、実行されるパスによって呼び出し先メソッドが変わる可能性があるためである。条件分岐によって生じる複数のパスは、シンボリック実行などの静的解析方法によって抽出することができる。
【００５８】
次に、解析装置１００の機能について説明する。
図７は、解析装置の機能例を示すブロック図である。
解析装置１００は、ソースコード記憶部１２１、ライブラリ記憶部１２２、ソースコード解析部１２３、バイトコード解析部１２４、呼び出し関係記憶部１２５、メソッド探索部１２６、プログラム実行部１２７、解析結果記憶部１２８および解析結果表示部１２９を有する。ソースコード記憶部１２１、ライブラリ記憶部１２２および呼び出し関係記憶部１２５は、例えば、ＲＡＭ１０２またはＨＤＤ１０３の記憶領域を用いて実現される。その他のユニットは、例えば、ＣＰＵ１０１が実行するプログラムを用いて実現される。
【００５９】
ソースコード記憶部１２１は、解析対象のアプリケーションソフトウェアについて、高水準言語で記述されたソースコードを記憶する。また、ソースコード記憶部１２１は、アプリケーションソフトウェアが使用するライブラリのソースコードを入手可能である場合、ライブラリのソースコードを記憶する。ソースコードは、例えば、オブジェクト指向言語で記述されている。また、ソースコード記憶部１２１は、アプリケーションソフトウェアの設定を記述した外部ファイル（ライブラリやＤＢアクセッサの設定を記述した外部ファイルを含む）が存在する場合、外部ファイルを記憶する。ソースコード記憶部１２１に記憶されるソースコードや外部ファイルはユーザにより入力される。
【００６０】
ライブラリ記憶部１２２は、アプリケーションソフトウェアが使用するライブラリやＤＢアクセッサについて、中間言語で記述されたコンパイル済みのバイトコードを記憶する。また、ライブラリ記憶部１２２は、データベースにアクセスせずにＳＱＬ文を記録するダミーＤＢアクセッサについて、中間言語で記述されたコンパイル済みのバイトコードを記憶する。ただし、ライブラリ記憶部１２２は、バイトコードに代えて、低水準言語で記述されたコンパイル済みのオブジェクトコードを記憶してもよい。
【００６１】
ソースコード解析部１２３は、ソースコード記憶部１２１に記憶されたソースコードの静的解析を行い、ソースコードに記述された複数のメソッドの間の呼び出し関係を検出する。ソースコード解析部１２３は、検出された呼び出し関係を呼び出し関係記憶部１２５に記録する。また、ソースコード解析部１２３は、外部ファイルにメソッドが定義されている場合、外部ファイルのメソッドを呼び出し先として検出することがある。なお、ソースコード解析部１２３は、着目する業務ロジックのみ解析してもよい。
【００６２】
バイトコード解析部１２４は、ライブラリ記憶部１２２に記憶されたライブラリのバイトコードの静的解析を行い、ライブラリに含まれる複数のメソッドの間の呼び出し関係を検出する。ただし、ソースコードを入手可能なライブラリについてはバイトコード解析を行わなくてもよい。バイトコード解析部１２４は、検出された呼び出し関係を、ソースコード解析部１２３を介して呼び出し関係記憶部１２５に記録する。なお、バイトコード解析部１２４は、着目する業務ロジックに関連するライブラリのみ解析してもよい。
【００６３】
呼び出し関係記憶部１２５は、ソースコード解析部１２３により検出された呼び出し関係およびバイトコード解析部１２４により検出された呼び出し関係を示す呼び出し関係情報を記憶する。呼び出し関係情報は、メソッド呼び出し毎に、呼び出し元クラス、呼び出し元メソッド、呼び出し先クラスおよび呼び出し先メソッドを含む。
【００６４】
メソッド探索部１２６は、ユーザから始点メソッドの指定を受け付け、指定された始点メソッドより下流のメソッドの中からクエリ決定メソッドを探索する。クエリ決定メソッドの探索では、メソッド探索部１２６は、呼び出し関係記憶部１２５に記憶された呼び出し関係情報を参照して、始点メソッドから到達可能であってＤＢアクセッサを呼び出すことがあるメソッドを基点メソッドとして選択する。メソッド探索部１２６は、基点メソッドから始めて呼び出し関係を上流に向かって遡って、実行開始位置のメソッドを切り替えていく。メソッド探索部１２６は、実行開始位置のメソッドを選択する毎に、プログラム実行部１２７にアプリケーションソフトウェアの実行を依頼し、生成されたＳＱＬ文をプログラム実行部１２７から取得する。メソッド探索部１２６は、正しい構文のＳＱＬ文が得られるまで呼び出し関係を遡って、アプリケーションソフトウェアの実行を繰り返す。
【００６５】
メソッド探索部１２６は、正しい構文のＳＱＬ文が得られたときの実行開始位置のメソッドを、クエリ決定メソッドであると判定する。正しい構文のＳＱＬ文が得られると、メソッド探索部１２６は、生成されたＳＱＬ文と判定されたクエリ決定メソッドとを対応付けた解析結果を、解析結果記憶部１２８に格納する。
【００６６】
プログラム実行部１２７は、メソッド探索部１２６からの依頼に応じて、解析対象のアプリケーションソフトウェアを実行する。アプリケーションソフトウェアの実行では、プログラム実行部１２７は、ソースコード記憶部１２１に記憶されたソースコードおよび外部ファイルを読み出す。また、プログラム実行部１２７は、ライブラリ記憶部１２２に記憶されたライブラリおよびダミーＤＢアクセッサを読み出す。
【００６７】
プログラム実行部１２７は、メソッド探索部１２６から指定された実行開始位置のメソッドを呼び出すメインソースコードを生成し、メインソースコードを含むソースコード群をコンパイルする。このとき、プログラム実行部１２７は、実行開始位置のメソッドの引数と、実行開始位置のメソッドおよびそれより下流のメソッドのグローバル変数とを検出する。プログラム実行部１２７は、検出した引数およびグローバル変数に適切な初期値が代入されるように、メインソースコードを生成する。また、プログラム実行部１２７は、通常のＤＢアクセッサに代えてダミーＤＢアクセッサが呼び出されるように、メインソースコードを生成する。プログラム実行部１２７は、コンパイル済みコードを実行し、ダミーＤＢアクセッサが出力するＳＱＬ文をメソッド探索部１２６に通知する。
【００６８】
解析結果記憶部１２８は、メソッド探索部１２６が生成した解析結果を記憶する。解析結果は、ＳＱＬ文とクエリ決定メソッドのメソッド名との組を１つ以上含む。
解析結果表示部１２９は、解析結果記憶部１２８に記憶された解析結果を表示装置１１１に表示する。なお、解析装置１００は、プリンタなど表示装置１１１以外の出力デバイスに解析結果を出力してもよいし、他の情報処理装置に解析結果を送信してもよい。
【００６９】
図８は、ソースコードの例を示す図である。
ソースコード１３１は、ソースコード記憶部１２１に記憶されるアプリケーションソフトウェアのソースコードである。ソースコード１３１は、オブジェクト指向言語で記述されている。ソースコード１３１には、クラスTimeRecordRegistBeanが記述されている。クラスTimeRecordRegistBeanは、メソッドinsertを含む。メソッドinsertは、クラスTimeRecordDtoInterfaceのオブジェクトを引数dtoとして受け付ける。メソッドinsertを実行開始位置に設定する場合、解析装置１００は、引数dtoにｎｕｌｌを代入することになる。メソッドinsertは、同じクラスのメソッドvalidate、クラスMospParamsのメソッドhasErrorMessage、同じクラスのcheckInsert、クラスTmdTimeRecordDaoのメソッドnextRecordId、クラスTmdTimeRecordDaoのメソッドinsertを呼び出すことがある。
【００７０】
図９は、呼び出し関係テーブルの例を示す図である。
呼び出し関係テーブル１３２は、呼び出し関係記憶部１２５に記憶される。呼び出し関係テーブル１３２には、ソースコード解析部１２３によるソースコード解析で検出された呼び出し関係が登録される。また、呼び出し関係テーブル１３２には、バイトコード解析部１２４によるバイトコード解析で検出された呼び出し関係も登録される。
【００７１】
呼び出し関係テーブル１３２は、呼び出し元クラス、呼び出し元メソッド、呼び出し先クラスおよび呼び出し先メソッドの項目を含む。呼び出し元クラスの項目には、メソッド呼び出しを行い得るメソッドが属するクラスのクラス名が登録される。呼び出し元メソッドの項目には、メソッド呼び出しを行い得るメソッドのメソッド名が登録される。このクラス名とメソッド名の組によって、メソッド呼び出しを行い得るメソッドが識別される。呼び出し先クラスの項目には、呼び出されるメソッドが属するクラスのクラス名が登録される。呼び出し先メソッドの項目には、呼び出されるメソッドのメソッド名が登録される。このクラス名とメソッド名の組によって、呼び出されるメソッドが識別される。
【００７２】
図１０は、呼び出し関係グラフの例を示す図である。
呼び出し関係グラフ７０は、メソッド間の呼び出し関係を示す有向グラフである。呼び出し関係グラフ７０は、メソッドに対応するノードと呼び出し関係に対応する単方向エッジとを含む。あるノードから他のノードに向かうエッジは、前者のノードに対応するメソッドが後者のノードに対応するメソッドを呼び出すことがあることを意味する。
【００７３】
一例として、呼び出し関係グラフ７０は、ノード７１，７２，７３，７４，７５，７６を含む。ノード７１は、クラスTimeRecordRegistBeanのメソッドinsertを示す。ノード７２は、クラスTimeRecordRegistBeanのメソッドvalidateを示す。ノード７３は、クラスTmdTimeRecordDaoのメソッドinsertを示す。ノード７４は、クラスTmdTimeRecordDaoのメソッドprepareStatementを示す。ノード７５は、クラスTmdTimeRecordDaoのメソッドexecuteUpdateを示す。ノード７６は、ＤＢアクセッサを示す。
【００７４】
呼び出し関係グラフ７０は、ノード７１からノード７２へのエッジと、ノード７１からノード７３へのエッジと、ノード７３からノード７４へのエッジと、ノード７３からノード７５へのエッジとを含む。また、呼び出し関係グラフ７０は、ノード７４からノード７６へのエッジと、ノード７５からノード７６へのエッジとを含む。
【００７５】
よって、クラスTimeRecordRegistBeanのメソッドinsertは、クラスTimeRecordRegistBeanのメソッドvalidateを呼び出すことがあり、クラスTmdTimeRecordDaoのメソッドinsertを呼び出すことがある。クラスTmdTimeRecordDaoのメソッドinsertは、クラスTmdTimeRecordDaoのメソッドprepareStatementを呼び出すことがあり、クラスTmdTimeRecordDaoのメソッドexecuteUpdateを呼び出すことがある。クラスTmdTimeRecordDaoのメソッドprepareStatementは、ＤＢアクセッサを呼び出すことがあり、クラスTmdTimeRecordDaoのメソッドexecuteUpdateは、ＤＢアクセッサを呼び出すことがある。
【００７６】
クエリ決定メソッドの探索では、解析装置１００は、ＤＢアクセッサを呼び出すノード７４のメソッドを基点メソッドと判断する。解析装置１００は、ノード７４のメソッドを実行開始位置として選択する。ノード７４のメソッドを選択することで生成されるＳＱＬ文が正しい構文でない場合、解析装置１００は、呼び出し元のノード７３のメソッドを実行開始位置として選択する。ノード７３のメソッドを選択することで生成されるＳＱＬ文が正しい構文である場合、解析装置１００は、ノード７３のメソッドをクエリ決定メソッドと判定し、ノード７４が示す基点メソッドから始まる探索を終了する。
【００７７】
同様に、解析装置１００は、ＤＢアクセッサを呼び出すノード７５のメソッドを基点メソッドと判断する。解析装置１００は、ノード７５のメソッドを実行開始位置として選択する。ノード７５のメソッドを選択することで生成されるＳＱＬ文が正しい構文でない場合、解析装置１００は、呼び出し元のノード７３のメソッドを実行開始位置として選択する。ノード７３のメソッドを選択することで生成されるＳＱＬ文が正しい構文である場合、解析装置１００は、ノード７３のメソッドをクエリ決定メソッドと判定し、ノード７５が示す基点メソッドから始まる探索を終了する。
【００７８】
このように、ノード７３のメソッドがクエリ決定メソッドであることは、ノード７４が示す基点メソッドから呼び出し関係を遡った場合と、ノード７５が示す基点メソッドから呼び出し関係を遡った場合の両方で判定される。一方で、ＳＱＬ文とクエリ決定メソッドの対応情報は、この２つの場合で同一のものが得られる。そこで、解析装置１００は、異なる基点メソッドから得られた対応情報を統合する。ここでは、ノード７４が示す基点メソッドから呼び出し関係を遡った場合の対応情報と、ノード７５が示す基点メソッドから呼び出し関係を遡った場合の対応情報とを、１つの対応情報に統合する。
【００７９】
図１１は、ＳＱＬ文の生成例を示す図である。
ソースコード１３３には、クラスTmdTimeRecordDaoが記述されている。クラスTmdTimeRecordDaoは、メソッドprepareStatementとメソッドinsertを含む。メソッドprepareStatementは前述のノード７４に対応し、メソッドinsertは前述のノード７３に対応する。メソッドinsertはメソッドprepareStatementを呼び出すことがある。メソッドprepareStatementは、文字列を引数sqlとして受け付ける。メソッドinsertは、インタフェースBaseDtoInterfaceの実装クラスのオブジェクトを引数baseDtoとして受け付ける。
【００８０】
メソッドprepareStatementを実行開始位置に設定した場合、ＳＱＬ文４６が生成される。ＳＱＬ文４６は空文字列である。メソッドprepareStatementは、ＳＱＬ文を示す引数sqlを受け付けてＤＢアクセッサに転送しているため、引数sqlに空文字列が代入されるとＳＱＬ文４６も空文字列になってしまう。よって、メソッドprepareStatementは、ＳＱＬ文の内容を決定しておらずクエリ決定メソッドではない。一方、メソッドinsertを実行開始位置に設定した場合、ＳＱＬ文４７が生成される。ＳＱＬ文４７は、コマンド名「ＩＮＳＥＲＴ」とテーブル名「tmd_time_record」と１１個のカラム名とを含む正しい構文のＳＱＬ文である。よって、メソッドinsertは、ＳＱＬ文の内容を実質的に決定するクエリ決定メソッドである。なお、メソッドinsertを呼び出す際に引数baseDtoにｎｕｌｌが代入されるため、ＳＱＬ文４７は１１個のカラムの具体的な値を含まない。
【００８１】
図１２は、解析結果画面の表示例を示す図である。
解析結果表示部１２９は、解析結果画面８０を生成して表示装置１１１に表示する。解析結果画面８０は、入力フィールド８１および解析結果テーブル８２を含む。解析結果テーブル８２は、解析結果記憶部１２８に記憶されている。
【００８２】
入力フィールド８１には、始点メソッドのクラス名およびメソッド名がユーザにより入力される。ユーザから指定される始点メソッドは、解析対象の業務ロジックに含まれるメソッドのうち、その業務ロジックの外部から最初に呼び出されるメソッドである。指定された始点メソッドより下流のメソッド、すなわち、指定された始点メソッドとＤＢアクセッサとの間にあるメソッドの中から、クエリ決定メソッドが探索される。
【００８３】
解析結果テーブル８２は、ＳＱＬ文とメソッド名の項目を含む。ＳＱＬ文の項目には、クエリ決定メソッドの探索の間にダミーＤＢアクセッサから出力された正しい構文のＳＱＬ文が登録される。メソッド名の項目には、検出されたクエリ決定メソッドのメソッド名が登録される。１つの始点メソッドの指定に対して、ＳＱＬ文とメソッド名を対応付けたレコードが１つも得られないこともあるし、１つだけ得られることもあるし、２つ以上得られることもある。レコードが１つも得られないことは、指定された始点メソッドを起動してもデータベースアクセスが発生しないことを意味する。レコードが１つだけ得られたことは、指定された始点メソッドを起動すると１種類のデータベースアクセスが発生することを意味する。レコードが２つ以上得られたことは、指定された始点メソッドを起動すると、引数に応じて異なる種類のデータベースアクセスが発生することを意味する。
【００８４】
次に、解析装置１００の処理手順について説明する。
図１３は、呼び出し関係解析の手順例を示すフローチャートである。
（Ｓ１０）バイトコード解析部１２４は、ライブラリ記憶部１２２に記憶されたライブラリのうち未解析のライブラリを１つ選択する。
【００８５】
（Ｓ１１）バイトコード解析部１２４は、選択したライブラリのバイトコードを解析して、ライブラリに含まれるクラスおよびメソッドを検出し、メソッド間の呼び出し関係を検出する。バイトコード解析部１２４は、検出した呼び出し関係を呼び出し関係テーブル１３２に記録する。呼び出し関係は、呼び出し元クラス、呼び出し元メソッド、呼び出し先クラスおよび呼び出し先メソッドの組で特定される。
【００８６】
（Ｓ１２）バイトコード解析部１２４は、ステップＳ１０で未選択のライブラリがあるか判断する。未選択のライブラリがある場合はステップＳ１０に進み、全てのライブラリを選択済みである場合はステップＳ１３に進む。
【００８７】
（Ｓ１３）ソースコード解析部１２３は、ソースコード記憶部１２１に記憶されたソースコードを解析し、ソースコードに記載されたメソッドを１つ選択する。
（Ｓ１４）ソースコード解析部１２３は、ステップＳ１３で選択したメソッドから呼び出されている呼び出し先メソッドをソースコードから抽出し、呼び出し関係を検出する。ソースコード解析部１２３は、検出した呼び出し関係を、呼び出し関係テーブル１３２に記録する。呼び出し関係は、呼び出し元クラス、呼び出し元メソッド、呼び出し先クラスおよび呼び出し先メソッドの組で特定される。
【００８８】
（Ｓ１５）ソースコード解析部１２３は、ステップＳ１４において呼び出し先メソッドとして動的実装メソッドが抽出されたか判断する。動的実装メソッドは、オブジェクト指向言語のインタフェースに属するメソッドや抽象クラスに属する抽象メソッドなど、メソッド名や引数の型は定義されているものの具体的な処理内容が定義されていないメソッドである。呼び出し先メソッドとして動的実装メソッドが抽出された場合はステップＳ１６に進み、動的実装メソッドが抽出されなかった場合はステップＳ１９に進む。
【００８９】
（Ｓ１６）ソースコード解析部１２３は、抽出された動的実装メソッドに対応する具象メソッドがソースコードに含まれているか判断する。具象メソッドは、オブジェクト指向言語のインタフェースを実装する実装クラスのメソッドや抽象クラスを継承する具象クラスのメソッドなど、動的実装メソッドで未定義になっていた具体的な処理内容を補完したメソッドである。１つの動的実装メソッドに対して２以上の具象メソッドが定義されることがある。具象メソッドがソースコードに含まれる場合はステップＳ１８に進み、具象メソッドがソースコードに含まれない場合はステップＳ１７に進む。
【００９０】
（Ｓ１７）ソースコード解析部１２３は、ソースコードと組み合わせて使用される外部ファイルに、抽出された動的実装メソッドに対応する具象メソッドが定義されているか判断する。外部ファイルに具象メソッドが定義されている場合はステップＳ１８に進み、外部ファイルに具象メソッドが定義されていない場合はステップＳ１９に進む。
【００９１】
（Ｓ１８）ソースコード解析部１２３は、ソースコードまたは外部ファイルから具象メソッドを抽出し、具象メソッドを呼び出す呼び出し関係を呼び出し関係テーブル１３２に記録する。オブジェクト指向言語のインタフェースまたは抽象クラスを示す変数には、何れかの具象クラスのオブジェクトが代入されることになり、動的実装メソッドの呼び出しは実行時には何れかの具象メソッドの呼び出しに置き換えられる。このため、実行時の呼び出し関係を辿ることができるように、ステップＳ１４で検出された呼び出し関係について、呼び出し元メソッドから具象メソッドへの呼び出し関係が追加される。
【００９２】
（Ｓ１９）ソースコード解析部１２３は、ステップＳ１３でソースコードに未調査のメソッドがあるか判断する。未調査のメソッドがある場合はステップＳ１３に進み、全てのメソッドを調査済みである場合は呼び出し関係解析が終了する。
【００９３】
図１４は、クエリ抽出の手順例を示すフローチャートである。
（Ｓ２０）メソッド探索部１２６は、ユーザから始点メソッドの指定を受け付ける。
（Ｓ２１）メソッド探索部１２６は、指定された始点メソッドの呼び出し先メソッドを呼び出し関係テーブル１３２から検索し、未探索リストに追加する。
【００９４】
（Ｓ２２）メソッド探索部１２６は、未探索リストからメソッドを１つ選択する。
（Ｓ２３）メソッド探索部１２６は、ステップＳ２２で選択したメソッドが基点メソッドであるか判断する。例えば、メソッド探索部１２６は、選択したメソッドの呼び出し先クラスを呼び出し関係テーブル１３２から検索する。メソッド探索部１２６は、呼び出し先クラスにＤＢアクセッサが含まれる場合、選択したメソッドが基点メソッドであると判断し、呼び出し先クラスにＤＢアクセッサが含まれない場合、選択したメソッドが基点メソッドでないと判断する。選択したメソッドが基点メソッドである場合はステップＳ２４に進み、基点メソッドでない場合はステップＳ２５に進む。
【００９５】
（Ｓ２４）メソッド探索部１２６は、選択した基点メソッドから呼び出し関係を遡ってクエリ決定メソッドを探索する。クエリ決定メソッド探索の詳細は後述する。
（Ｓ２５）メソッド探索部１２６は、選択したメソッドの呼び出し先メソッドを呼び出し関係テーブル１３２から検索し、未探索リストに追加する。
【００９６】
（Ｓ２６）メソッド探索部１２６は、未探索リストが空であるか判断する。未探索リストが空の場合はステップＳ２７に進み、空でない場合はステップＳ２２に進む。
（Ｓ２７）メソッド探索部１２６は、ステップＳ２４で記録されたＳＱＬ文とメソッド名の対応関係を示すテーブルを解析結果として出力する。すなわち、メソッド探索部１２６は、ＳＱＬ文とメソッド名のテーブルを解析結果記憶部１２８に格納する。解析結果表示部１２９は、ＳＱＬ文とメソッド名のテーブルを表示装置１１１に表示する。
【００９７】
図１５は、クエリ決定メソッド探索の手順例を示すフローチャートである。
クエリ決定メソッド探索は、上記のステップＳ２４で実行される。
（Ｓ３０）メソッド探索部１２６は、基点メソッドを実行開始メソッドに指定する。
【００９８】
（Ｓ３１）プログラム実行部１２７は、ソースコードに基づいて実行開始メソッドのシンボリック実行を行う。すなわち、プログラム実行部１２７は、実行開始メソッドの引数やグローバル変数に抽象的シンボルを割り当て、各変数の値を抽象的シンボルを用いて表現し、ソースコードに従って各変数の値の変化を追跡する。プログラム実行部１２７は、シンボリック実行によって実行開始メソッド内の１以上のパスを抽出し、各パスが選択される変数条件を判定する。分岐条件が引数やグローバル変数に依存する場合、引数やグローバル変数の値によって選択されるパスが変わる。
【００９９】
（Ｓ３２）プログラム実行部１２７は、実行開始メソッドに与える引数や、実行開始メソッドおよびそれより下流のメソッドが参照するグローバル変数の初期値を決定する。原則として、数値型変数の初期値は「０」、文字列型変数の初期値は空文字、オブジェクト型変数の初期値はｎｕｌｌにするなど、データが存在しないことを示す初期値でよい。ただし、ステップＳ３１で複数のパスが抽出された場合、プログラム実行部１２７は、それら複数のパスのうち未試行のパスを１つ選択し、選択したパスを通るように引数やグローバル変数の初期値を決定する。選択したパスを通るための初期値は、ステップＳ３１で判定された変数条件を満たす初期値である。また、使用するＤＢアクセッサのオブジェクトを示すグローバル変数に、ダミーＤＢアクセッサのオブジェクトを代入することで、ＤＢアクセッサをダミーＤＢアクセッサに置換できることがある。
【０１００】
（Ｓ３３）プログラム実行部１２７は、実行開始メソッドを呼び出すメインソースコードを生成する。メインソースコードには、ステップＳ３２で決定した初期値を引数やグローバル変数に代入する処理を記述する。また、メインソースコードには、ＤＢアクセッサをダミーＤＢアクセッサに置換する処理を記述する。
【０１０１】
（Ｓ３４）プログラム実行部１２７は、元のアプリケーションソフトウェアのソースコードおよびステップＳ３３で生成したメインソースコードをコンパイルして実行する。プログラム実行部１２７は、ダミーＤＢアクセッサが出力するＳＱＬ文を取得する。
【０１０２】
（Ｓ３５）メソッド探索部１２６は、ステップＳ３４で正しい構文のＳＱＬ文が生成されたか判断する。正しい構文のＳＱＬ文は、ＳＥＬＥＣＴやＩＮＳＥＲＴなどのコマンド名とテーブル名とを含み、カラムの指定を要するコマンドについては更にカラム名を含むＳＱＬ文である。コマンド名またはテーブル名が欠けたＳＱＬ文は、正しい構文のＳＱＬ文ではない。ただし、具体的なカラム値やＷＨＥＲＥ句は含まなくてもよい。実行開始メソッドの起動により正しい構文のＳＱＬ文が生成された場合はステップＳ３６に進み、正しい構文ＳＱＬ文が生成されなかった場合はステップＳ３７に進む。
【０１０３】
（Ｓ３６）メソッド探索部１２６は、今回の実行開始メソッドがクエリ決定メソッドであると判定する。メソッド探索部１２６は、ダミーＤＢアクセッサが出力したＳＱＬ文と今回の実行開始メソッドのメソッド名とを対応付けて記録する。
【０１０４】
（Ｓ３７）メソッド探索部１２６は、ステップＳ３２の初期値の設定によって、実行開始メソッド内の全てのパスを試行したか判断する。全てのパスを試行した場合はステップＳ３８に進み、未試行のパスが存在する場合はステップＳ３２に進む。
【０１０５】
（Ｓ３８）メソッド探索部１２６は、今回の実行開始メソッドがクエリ決定メソッドであるか、すなわち、ステップＳ３５の判断がＹＥＳであるか判断する。実行開始メソッドがクエリ決定メソッドである場合はステップＳ４０に進み、実行開始メソッドがクエリ決定メソッドでない場合はステップＳ３９に進む。
【０１０６】
（Ｓ３９）メソッド探索部１２６は、実行開始メソッドの呼び出し元メソッドを呼び出し関係テーブル１３２から検索する。呼び出し元メソッドが１つのみ存在する場合もあるし、呼び出し元メソッドが２つ以上存在する場合もある。
【０１０７】
（Ｓ４０）メソッド探索部１２６は、ステップＳ３９で検索された呼び出し元メソッドのうち実行開始メソッドとして未実行の呼び出し元メソッドがあるか判断する。未実行の呼び出し元メソッドがある場合、未実行の呼び出し元メソッドのうちの１つを次の実行開始メソッドに指定してステップＳ３１に進む。未実行の呼び出し元メソッドがない場合、クエリ決定メソッド探索が終了する。
【０１０８】
第２の実施の形態の解析装置１００によれば、ソースコードやバイトコードから静的解析によってメソッド間の呼び出し関係が検出される。ユーザから指定された始点メソッドより下流のメソッドのうちＤＢアクセッサを呼び出しているメソッドが基点メソッドとして選択され、ＤＢアクセッサがダミーＤＢアクセッサに置換された上で、基点メソッドからアプリケーションソフトウェアが実行される。ダミーＤＢアクセッサが出力するＳＱＬ文が正しい構文のＳＱＬ文でない場合、正しい構文のＳＱＬ文が得られるまで、基点メソッドから呼び出し元に向かって呼び出し関係を遡って実行開始点が変更される。初めて正しい構文のＳＱＬ文が得られたときの実行開始点がクエリ決定メソッドと判定され、ＳＱＬ文とクエリ決定メソッドとを対応付けた解析結果が出力される。
【０１０９】
これにより、複数のメソッドが階層的に呼び出されて動的に生成されるＳＱＬ文も抽出することができる。また、始点メソッドを呼び出して業務ロジックの全体を試行錯誤的に実行する場合よりも、ＳＱＬ文の生成と無関係なメソッドの実行を抑制でき解析時間を短縮できる。また、ＤＢアクセッサをダミーＤＢアクセッサに置換することで、データベースを実際に構築しなくてもＳＱＬ文を抽出することが可能となる。また、ＤＢアクセッサに近いメソッドから優先的に実行開始点に指定することで、ＳＱＬ文毎にそのＳＱＬ文の内容を実質的に決定しているクエリ決定メソッドを効率的に探索できる。
【符号の説明】
【０１１０】
１０  解析装置
１１  記憶部
１２  処理部
１３  解析対象プログラム
１４  データベース
１５，１６，１７  モジュール
１８  クエリ
１９  解析結果
【図１】
2020119348.tif 000003
【図２】
2020119348.tif 000004
【図３】
2020119348.tif 000005
【図４】
2020119348.tif 000006
【図５】
2020119348.tif 000007
【図６】
2020119348.tif 000008
【図７】
2020119348.tif 000009
【図８】
2020119348.tif 000010
【図９】
2020119348.tif 000011
【図１０】
2020119348.tif 000012
【図１１】
2020119348.tif 000013
【図１２】
2020119348.tif 000014
【図１３】
2020119348.tif 000015
【図１４】
2020119348.tif 000016
【図１５】
2020119348.tif 000017