(57)【要約】【課題】トレース時に発生するキャストエラーを抑制すること。【解決手段】情報処理装置１０は、クラスファイルの読み込みを受け付ける処理と、クラスファイルのクラスがトレース対象である場合、トレース出力処理をクラスファイルへ挿入するクラス変換を行う処理と、クラス変換が行われたクラスファイルの実行中にトレース出力処理が呼び出された場合、トレース出力処理に対応するトレースクラスファイルを読み込む第１のクラスローダを生成する処理と、第１のクラスローダごとに当該第１のクラスローダがクラスの読み込みを委譲する優先順位としてトレース出力処理に引数として渡されるオブジェクトのクラスを読み込んだ第２のクラスローダを最優先に設定する処理と、第１のクラスローダに対するクラスの読み込み要求が行われた場合、優先順位が高いクラスローダから順にクラスの読み込みを第１のクラスローダに委譲させる処理とを実行する。【選択図】図１
2017174024.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータが、
オブジェクト指向プログラム言語を用いて作成されたクラスファイルの読み込みを受け付ける処理と、
前記クラスファイルのクラスがトレース対象である場合、トレース出力処理を前記クラスファイルへ挿入するクラス変換を行う処理と、
前記クラス変換が行われたクラスファイルの実行中に前記トレース出力処理が呼び出された場合、前記トレース出力処理に対応するトレースクラスファイルを読み込む第１のクラスローダを生成する処理と、
前記第１のクラスローダごとに当該第１のクラスローダがクラスの読み込みを委譲する優先順位として前記トレース出力処理に引数として渡されるオブジェクトのクラスを読み込んだ第２のクラスローダを最優先に設定する処理と、
前記第１のクラスローダに対するクラスの読み込み要求が行われた場合、前記優先順位が高いクラスローダから順に前記クラスの読み込みを前記第１のクラスローダに委譲させる処理と
を実行することを特徴とするトレース方法。
【請求項２】
前記設定する処理は、前記優先順位が高いクラスローダから、前記第２のクラスローダ、前記第１のクラスローダ、システムクラスローダの順に設定することを特徴とする請求項１に記載のトレース方法。
【請求項３】
前記トレース出力処理は、実行結果を出力する処理、または、内部呼出結果を出力する処理であることを特徴とする請求項１に記載のトレース方法。
【請求項４】
コンピュータに、
オブジェクト指向プログラム言語を用いて作成されたクラスファイルの読み込みを受け付ける処理と、
前記クラスファイルのクラスがトレース対象である場合、トレース出力処理を前記クラスファイルへ挿入するクラス変換を行う処理と、
前記クラス変換が行われたクラスファイルの実行中に前記トレース出力処理が呼び出された場合、前記トレース出力処理に対応するトレースクラスファイルを読み込む第１のクラスローダを生成する処理と、
前記第１のクラスローダごとに当該第１のクラスローダがクラスの読み込みを委譲する優先順位として前記トレース出力処理に引数として渡されるオブジェクトのクラスを読み込んだ第２のクラスローダを最優先に設定する処理と、
前記第１のクラスローダに対するクラスの読み込み要求が行われた場合、前記優先順位が高いクラスローダから順に前記クラスの読み込みを前記第１のクラスローダに委譲させる処理と
を実行させることを特徴とするトレースプログラム。
【請求項５】
プロセッサが、
オブジェクト指向プログラム言語を用いて作成されたクラスファイルの読み込みを受け付ける処理と、
前記クラスファイルのクラスがトレース対象である場合、トレース出力処理を前記クラスファイルへ挿入するクラス変換を行う処理と、
前記クラス変換が行われたクラスファイルの実行中に前記トレース出力処理が呼び出された場合、前記トレース出力処理に対応するトレースクラスファイルを読み込む第１のクラスローダを生成する処理と、
前記第１のクラスローダごとに当該第１のクラスローダがクラスの読み込みを委譲する優先順位として前記トレース出力処理に引数として渡されるオブジェクトのクラスを読み込んだ第２のクラスローダを最優先に設定する処理と、
前記第１のクラスローダに対するクラスの読み込み要求が行われた場合、前記優先順位が高いクラスローダから順に前記クラスの読み込みを前記第１のクラスローダに委譲させる処理と
を実行することを特徴とする情報処理装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、トレース方法、トレースプログラム及び情報処理装置に関する。
【背景技術】
【０００２】
Ｊａｖａ（登録商標）やＣ＋＋等は、オブジェクト指向プログラム言語として知られている。オブジェクト指向プログラム言語を用いて作成されるプログラムは、Ｗｅｂアプリケーションの開発などを始めとし、多用な場面で活用される。
【０００３】
例えば、Ｗｅｂアプリケーションの開発は、ＯＳＳ（Open  Source  Software）を組み合わせることにより実現される。この場合、ＯＳＳの開発者と、ＯＳＳの振る舞いを調査する調査担当者とが必ずしも同一であるとは限らず、両者が異なるケースも多い。このため、ＯＳＳのソードコードの変更を最小限とし、ＯＳＳの振舞いを様々な観点から調査するニーズが広がっている。
【０００４】
このようにＯＳＳの振る舞いが調査される場合、クラスローダがクラスファイルをクラスとして解釈する前に、実行トレースの出力処理、例えばメソッドの実行結果や内部呼出結果を記録する処理をクラスローダが読み込むクラスファイルにプラグインするクラス変換が用いられることがある。
【０００５】
また、ＯＳＳが組み合わせられたＷｅｂアプリケーションサーバでは、Ｊａｖａ（登録商標）プログラムの実行環境であるＪＶＭ（Java（登録商標）  Virtual  Machine）が複数のクラスローダを使い分けることで、同名の異なるクラスが同時に利用される場面も増加している。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特表２００６−５２５５７５号公報
【特許文献２】特開２０１３−１９６４５３号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
しかしながら、上記の技術では、トレース時にキャストエラーの発生を抑制できない場合がある。例えば、実行トレース出力処理を含むクラスを読み込んだクラスローダとは、異なるクラスローダで読み込まれたクラスのオブジェクトが実行トレース出力処理に引数として渡された場合にキャストエラーが生じる。
【０００８】
１つの側面では、本発明は、トレース時に発生するキャストエラーを抑制できるトレース方法、トレースプログラム及び情報処理装置を提供することを目的とする。
【課題を解決するための手段】
【０００９】
一態様のトレース方法では、コンピュータが、オブジェクト指向プログラム言語を用いて作成されたクラスファイルの読み込みを受け付ける処理と、前記クラスファイルのクラスがトレース対象である場合、トレース出力処理を前記クラスファイルへ挿入するクラス変換を行う処理と、前記クラス変換が行われたクラスファイルの実行中に前記トレース出力処理が呼び出された場合、前記トレース出力処理に対応するトレースクラスファイルを読み込む第１のクラスローダを生成する処理と、前記第１のクラスローダごとに当該第１のクラスローダがクラスの読み込みを委譲する優先順位として前記トレース出力処理に引数として渡されるオブジェクトのクラスを読み込んだ第２のクラスローダを最優先に設定する処理と、前記第１のクラスローダに対するクラスの読み込み要求が行われた場合、前記優先順位が高いクラスローダから順に前記クラスの読み込みを前記第１のクラスローダに委譲させる処理とを実行する。
【発明の効果】
【００１０】
トレース時に発生するキャストエラーを抑制できる。
【図面の簡単な説明】
【００１１】
【図１】図１は、実施例１における情報処理装置のハードウェア構成例を示す図である。
【図２】図２は、実施例１における情報処理装置の機能構成例を示す図である。
【図３】図３は、クラス変換の一例を示す図である。
【図４】図４は、Ｔｒａｃｅクラスファイルの一例を示す図である。
【図５】図５は、トレーシング処理の一例を示すシーケンス図である。
【図６】図６は、複数のクラスローダが使用される場合の処理の一例を示すシーケンス図である。
【図７】図７は、複数のクラスローダが使用される場合のトレース処理の一例を示すシーケンス図である。
【図８】図８は、クラス及びオブジェクト間の相関の一例を示す図である。
【図９】図９は、Ｔｒａｃｅコードの一例を示す図である。
【図１０】図１０は、Ｔｒａｃｅコードの一例を示す図である。
【図１１】図１１は、トレース用クラスローダの管理方法の一例を示す図である。
【図１２】図１２は、優先順位の設定方法の一例を示す図である。
【図１３】図１３は、クラス及びオブジェクト間の相関の一例を示す図である。
【図１４】図１４は、実施例１に係るトレース処理の手順を示すフローチャート（１）である。
【図１５】図１５は、実施例１に係るトレース処理の手順を示すフローチャート（２）である。
【図１６】図１６は、実施例１に係るトレース処理のサブルーチンを示すフローチャートである。
【発明を実施するための形態】
【００１２】
以下に添付図面を参照して本願に係るトレース方法、トレースプログラム及び情報処理装置について説明する。なお、この実施例は開示の技術を限定するものではない。そして、各実施例は、処理内容を矛盾させない範囲で適宜組み合わせることが可能である。
【実施例１】
【００１３】
図１は、実施例１における情報処理装置のハードウェア構成例を示す図である。図１に示すように、情報処理装置１０は、ドライブ装置１００、補助記憶装置１０２、メモリ装置１０３、ＣＰＵ１０４及びインタフェース装置１０５等を有する。なお、ドライブ装置１００、補助記憶装置１０２、メモリ装置１０３、ＣＰＵ１０４及びインタフェース装置１０５は相互にバスＢにより接続される。
【００１４】
情報処理装置１０での処理を実現するプログラムは、一例として、記録媒体１０１によって提供される。プログラムが記録された記録媒体１０１がドライブ装置１００にセットされると、プログラムが記録媒体１０１からドライブ装置１００を介して補助記憶装置１０２にインストールされる。但し、プログラムのインストールは必ずしも記録媒体１０１を経由して行われずともよく、ネットワークを介して他のコンピュータからダウンロードされることとしてもかまわない。補助記憶装置１０２は、インストールされたプログラムを格納すると共に、ＣＰＵ１０４が実行する処理等に用いられるファイルやデータ等を格納する。
【００１５】
メモリ装置１０３は、プログラムの起動指示があった場合に、補助記憶装置１０２からプログラムを読み出して格納する。ＣＰＵ１０４は、メモリ装置１０３に格納されたプログラムに従って情報処理装置１０に係る機能を実行する。インタフェース装置１０５は、ネットワークに接続するためのインタフェースとして用いられる。
【００１６】
なお、記録媒体１０１の一例としては、ＣＤ−ＲＯＭ、ＤＶＤディスク又はＵＳＢメモリ等の可搬型の記録媒体が挙げられる。また、補助記憶装置１０２の一例としては、ＨＤＤ（Hard  Disk  Drive）又はフラッシュメモリ等が挙げられる。記録媒体１０１及び補助記憶装置１０２のいずれについても、コンピュータ読み取り可能な記録媒体に相当する。
【００１７】
図２は、実施例１における情報処理装置の機能構成例を示す図である。図２に示すように、情報処理装置１０は、クラスファイル記憶部１１、クラス変換設定ファイル記憶部１２及び実行トレース記憶部１３等の記憶部を有する。これらの記憶部は、あくまで一例として、補助記憶装置１０２又は情報処理装置１０とネットワークを介して接続される記憶装置等を用いるファイルシステムにより実現される。この他、記憶部の一部又は全部は、メモリ装置１０３が有するワークエリアの一部を使用することにより実現される。
【００１８】
クラスファイル記憶部１１は、クラスファイルを記憶する記憶部である。
【００１９】
一実施形態として、クラスファイル記憶部１１には、Ｊａｖａ（登録商標）言語で記述されたソースファイルがＪＶＭ（Java（登録商標）  Virtual  Machine）によりコンパイルされたバイトコードを含むクラスファイルが記憶される。クラスファイル記憶部１１には、Ｏ／Ｒマッピングツールなどを用いてクラスファイルが永続化された状態で記憶される。例えば、クラスファイル記憶部１１には、ＭｙＡｐｐクラスファイル１１ａと、Ｕｔｉｌクラスファイル１１ｂと、Ｔｒａｃｅクラスファイル１１ｃとが記憶される。なお、図２には図示されていないが、クラスロード用クラス、すなわちクラスローダのクラスファイルや汎用のライブラリに関するクラスファイルなどがクラスファイル記憶部１１に記憶されることを妨げない。
【００２０】
これらＭｙＡｐｐクラスファイル１１ａ及びＵｔｉｌクラスファイル１１ｂは、一例として、ＪＶＭ等により提供される環境の下で実行される各種のアプリケーションプログラム、例えばＷｅｂアプリケーションとして実装される。このように、クラスファイル記憶部１１には、一例として、Ｗｅｂアプリケーション等の開発者によりプログラミングされたソースファイルがコンパイルされたＭｙＡｐｐクラスファイル１１ａ及びＵｔｉｌクラスファイル１１ｂが格納される。例えば、ＭｙＡｐｐクラスファイル１１ａには、ＭｙＡｐｐクラスの定義と共にＭｙＡｐｐクラスで最初に実行されるｍａｉｎメソッドが含まれる。
【００２１】
また、Ｔｒａｃｅクラスファイル１１ｃは、Ｗｅｂアプリケーション等の実行トレースを出力し、もってＷｅｂアプリケーション等の振舞いの理解、ボトルネックの発見、さらには、コールグラフの生成に役立てることを目的とし、Ｗｅｂアプリケーションの調査担当者によりプログラミングされる。例えば、Ｔｒａｃｅクラスファイル１１ｃに定義された実行トレースの出力処理が観測対象とするＪａｖａ（登録商標）プログラムにプラグイン化されるクラス変換を実行することにより、Ｗｅｂアプリケーション等の実行トレースが実現される。例えば、Ｔｒａｃｅクラスファイル１１ｃには、Ｔｒａｃｅクラスの定義、及び、実行トレースの出力処理が記述されたｗｒｉｔｅメソッドが含まれる。
【００２２】
なお、ここでは、あくまで一例として、Ｊａｖａ（登録商標）クラスファイルが記憶される場合を例示するが、他のオブジェクト指向プログラミング言語で記述されたソースファイルがコンパイルされたクラスファイルであってもかまわない。また、必ずしもクラスファイルが記憶されずともかまわない。例えば、クラスファイルの代わりにソースファイルを記憶部に格納しておき、Ｗｅｂアプリケーションが実行される場面でソースファイルをコンパイルすることもできる。
【００２３】
クラス変換設定ファイル記憶部１２は、クラス変換設定ファイル１２ａを記憶する記憶部である。ここで言う「クラス変換設定ファイル」とは、上記のクラス変換時に参照される設定ファイルを指し、例えば、ＸＭＬ（Extensible  Markup  Language）形式やＣＳＶ（Comma-Separated  Values）形式などにより記述することができる。このクラス変換設定ファイル１２ａは、Ｗｅｂアプリケーションの調査担当者等からｊａｖａａｇｅｎｔ等のインタフェースを介して設定内容を受け付けることができる。かかる設定内容には、一例として、トレース対象とするクラスやメソッドの他、トレース時にロギングする情報の内容、さらには、Ｔｒａｃｅクラスの中で当該トレースに用いるメソッドの指定などを含めることができる。
【００２４】
実行トレース記憶部１３は、実行トレースの結果を記憶する記憶部である。例えば、実行トレース記憶部１３には、Ｔｒａｃｅクラスのメソッドにより出力される情報が時系列に蓄積されたトレースファイル１３ａが記憶される。
【００２５】
また、図２に示すように、情報処理装置１０は、アプリ実行部１４、クラス記憶部１５、クラス変換部１６、トレース用クラスローダ管理部１７及びトレース用クラスローダ１８等を有する。これらの処理部は、情報処理装置１０にインストールされた制御プログラムがＣＰＵ１０４に実行させる処理により実現される。なお、上記のアプリ実行部１４の「アプリ」は、アプリケーションプログラムの略称である。
【００２６】
アプリ実行部１４は、Ｊａｖａ（登録商標）プログラムを実行する処理部である。
【００２７】
一実施形態として、アプリ実行部１４は、上記のＪＶＭ等を実行することにより実装される。かかるＪＶＭによって、Ｊａｖａ（登録商標）の実行環境が提供される結果、Ｊａｖａ（登録商標）プログラムの実行が可能になる。このようにＪＶＭが開始されると、ブートストラップクラスローダ、拡張クラスローダ、ＳｙｓｔｅｍＣｌａｓｓＬｏａｄｅｒなどの各種のクラスローダがロードされる。この他、ＪＶＭでは、クラスローダがクラスファイルを読み込む直前にクラスファイルを変換することができる。
【００２８】
クラス記憶部１５は、クラスを記憶する記憶部である。
【００２９】
一実施形態として、クラス記憶部１５には、クラスファイル記憶部１１に記憶されたクラスファイルがメモリ装置１０３にロードされる度に、当該ロードが行われたクラスに関するクラス名や識別子などの識別情報が格納される。さらに、クラス記憶部１５には、クラスからオブジェクトが生成される度に、当該クラスから生成されたオブジェクトに関するオブジェクト名や識別子などの識別情報が格納される。これによって、クラス記憶部１５では、情報処理装置１０で動作中のクラスやオブジェクトの識別情報が管理されることになる。このように情報処理装置１０で動作するクラスの一例として、クラスロード用クラス、アプリ実行用クラス及びトレース出力用クラスなどが含まれる。
【００３０】
クラス変換部１６は、クラスローダが読み込むクラスファイルを変換する処理部である。
【００３１】
一実施形態として、クラス変換部１６は、「java（登録商標）.lang.instrument.ClassFileTransformer」の実装クラス等によりＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒとして実装される。このクラス変換部１６は、クラス変換設定記憶部１６ａを有する。このクラス変換設定記憶部１６ａには、クラス変換設定ファイル記憶部１２に記憶されたクラス変換設定ファイル１２ａが複製されることにより得られたクラス変換設定が格納される。
【００３２】
［トレース処理のプラグイン化］
ここで、トレース処理のプラグイン化について説明する。図３は、クラス変換の一例を示す図である。図３では、入力デバイスまたはネットワークを介して、ＭｙＡｐｐクラスを初めに実行するクラスとする指定、並びに、クラス変換設定ファイル１２ａをクラス変換に用いる設定とする指定が受け付けられる場合を想定する。図３では、変換前のトレース対象クラスとしてＭｙＡｐｐクラスファイルに符号１１ａ１が付与されると共にクラス変換時に参照されるクラス変換設定ファイルに符号１２ａが付与され、変換後のトレース対象クラスとしてＭｙＡｐｐクラスファイルに符号１１ａ２が付与されている。なお、図３には、説明の便宜上、各クラスファイルのソースコードが示されているが、実際にはバイナリファイルであることは言うまでもない。また、ソースコード中のコメント文は斜体で示されている。
【００３３】
図３に示すように、変換前のＭｙＡｐｐクラスファイル１１ａ１がＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒへ入力されると、ＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒは、クラス変換設定ファイル１２ａを参照する。
【００３４】
このクラス変換設定ファイル１２ａには、トレース対象とするＭｙＡｐｐクラス内のトレース対象とするｍａｉｎメソッドについて、次のような設定の解釈がなされる。例えば、トレースする情報が「実行開始」である場合、対象メソッドの定義ブロックの先頭で、トレースに使うメソッドを、対象メソッドの宣言クラス、名前を引数として呼び出す。また、トレースする情報が「内部呼出結果」である場合、対象メソッドの定義ブロック中に存在するメソッド呼出式について、その戻り値を引数として、トレースに使うメソッドを呼び出す。
【００３５】
このようなクラス変換設定ファイル１２ａを参照して、ＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒは、Ｔｒａｃｅクラスファイル１１ｃに定義された実行トレースの出力処理を変換前のＭｙＡｐｐクラスファイル１１ａ１へプラグイン化することにより、ＭｙＡｐｐクラスファイル１１ａ１をＭｙＡｐｐクラスファイル１１ａ２へ変換する。
【００３６】
図４は、Ｔｒａｃｅクラスファイル１１ｃの一例を示す図である。図４においても、説明の便宜上、Ｔｒａｃｅクラスファイル１１ｃのソースコードが示されると共にソースコード中のコメント文は斜体で示されているが、実際にはバイナリファイルであることは言うまでもない。図４に示すＴｒａｃｅクラスファイル１１ｃには、Ｔｒａｃｅクラスのｗｒｉｔｅメソッドが呼び出された時に、外部ファイル、すなわちトレースファイル１３ａに実行トレースが格納される仕組みが記述されている。
【００３７】
クラスファイルの変換後、ＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒは、変換後のＭｙＡｐｐクラスファイル１１ａ２をクラスローダへ出力する。
【００３８】
図５は、トレーシング処理の一例を示すシーケンス図である。図５に示すシーケンス図には、処理の実行主体として、ユーザと、ＪＶＭと、Ｊａｖａ（登録商標）の実行環境で動作するＣｌａｓｓＬｏａｄｅｒ１５ｂ及びＣｌａｓｓＴｒａｎｓｆｏｒｍａｅｒと、ファイルシステムとが示されている。なお、ユーザは、処理の実行主体が人であることを意味する訳ではなく、ＣＬＩ（Common  Language  Infrastructure）等を介してユーザである開発者や調査担当者等が入力するユーザ入力を意味する。かかるユーザ入力は、入力デバイスを介するものであってもよいし、ネットワークを介するものであってもかまわない。
【００３９】
図５に示すように、入力デバイスまたはネット−ワークを介して、ＭｙＡｐｐクラスを初めに実行するクラスとして指定するユーザ入力、並びに、Ｔｒａｃｅクラスがファイルシステムにある旨のユーザ入力がＪＶＭへ行われる（ステップＳ１０１）。
【００４０】
すると、ＪＶＭは、ＭｙＡｐｐクラスファイル１１ａの読み込みをＣｌａｓｓＬｏａｄｅｒ１５ｂへ指示する（ステップＳ１０２）。続いて、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、ＭｙＡｐｐクラスファイル１１ａをファイルシステムへリクエストする（ステップＳ１０３）。このとき、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、Ｔｒａｃｅクラスファイル１１ｃの位置をＪＶＭの実行引数で通知する。
【００４１】
その後、ファイルシステムは、クラスファイル記憶部１１に記憶されたＭｙＡｐｐクラスファイル１１ａ１をＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒへ出力する（ステップＳ１０４）。そして、ＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒは、クラス変換設定ファイル１２ａにしたがってＴｒａｃｅクラスファイル１１ｃに定義された実行トレースの出力処理をＭｙＡｐｐクラスファイル１１ａ１へプラグイン化することにより、ＭｙＡｐｐクラスファイル１１ａ１からＭｙＡｐｐクラスファイル１１ａ２へ変換する（ステップＳ１０５）。
【００４２】
かかるクラス変換によって、ＭｙＡｐｐクラスファイル１１ａ１に規定されていたｍａｉｎメソッドの定義、すなわちＵｔｉｌクラスの利用に加えて、Ｔｒａｃｅクラスで実行開始を記録する処理と、Ｔｒａｃｅクラスで実行結果を記録する処理との２つのトレース処理がプラグインされたＭｙＡｐｐクラスファイル１１ａ２が得られる。続いて、ＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒは、ステップＳ１０５で変換されたＭｙＡｐｐクラスファイル１１ａ２をＣｌａｓｓＬｏａｄｅｒ１５ｂへ出力する（ステップＳ１０６）。
【００４３】
かかるＭｙＡｐｐクラスファイル１１ａ２のｍａｉｎメソッドの定義確認を行ったＣｌａｓｓＬｏａｄｅｒ１５ｂは、次のような処理を実行する。すなわち、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、Ｕｔｉｌクラスファイル１１ｂをファイルシステムへリクエストする（ステップＳ１０７）。この結果、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、ファイルシステムからＵｔｉｌクラスファイル１１ｂを取得する（ステップＳ１０８）。また、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、Ｔｒａｃｅクラスファイル１１ｃをファイルシステムへリクエストする（ステップＳ１０９）。この結果、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、ファイルシステムからＴｒａｃｅクラスファイル１１ｃを取得する（ステップＳ１１０）。
【００４４】
その後、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、ＭｙＡｐｐクラスファイル１１ａ２、Ｕｔｉｌクラスファイル１１ｂ及びＴｒａｃｅクラスファイル１１ｃをＪＶＭへ出力する（ステップＳ１１１）。
【００４５】
そして、ＪＶＭは、ＣｌａｓｓＬｏａｄｅｒ１５ｂによりロードされたＭｙＡｐｐクラス１５ｄのｍａｉｎメソッドを実行する（ステップＳ１１２）。かかるｍａｉｎメソッドには、ｍａｉｎメソッドの実行開始を記録するｗｒｉｔｅメソッドと、Ｕｔｉｌクラス１５ｂ１のｃａｌｃメソッドの実行結果を記録するｗｒｉｔｅメソッドとが挿入されている。その後、ＪＶＭは、実行トレースの結果、すなわちｍａｉｎメソッドの実行開始及びｃａｌｃメソッドの実行結果をファイルシステム内のトレースファイル１３ａへ出力する（ステップＳ１１３）。
【００４６】
このように、プラグイン化した実行トレース出力処理、例えば図４に示す例ではＴｒａｃｅクラスのｗｒｉｔｅメソッドを呼び出すように観測対象クラスを変換すると、手軽にトレーシングを実現できる。
【００４７】
［複数のクラスロードの利用］
Ｗｅｂアプリケーション等の開発において、ＯＳＳ（Open  Source  Software）を組み合わせることにより、Ｗｅｂアプリケーションサーバを実現する場面が増加している。このようにＯＳＳが組み合わせられたＷｅｂアプリケーションサーバでは、ＪＶＭが複数のクラスローダを使い分けることで、同名の異なるクラスが同時に利用される。
【００４８】
図６は、複数のクラスローダが使用される場合の処理の一例を示すシーケンス図である。図６には、説明の便宜上、実行トレースの出力処理をプラグインする処理は組み込まれておらず、処理の実行主体にＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒは含まれない。その一方で、図６には、ＣｌａｓｓＬｏａｄｅｒ１５ｂに加え、ＯｔｈｅｒＬｏａｄｅｒ１５ｃの２つのクラスローダが処理の実行主体に含まれる。
【００４９】
図６に示すように、入力デバイスまたはネット−ワークを介して、ＭｙＡｐｐクラスを初めに実行するクラスとして指定するユーザ入力がＪＶＭへ行われる（ステップＳ２０１）。
【００５０】
すると、ＪＶＭは、ＭｙＡｐｐクラスファイル１１ａの読み込みをＣｌａｓｓＬｏａｄｅｒ１５ｂへ指示する（ステップＳ２０２）。続いて、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、ＭｙＡｐｐクラスファイル１１ａ３をファイルシステムへリクエストする（ステップＳ２０３）。この結果、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、ファイルシステムからＭｙＡｐｐクラスファイル１１ａ３を取得する（ステップＳ２０４）。かかるＭｙＡｐｐクラスファイル１１ａ３には、図５に示したＭｙＡｐｐクラスファイル１１ａ１に規定されていたｍａｉｎメソッドの定義、すなわちＵｔｉｌクラスの利用に加えて、別のＵｔｉｌクラスを強制的に利用する定義が併せて含まれる。
【００５１】
かかるＭｙＡｐｐクラスファイル１１ａ３のｍａｉｎメソッドの定義確認を行ったＣｌａｓｓＬｏａｄｅｒ１５ｂは、次のような処理を実行する。すなわち、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、Ｕｔｉｌクラスファイル１１ｂをファイルシステムへリクエストする（ステップＳ２０５）。この結果、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、ファイルシステムからＵｔｉｌクラスファイル１１ｂを取得する（ステップＳ２０６）。
【００５２】
その後、ＪＶＭは、ＣｌａｓｓＬｏａｄｅｒ１５ｂによりロードされたＭｙＡｐｐクラスファイル１１ａ３及びＵｔｉｌクラスファイル１１ｂを取得する（ステップＳ２０７）。続いて、ＪＶＭは、ＣｌａｓｓＬｏａｄｅｒ１５ｂによりロードされたＭｙＡｐｐクラス１５ｄのｍａｉｎメソッドを実行する（ステップＳ２０８）。
【００５３】
このようにステップＳ２０８で実行されるｍａｉｎメソッドには、Ｕｔｉｌクラス１５ｂ１のｃａｌｃメソッドの呼び出しと、別のｃａｌｃメソッドの呼び出しとが定義されている。すなわち、通常は、実行中のメソッドを含むクラスを読み込んだクラスローダと同一のクラスローダが、依存するクラス（Ｕｔｉｌクラス）の読み込みにも使用されるが、明示的に指定すれば、任意のクラスローダで任意のクラスを読み込むこともできる。このことから、ＪＶＭは、ｍａｉｎメソッドの定義にしたがってＣｌａｓｓＬｏａｄｅｒ１５ｂとは別のＯｔｈｅｒＬｏａｄｅｒ１５ｃにＵｔｉｌクラスファイル１１ｂを読み出すように指示する（ステップＳ２０９）。
【００５４】
これを受けて、ＯｔｈｅｒＬｏａｄｅｒ１５ｃは、Ｕｔｉｌクラスファイル１１ｂをファイルシステムへリクエストする（ステップＳ２１０）。この結果、ＯｔｈｅｒＬｏａｄｅｒ１５ｃは、ファイルシステムからＵｔｉｌクラスファイル１１ｂを取得する（ステップＳ２１１）。
【００５５】
これら一連の処理によって、ＪＶＭでは、同名の異なるクラス、すなわち同一のクラス名を持ち、読み込み元のクラスファイルは同一であるが、メモリ上のデータとしては異なるクラスを同時に利用することができる。
【００５６】
［複数のクラスローダが引き起こすエラーの一例］
複数のクラスローダが使用される場合、同名の異なるクラスをトレースすると、エラー発生により異常停止を引き起こすことがある。図７は、複数のクラスローダが使用される場合のトレース処理の一例を示すシーケンス図である。図７では、図６に比べて、処理の実行主体としてＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒをさらに含み、トレース処理の実行時にキャストエラーが発生する例が示されている。
【００５７】
図７に示すように、入力デバイスまたはネット−ワークを介して、ＭｙＡｐｐクラスを初めに実行するクラスとして指定するユーザ入力がＪＶＭへ行われる（ステップＳ３０１）。
【００５８】
すると、ＪＶＭは、ＭｙＡｐｐクラスファイル１１ａの読み込みをＣｌａｓｓＬｏａｄｅｒ１５ｂへ指示する（ステップＳ３０２）。続いて、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、ＭｙＡｐｐクラスファイル１１ａをファイルシステムへリクエストする（ステップＳ３０３）。
【００５９】
その後、ファイルシステムは、クラスファイル記憶部１１に記憶されたＭｙＡｐｐクラスファイル１１ａ３をＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒへ出力する（ステップＳ３０４）。そして、ＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒは、クラス変換設定ファイル１２ａにしたがってＴｒａｃｅクラスファイル１１ｃに定義された実行トレースの出力処理をＭｙＡｐｐクラスファイル１１ａ３へプラグイン化することにより、ＭｙＡｐｐクラスファイル１１ａ３からＭｙＡｐｐクラスファイル１１ａ４へ変換する（ステップＳ３０５）。
【００６０】
かかるクラス変換によって、ＭｙＡｐｐクラスファイル１１ａ３に規定されていたｍａｉｎメソッドの定義、すなわちＵｔｉｌクラスの利用及び別のＵｔｉｌクラスの強制利用に加えて、Ｔｒａｃｅクラスでｍａｉｎメソッドの実行開始を記録する処理と、ＴｒａｃｅクラスでＵｔｉｌクラスのｃａｌｃメソッドの実行結果を記録する処理と、Ｔｒａｃｅクラスで別のＵｔｉｌクラスのｃａｌｃメソッドの実行結果を記録する処理との３つのトレース処理がプラグインされたＭｙＡｐｐクラスファイル１１ａ４が得られる。
【００６１】
続いて、ＣｌａｓｓＴｒａｎｓｆｏｒｍｅｒは、ステップＳ３０５で変換されたＭｙＡｐｐクラスファイル１１ａ４をＣｌａｓｓＬｏａｄｅｒ１５ｂへ出力する（ステップＳ３０６）。
【００６２】
かかるＭｙＡｐｐクラスファイル１１ａ４のｍａｉｎメソッドの定義確認を行ったＣｌａｓｓＬｏａｄｅｒ１５ｂは、次のような処理を実行する。すなわち、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、Ｕｔｉｌクラスファイル１１ｂ及びＴｒａｃｅクラスファイル１１ｃをファイルシステムへリクエストする（ステップＳ３０７）。この結果、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、ファイルシステムからＵｔｉｌクラスファイル１１ｂ及びＴｒａｃｅクラスファイル１１ｃを取得する（ステップＳ３０８）。
【００６３】
その後、ＣｌａｓｓＬｏａｄｅｒ１５ｂは、ＭｙＡｐｐクラスファイル１１ａ４、Ｕｔｉｌクラスファイル１１ｂ及びＴｒａｃｅクラスファイル１１ｃをＪＶＭへ出力する（ステップＳ３０９）。
【００６４】
そして、ＪＶＭは、ＣｌａｓｓＬｏａｄｅｒ１５ｂによりロードされたＭｙＡｐｐクラス１５ｄのｍａｉｎメソッドを実行する（ステップＳ３１０）。ここで、ｍａｉｎメソッドには、ｍａｉｎメソッドの実行開始を記録する処理と、Ｕｔｉｌクラス１５ｂ１のｃａｌｃメソッドの実行結果を記録する処理と、別のＵｔｉｌクラス１５ｃ１のｃａｌｃメソッドの実行結果を記録する処理との３つのトレース処理が挿入されている。
【００６５】
これらのうち、ｍａｉｎメソッドの実行開始を記録する処理と、Ｕｔｉｌクラス１５ｂ１のｃａｌｃメソッドの実行結果を記録する処理とは成功する。なぜなら、Ｕｔｉｌクラス１５ｂ１がインスタンス化されたＵｔｉｌオブジェクト１５ｂ２を引数として受け取るＴｒａｃｅクラス１５ｅのメソッドは同一のＣｌａｓｓＬｏａｄｅｒ１５ｂにより読み込まれたものであるからである。すなわち、ＪＶＭは、実行トレースの結果、すなわちｍａｉｎメソッドの実行開始及びｃａｌｃメソッドの実行結果をファイルシステム内のトレースファイル１３ａへ出力する（ステップＳ３１０Ａ）。
【００６６】
一方、別のＵｔｉｌクラス１５ｃ１のｃａｌｃメソッドの実行結果を記録する処理は失敗する。すなわち、ＪＶＭは、ｍａｉｎメソッドの定義にしたがってＣｌａｓｓＬｏａｄｅｒ１５ｂとは別のＯｔｈｅｒＬｏａｄｅｒ１５ｃにＵｔｉｌクラスファイル１１ｂを読み出すように指示する（ステップＳ３１０Ｂ）。これを受けて、ＯｔｈｅｒＬｏａｄｅｒ１５ｃは、Ｕｔｉｌクラスファイル１１ｂをファイルシステムへリクエストする（ステップＳ３１０Ｃ）。この結果、ＯｔｈｅｒＬｏａｄｅｒ１５ｃは、ファイルシステムからＵｔｉｌクラスファイル１１ｂを取得する（ステップＳ３１０Ｄ）。
【００６７】
ここで、ＯｔｈｅｒＬｏａｄｅｒ１５ｃにより読み込まれた別のＵｔｉｌクラス１５ｃ１がインスタンス化されたＵｔｉｌオブジェクト１５ｃ２を引数として、Ｔｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドが呼び出される。このとき、Ｔｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドは、Ｔｒａｃｅクラス１５ｅが読み込まれたＣｌａｓｓＬｏａｄｅｒ１５ｂを確認して、ｃａｌｃメソッドの呼び出し方法を解析しようと試みる。しかしながら、Ｔｒａｃｅクラス１５ｅが読み込まれたＣｌａｓｓＬｏａｄｅｒ１５ｂは、別のＵｔｉｌクラス１５ｃ１が読み込まれたＯｔｈｅｒＬｏａｄｅｒ１５ｃとは異なる。それ故、図８を用いて後述する通り、キャストエラーが発生する。この結果、ＪＶＭは、ＯｔｈｅｒＬｏａｄｅｒ１５ｃにより読み込まれた別のＵｔｉｌクラス１５ｃ１のｃａｌｃメソッドの実行結果をファイルシステム内のトレースファイル１３ａへ出力するステップＳ３１０Ｅの処理を実行することができない。
【００６８】
図８は、クラス及びオブジェクト間の相関の一例を示す図である。図８には、ＣｌａｓｓＬｏａｄｅｒ１５ｂにより読み込まれたクラス及びそのクラスがインスタンス化されたオブジェクトと、ＯｔｈｅｒＬｏａｄｅｒ１５ｃにより読み込まれたクラス及びそのクラスがインスタンス化されたオブジェクトとが示されている。
【００６９】
図８に示すように、ＯｔｈｅｒＬｏａｄｅｒ１５ｃにより読み込まれたＵｔｉｌクラス１５ｃ１がインスタンス化されたＵｔｉｌオブジェクト１５ｃ２を引数として、Ｔｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドが呼び出される。このＴｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドは、Ｕｔｉｌオブジェクト１５ｃ２を受け取ってｇｅｔメソッドを呼び出し、その戻り値を実行トレースとして出力しようとする。
【００７０】
ここで、ｇｅｔメソッドを呼び出すには、オブジェクトをＵｔｉｌクラス１５ｃ１に型変換することができればキャストが成功するが、Ｔｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドにはそれができない。なぜなら、Ｔｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドは、当該Ｔｒａｃｅクラス１５ｅを読み込んだＣｌａｓｓＬｏａｄｅｒ１５ｂにより読み込まれたＵｔｉｌクラス１５ｂ１に型変換しようとするからである。このように、ＣｌａｓｓＬｏａｄｅｒ１５ｂにより読み込まれたＵｔｉｌクラス１５ｂ１と、ＯｔｈｅｒＬｏａｄｅｒ１５ｃにより読み込まれたＵｔｉｌクラス１５ｃ１とは、たとえ同一のクラスファイルから読み込まれたものであっても異なる実体であるので、相互に型変換を行うことはできない。この結果、キャストエラーが発生する。
【００７１】
このように、あるクラスローダＡで読み込まれたトレース用クラスのメソッドが、クラスローダＢで読み込まれたクラスのオブジェクトＣを引数として受け取る場合、処理中にオブジェクトＣをクラスＢとして利用しようとするとキャストエラーが生じる。
【００７２】
［リフレクションの使用］
図８に示したＴｒａｃｅクラス１５ｅ内で、「リフレクション」を用いて引数のオブジェクトを操作することにより、キャストエラーを回避することも考えられる。ここで言う「リフレクション」とは、プログラム自身の構造を、データとして操作する仕組みを指す。かかるリフレクションを使ってメソッドを呼び出すと上記のキャストエラーを抑制することができる。
【００７３】
すなわち、Ｔｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドは、Ｕｔｉｌオブジェクト１５ｃ２を受け取った後、リフレクションを使ってｇｅｔメソッドを呼び出し、その戻り値を実行トレースとして出力する。このようにリフレクションが用いられる場合、Ｕｔｉｌオブジェクト１５ｃ２を実際にインスタンス化したＵｔｉｌクラス１５ｃ１を取得してそのクラスのｇｅｔメソッドを返すことになるので、キャストエラーは生じない。
【００７４】
［リフレクション使用による弊害］
リフレクションが用いられる場合、次のように、多くの開発支援機能がトレースに利用できなくなってしまう。例えば、（１）コンパイル時（ＩＤＥ利用ではコーディング時も）の型検査、（２）コーディング時のコード補完、（３）コーディング時のリファクタリング（特に、メソッド名の自動変換）などの機能が利用できない。
【００７５】
図９及び図１０は、Ｔｒａｃｅコードの一例を示す図である。図９及び図１０には、クラス変換を行ってトレース処理を実行するＴｒａｃｅコードが示されているが、図９には、リフレクションが用いられないＴｒａｃｅコードが示される一方で、図１０には、リフレクションが用いられるＴｒａｃｅコードが示されている。
【００７６】
例えば、図９に示すＴｒａｃｅコードにおいて下線部２１の文に含まれるメソッドの記述を“ｇｅｔ”とするところを“ｇｅｙ”と誤って記述してしまったとしても、上記の機能（１）により開発時に発見できる。さらに、上記の機能（２）により「“ｇｅｔ”ではありませんか？」などのヒントがもらえる。加えて、Ｕｔｉｌクラスのｇｅｔメソッドの名前を“ｇｅｔＶａｌｕｅ”などに書き換える場合も、上記の機能（３）により、Ｔｒａｃｅクラス１５ｅのコードも自動変換される。このように、リフレクションが使用されない場合、上記の機能（１）〜（３）を有効活用できる。
【００７７】
一方、図１０に示すＴｒａｃｅコードの下線部２２の通り、リフレクションを使用する場合、メソッド名を、実行時に初めて決定する文字列データで指定することになる。そのため、もしメソッド名を書き間違っていたとしても、上記の機能（１）では発見できず、同様に、上記の機能（２）によるヒントももらえない。さらに、上記の機能（３）による自動変換も実施できない。
【００７８】
このように、リフレクションを使用することにより、リフレクションを使用しない場合と比べて上記のキャストエラーの発生は抑制できるものの、上記の機能（１）〜（３）を有効活用できないという制約も生じる。これらの開発支援機能が使用できない場合、プログラムの保守性が大きく低下する。さらに、リフレクションは他のコードよりも読み込みづらいので、実行速度も約１０倍程度遅くなる。
【００７９】
［目的の一側面］
これらのことから、本実施例では、「複数クラスローダを使い分けるＪａｖａ（登録商標）プログラム」の実行トレース出力内容をより手軽に変更できるようにするため、実行トレース出力処理を含むクラスを読み込んだクラスローダとは、異なるクラスローダで読み込まれたクラスのオブジェクトが実行トレース出力処理に引数として渡された場合にも、各種の開発支援機能、例えば上記の機能（１）〜（３）が適用可能であるように、リフレクションを使わずに記述された「オブジェクトをレシーバとしてクラスのメソッドを呼び出す」処理をキャストエラーを発生させることなく実行できるトレーシング方法を適用することを一側面とする。
【００８０】
上記のトレーシング方法を実現するために、本実施例では、トレース用クラスローダ管理部１７と、トレース用クラスローダ１８とが実装される。
【００８１】
［トレース用クラスローダ管理部１７］
トレース用クラスローダ管理部１７は、トレース用クラスローダ１８が読み込みを委譲するクラスローダの識別子順序集合の同値性に基づいて、各トレース用クラスローダ１８を管理する処理部である。
【００８２】
一実施形態として、トレース用クラスローダ管理部１７は、実行トレースの出力処理が呼び出される度、すなわちＴｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドの呼び出し式が実行される度に、当該ｗｒｉｔｅメソッドの引数として渡されるオブジェクトのクラスを読み込んだクラスローダに対応する識別子がクラスローダ識別子記憶部１７ａに登録されているか否かを判定する。
【００８３】
ここで、クラスローダ識別子記憶部１７ａには、クラスローダ及び識別子が対応付けられたデータ構造が採用される。例えば、クラスローダ識別子記憶部１７ａは、オブジェクトであるクラスローダの参照をキーとし、識別子をバリューとするＪａｖａ（登録商標）の連想配列により実現できる。ここで言う「識別子」は、数字または英字に限定されず、任意の文字列を採用することができる。このうち、クラスローダのキーには、ＳｙｓｔｅｍＣｌａｓｓＬｏａｄｅｒ以外のクラスローダが読み込まれる度に、当該クラスローダが格納されるメモリ上のアドレスを格納しておくことができる。
【００８４】
このようなクラスローダ識別子記憶部１７ａの構成の下、トレース用クラスローダ管理部１７は、ｗｒｉｔｅメソッドの引数として渡されるオブジェクトのクラスを読み込んだクラスローダに対応する識別子がクラスローダ識別子記憶部１７ａに登録されていない場合、ユニークな識別子を採番する。かかる識別子の採番方法には、一例として、昇順または降順で番号を付与する方法を採用することができる。その上で、トレース用クラスローダ管理部１７は、先に採番された識別子を当該クラスローダのキーに対応付けてクラスローダ識別子記憶部１７ａへ格納する。
【００８５】
その後、トレース用クラスローダ管理部１７は、クラスローダ識別子記憶部１７ａに新規の識別子が追加される度に、当該新規の識別子を要素とする順序付集合を生成する。そして、トレース用クラスローダ管理部１７は、ｗｒｉｔｅメソッドの引数として渡されるオブジェクトのクラスを読み込んだクラスローダを委譲先とする、トレース用クラスローダ１８を生成する。その上で、トレース用クラスローダ管理部１７は、先に生成された順序付集合をキーとする一方で先に生成されたトレース用クラスローダ１８をバリューとし、これらの対応関係をトレース用クラスローダ対応記憶部１７ｂへ格納する。
【００８６】
そして、トレース用クラスローダ管理部１７は、クラスファイル記憶部１１に記憶されたＴｒａｃｅクラスファイル１１ｃの読み込みを、先に生成されたトレース用クラスローダ１８に要求する。その後、トレース用クラスローダ管理部１７は、トレース用クラスローダ１８により読み込まれたＴｒａｃｅクラスファイル１１ｃを取得してＪａｖａ（登録商標）プログラムを実行するアプリ実行部１４へ出力する。なお、トレース用クラスローダ１８が既に生成されている場合、当該トレース用クラスローダ１８により読み込まれたＴｒａｃｅクラス１５ｅがアプリ実行部１４へ出力される。
【００８７】
図１１は、トレース用クラスローダの管理方法の一例を示す図である。図１１には、ＣｌａｓｓＬｏａｄｅｒ１５ｂにより読み込まれたＵｔｉｌクラス１５ｂ１からＵｔｉｌオブジェクト１５ｂ２が生成された上でＴｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドが実行された後に、ＯｔｈｅｒＬｏａｄｅｒ１５ｃにより読み込まれたＵｔｉｌクラス１５ｃ１からＵｔｉｌオブジェクト１５ｃ２が生成された局面が想定されている。
【００８８】
図１１に示すように、ＣｌａｓｓＬｏａｄｅｒ１５ｂによりロードされたＭｙＡｐｐクラス１５ｄのｍａｉｎメソッドが実行される場合、ＪＶＭは、ｍａｉｎメソッドの中でＴｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドの呼び出し式を実行する。このとき、ＪＶＭは、Ｕｔｉｌクラス１５ｃ２のオブジェクトを引数として処理するＴｒａｃｅクラス１５ｅのロードをトレース用クラスローダ管理部１７へリクエストする。
【００８９】
すると、トレース用クラスローダ管理部１７は、当該ｗｒｉｔｅメソッドの引数として渡されるＵｔｉｌオブジェクト１５ｃ２のクラスを読み込んだＯｔｈｅｒＬｏａｄｅｒ１５ｃに対応する識別子がクラスローダ識別子記憶部１７ａに登録されているか否かを判定する。このとき、ＯｔｈｅｒＬｏａｄｅｒ１５ｃに対応する識別子がクラスローダ識別子記憶部１７ａに登録されていない場合、一例として、ＣｌａｓｓＬｏａｄｅｒ１５ｂに採番された識別子「１」へ昇順に続く連番の識別子「２」がＯｔｈｅｒＬｏａｄｅｒ１５ｃに採番される。この結果、クラスローダ識別子記憶部１７ａには、図１１の網掛け部分に示す通り、キーであるＯｔｈｅｒＬｏａｄｅｒ１５ｃに対応付けてバリューである２が格納される。
【００９０】
このようにクラスローダ識別子記憶部１７ａに新規の識別子が追加されると、トレース用クラスローダ管理部１７は、当該新規の識別子「２」を要素とする順序付集合｛２｝を生成する。そして、トレース用クラスローダ管理部１７は、ｗｒｉｔｅメソッドの引数として渡されるオブジェクトのクラスを読み込んだＯｔｈｅｒＬｏａｄｅｒ１５ｃを委譲先とする、トレース用クラスローダ１８ｃを生成する。その上で、トレース用クラスローダ管理部１７は、先に生成された順序付集合｛２｝をキーとする一方で先に生成されたトレース用クラスローダ１８ｃをバリューとし、これらの対応関係をトレース用クラスローダ対応記憶部１７ｂへ格納する。
【００９１】
そして、トレース用クラスローダ管理部１７は、クラスファイル記憶部１１に記憶されたＴｒａｃｅクラスファイル１１ｃの読み込みを、先に生成されたトレース用クラスローダ１８ｃに要求する。その後、トレース用クラスローダ管理部１７は、トレース用クラスローダ１８ｃにより読み込まれたＴｒａｃｅクラスファイル１１ｃを取得してＪａｖａ（登録商標）プログラムを実行するアプリ実行部１４へ出力する。
【００９２】
［トレース用クラスローダ１８］
トレース用クラスローダ１８は、Ｔｒａｃｅクラスファイル１１ｃを読み込むクラスローダである。
【００９３】
一実施形態として、トレース用クラスローダ１８は、トレース用クラスローダ対応記憶部１７ｂに格納される順序付集合ごとにトレース用クラスローダ管理部１７により生成される。例えば、図１１に示した例で言えば、ＣｌａｓｓＬｏａｄｅｒ１５ｂの識別子「１」がクラスローダ識別子記憶部１７ａに格納された場合、トレース用クラスローダ対応記憶部１７ｂに順序付集合｛１｝が格納されることにより、トレース用クラスローダ１８ｃが生成される。また、ＯｔｈｅｒＬｏａｄｅｒ１５ｃの識別子「２」がクラスローダ識別子記憶部１７ａに格納された場合、トレース用クラスローダ対応記憶部１７ｂに順序付集合｛２｝が格納されることにより、トレース用クラスローダ１８ｃが生成される。
【００９４】
ここで、トレース用クラスローダ１８は、当該トレース用クラスローダ１８がクラスの読み込みを委譲する優先順位と、委譲先のクラスローダとを対応付けて記憶する優先順位記憶部１８１を有する。かかる優先順位記憶部１８１には、トレース用クラスローダ１８がトレース用クラスローダ管理部１７により生成された場合、次のようなポリシーにしたがって、キーである優先順位に対応付けてバリューであるクラスローダのオブジェクトの参照が格納される。すなわち、トレース用クラスローダ１８は、上記の優先順位が高いクラスローダから順に、ｗｒｉｔｅメソッドの引数として渡されるオブジェクトのクラスを読み込んだクラスローダ、トレース用クラスローダ１８、ＳｙｓｔｅｍＣｌａｓｓＬｏａｄｅｒ１５ａを優先順位記憶部１８１へ格納する。
【００９５】
かかる優先順位記憶部１８１を参照して、トレース用クラスローダ１８は、トレース用クラスローダ管理部１７からクラスの読み込みが要求された場合に、優先順位が高いクラスローダから順にクラスの読み込みを委譲する。このとき、トレース用クラスローダ１８は、委譲先のクラスローダが当該要求に対応するクラスファイルの格納位置を参照できない場合、クラスの読み込みに失敗する。この場合、トレース用クラスローダ１８は、クラスの読み込みに失敗したクラスローダの次に優先順位が高いクラスローダにクラスの読み込みを委譲する。なお、優先順位記憶部１８１に記憶された全てのクラスローダが読み込めなかった場合、諦めて例外が出力される。この場合、クラスの読み込みの失敗は、トレース用クラスローダ１８の誤りではなく、実行トレース出力処理の誤りである可能性が高い。
【００９６】
図１２は、優先順位の設定方法の一例を示す図である。図１２では、クラスの読み込みを委譲するクラスローダとしてＯｔｈｅｒＬｏａｄｅｒ１５ｃがトレース用クラスローダ管理部１７により指定された状態でトレース用クラスローダ１８ｃが生成された場合を想定する。この場合、図１２に示すように、優先順位記憶部１８ｃ１には、上記の優先順位が高いクラスローダから順に、ｗｒｉｔｅメソッドの引数として渡されるオブジェクトのクラスを読み込んだＯｔｈｅｒＬｏａｄｅｒ１５ｃ、トレース用クラスローダ１８ｃ、ＳｙｓｔｅｍＣｌａｓｓＬｏａｄｅｒ１５ａが格納される。
【００９７】
図１３は、クラス及びオブジェクト間の相関の一例を示す図である。図１３には、図８と同様、ＣｌａｓｓＬｏａｄｅｒ１５ｂにより読み込まれたクラス及びそのクラスから生成されたオブジェクトと、ＯｔｈｅｒＬｏａｄｅｒ１５ｃにより読み込まれたクラス及びそのクラスから生成されたオブジェクトとが示されている。
【００９８】
ここで、図１３の例では、図１２を用いて説明したように、トレース用クラスローダ管理部１７と、トレース用クラスローダ管理部１７により生成されたトレース用クラスローダ１８ｃとが含まれる点が図８の例と異なる。かかるトレース用クラスローダ１８ｃは、トレース用クラスローダ管理部１７からクラスの読み込みが要求された場合、優先順位記憶部１８ｃ１に記憶された優先順位にしたがってクラスの読み込みを委譲する。これによって、Ｔｒａｃｅクラス１５ｅの定義に含まれる「他のクラスの名前」は、全て、当該トレース用クラスローダ１８ｃによって解釈されるので、たとえ同名のクラスがＯｔｈｅｒＬｏａｄｅｒ１５ｃ以外のクラスローダで管理されていても、ＯｔｈｅｒＬｏａｄｅｒ１５ｃが管理するクラスが最優先される。この結果、Ｔｒａｃｅクラス１５ｅのｗｒｉｔｅメソッドの呼び出し式が実行される場合、ｗｒｉｔｅメソッドの引数として渡されるオブジェクトをインスタンス化したクラスを読み込んだＯｔｈｅｒＬｏａｄｅｒ１５ｃが管理するクラスに型変換できる。言い換えれば、ＯｔｈｅｒＬｏａｄｅｒ１５ｃとは異なるＣｌａｓｓＬｏａｄｅｒ１５ｂが管理する同名のクラスへ型変換されるのを抑制できる。したがって、キャストエラーの発生を抑制できる。
【００９９】
［処理の流れ］
次に、本実施例に係る情報処理装置１０の処理の流れについて説明する。図１４及び図１５は、実施例１に係るトレース処理の手順を示すフローチャートである。図１４に示すように、アプリ実行部１４は、入力デバイスまたはネット−ワークを介して、Ｊａｖａ（登録商標）プログラムの実行指示（初めに実行するクラス４の指定及びクラス変換設定ファイル１２ａの使用）を受け付ける（ステップＳ４０１）。
【０１００】
すると、クラス変換部１６は、クラス変換設定ファイル１２ａをクラス変換設定ファイル記憶部１２から取得し、取得された内容をクラス変換設定記憶部１６ａに格納する（ステップＳ４０２）。
【０１０１】
そして、アプリ実行部１４は、ＳｙｓｔｅｍＣｌａｓｓＬｏａｄｅｒ１５ａに、初めに実行するクラスであるクラス４の読み込みを要求する（ステップＳ４０３）。続いて、ＳｙｓｔｅｍＣｌａｓｓＬｏａｄｅｒ１５ａは、クラス４に対応するクラスファイル１をファイルシステムから取得した後に、クラス変換部１６にクラス４の変換を要求する（ステップＳ４０４）。
【０１０２】
その後、クラス変換部１６は、クラス変換設定に従って、クラス４がクラス変換の対象かどうかを判断する（ステップＳ４０５）。このとき、クラス４に変換対象のメソッド６があり、かつ変換対象のメソッド６内に戻り値を持つメソッド呼び出し式７がある場合（ステップＳ４０６ＹｅｓかつステップＳ４０７Ｙｅｓ）、クラス変換部１６は、変換対象のメソッド呼び出し式７について、その戻り値を実行トレースとして出力する式（＝戻り値を引数としてクラス５のｗｒｉｔｅメソッドを呼び出す式）を挿入する（ステップＳ４０８）。続いて、クラス変換部１６は、ＳｙｓｔｅｍＣｌａｓｓＬｏａｄｅｒ１５ａにクラス４を返す（ステップＳ４０９）。
【０１０３】
例えば、ＭｙＡｐｐクラス１５ｄがクラス４として指定された場合、ＭｙＡｐｐクラス１５ｄに含まれるｍａｉｎメソッドが変換対象のメソッド６に該当すると共にｍａｉｎメソッド内に戻り値型のＵｔｉｌ．ｃａｌｃ（）が含まれるので、ステップＳ４０６及びステップＳ４０７の分岐はいずれもＹｅｓと判断される。この場合、図３に示した通り、Ｔｒａｃｅクラスファイル１１ｃに定義された実行トレースの出力処理がＭｙＡｐｐクラスファイル１１ａへ挿入される。
【０１０４】
一方、クラス４に変換対象のメソッド６が存在しないか、あるいは変換対象のメソッド６内に戻り値を持つメソッド呼び出し式７がない場合（ステップＳ４０６ＮｏまたはステップＳ４０７Ｎｏ）、ステップＳ４０８の処理を飛ばし、ステップＳ４０９の処理が実行される。
【０１０５】
そして、ＳｙｓｔｅｍＣｌａｓｓＬｏａｄｅｒ１５ａは、アプリ実行部１４にクラス４を返す（ステップＳ４１０）。その上で、アプリ実行部１４は、クラス４のｍａｉｎメソッドを実行する（ステップＳ４１１）。
【０１０６】
続いて、図１５に示すように、実行中のメソッドに未だ実行されていない式８が存在する限り（ステップＳ４１２Ｙｅｓ）、下記のステップＳ４１３からステップＳ４２５までの処理が繰り返し実行される。すなわち、式８が特定のクラスローダ９に特定のクラス１０の読み込みを要求するものである場合（ステップＳ４１３Ｙｅｓ）、アプリ実行部１４は、式８を解釈し、指定されたクラスローダ９に、指定されたクラス１０の読み込みを要求する（ステップＳ４１４）。そして、クラスローダ９は、クラス１０に対応するクラスファイル１１をクラスファイル記憶部１１から取得した後に、読み込んだクラス１０をアプリ実行部１４に返し（ステップＳ４１５）、ステップＳ４１２の処理へ移行する。これらステップＳ４１４及びステップＳ４１５の処理は、一例として、ＣｌａｓｓＬｏａｄｅｒ１５ｂによりＵｔｉｌクラス１５ｂ１が読み込まれる処理やＯｔｈｅｒＬｏａｄｅｒ１５ｃによりＵｔｉｌクラス１５ｃ１が読み込まれる処理などに該当する。
【０１０７】
一方、式８が特定のクラスローダ９に特定のクラス１０の読み込みを要求するものでなく、式８が特定のクラス１２のオブジェクトを生成するものである場合（ステップＳ４１３ＮｏかつステップＳ４１６Ｙｅｓ）、アプリ実行部１４は、式８を解釈し、指定されたクラス１２のオブジェクト１３を新たに生成する（ステップＳ４１７）。これには、一例として、Ｕｔｉｌクラス１５ｂ１をインスタンス化することによりＵｔｉｌオブジェクト１５ｂ２を生成する処理やＵｔｉｌクラス１５ｃ１をインスタンス化することによりＵｔｉｌオブジェクト１５ｃ２を生成する処理などが当てはまる。
【０１０８】
また、式８が特定のクラスまたはオブジェクトのメソッド１４を呼び出すものである場合（ステップＳ４１８Ｙｅｓ）、アプリ実行部１４は、式８を解釈し、指定されたクラスまたはオブジェクトのメソッド１４を、指定された値を引数として実行し（ステップＳ４１９）、ステップＳ４１２の処理へ移行する。なお、ステップＳ４１８Ｙｅｓの条件を満たすメソッドの一例には、Ｕｔｉｌ．ｃａｌｃ（）などが含まれる。
【０１０９】
また、式８が実行トレースの出力処理である場合、すなわちクラス５のｗｒｉｔｅメソッドを呼び出すものである場合（ステップＳ４２０Ｙｅｓ）、アプリ実行部１４は、式８を解釈し、トレース用クラスローダ管理部１７にｗｒｉｔｅメソッド呼び出しの引数１５を処理できるクラス５の読み込みを要求する（ステップＳ４２１）。
【０１１０】
すると、トレース用クラスローダ管理部１７は、指定された引数１５を処理できるクラス５を、適切なトレース用クラスローダ１８を使って読み込んだ後に、クラス５をアプリ実行部１４に返す（ステップＳ４２２）。
【０１１１】
かかるステップＳ４２２の処理のサブルーチンを図１６を用いて説明する。図１６は、実施例１に係るトレース処理のサブルーチンを示すフローチャートである。この処理は、図１５に示したステップＳ４２２の処理に対応する。図１６に示すように、トレース用クラスローダ管理部１７は、指定された引数１５のクラスを読み込んだクラスローダ１７を取得する（ステップＳ５０１）。
【０１１２】
このとき、クラスローダ識別子記憶部１７ａにクラスローダ１７に対応する（同値である）識別子１８がまだ格納されていない場合（ステップＳ５０２Ｙｅｓ）、トレース用クラスローダ管理部１７は、ユニークな識別子１８を生成した後に、クラスローダ１７と識別子１８との対応関係を、クラスローダー識別子記憶部１７ａに格納する（ステップＳ５０３）。そして、トレース用クラスローダ管理部１７は、識別子１８を要素とする、識別子の順序付集合１９を生成する（ステップＳ５０４）。なお、クラスローダー識別子記憶部１７ａにクラスローダ１７に対応する識別子１８がまだ格納されていない場合（ステップＳ５０２Ｎｏ）、ステップＳ５０３及びステップＳ５０４の処理を飛ばし、ステップＳ５０５の処理へ移行する。
【０１１３】
そして、トレース用クラスローダ対応記憶部１７ｂに識別子の順序付集合１９に対応する（同値である）トレース用クラスローダ２０がまだ格納されていない場合（ステップＳ５０５Ｙｅｓ）、トレース用クラスローダ管理部１７は、引数１５のクラスローダ１７を委譲先とする、トレース用クラスローダ２０を生成する（ステップＳ５０６）。なお、トレース用クラスローダ対応記憶部１７ｂに識別子の順序付集合１９に対応するトレース用クラスローダ２０が格納されている場合（ステップＳ５０５Ｎｏ）、ステップＳ５０９の処理へ移行する。
【０１１４】
その上で、トレース用クラスローダ２０は、引数１５のクラスローダ１７を最優先する委譲先として、優先順位記憶部に格納する（ステップＳ５０７）。さらに、トレース用クラスローダ２０は、自身（トレース用クラスローダ２０）を次に優先する委譲先として、ＳｙｓｔｅｍＣｌａｓｓＬｏａｄｅｒ１５ａをその次に優先する委譲先として、各々を優先順位記憶部に格納する（ステップＳ５０８）。
【０１１５】
そして、トレース用クラスローダ管理部１７は、トレース用クラスローダ２０に、実行トレース出力処理が定義されたクラス５の読み込みを要求する（ステップＳ５０９）。そして、トレース用クラスローダ２０は、クラス５に対応するクラスファイル２をクラスファイル記憶部から取得した後に、クラス５の処理に用いる他のクラス２１があるかどうかを判断する（ステップＳ５１０）。
【０１１６】
このとき、クラス５の処理に用いる他のクラス２１がまだ存在する場合（ステップＳ５１１Ｙｅｓ）、トレース用クラスローダ２０は、優先順位記憶部に記憶された優先順位の高いクラスローダ２２から順に、クラス２１の読み込みを要求する（ステップＳ５１２）。そして、優先度の高いクラスローダ２２を使って、クラス２１を読み込むことができるまで（ステップＳ５１３Ｎｏ）、上記のステップＳ５１２の処理を繰り返し実行する。
【０１１７】
その後、クラス５の処理に用いる他のクラス２１が存在しない場合（ステップＳ５１１Ｎｏ）、トレース用クラスローダ２０は、トレース用クラスローダ管理部１７に、読み込んだクラス５を返し（ステップＳ５１４）、サブルーチンを終了する。
【０１１８】
図１５の説明に戻り、ステップＳ４２２の処理が終了すると、アプリ実行部１４は、式８を解釈し、トレース用クラスローダ管理部１７に、ｗｒｉｔｅメソッド呼び出しの引数１５を処理できるクラス５の読み込みを要求する（ステップＳ４２３）。
【０１１９】
そして、アプリ実行部１４は、クラス５のｗｒｉｔｅメソッドの引数に引数１５を指定して実行する（ステップＳ４２４）。その上で、クラス５のｗｒｉｔｅメソッドは、引数１５を値１６に変換した後に、値１６を実行トレースとして実行トレース記憶部１３に永続化し（ステップＳ４２５）、ステップＳ４１２の処理へ移行する。
【０１２０】
［効果の一側面］
上述してきたように、本実施例に係る情報処理装置１０は、実行トレース出力処理がＷｅｂアプリ実行用のクラスのオブジェクトを引数として呼び出す際、当該オブジェクトをインスタンス化したクラスを読み込んだクラスローダが管理するクラスに型変換する。したがって、本実施例に係る情報処理装置１０によれば、キャストエラーの発生を抑制できる。
【０１２１】
この他、本実施例に係る情報処理装置１０によれば、実行トレース出力処理の保守性も高めることができる。すなわち、最近では、業務アプリといった大規模かつ複雑なＷｅｂアプリであっても、自社開発せずにＯＳＳを組み合わせて実現するようになってきている。このような背景から、ＯＳＳのソードコードの変更を最小限とし、ＯＳＳの振舞いを様々な観点から調査するニーズが徐々に生まれてきている。この場合、ＯＳＳの開発者と、実行トレース出力処理の開発者は異なる組織であり、かつ、調査のために多様な仮説検証を繰り返し行う必要がある。これらのことから、開発支援機能の利用促進により、実行トレース出力処理の保守性も高めることができる。
【実施例２】
【０１２２】
さて、これまで開示の装置に関する実施例について説明したが、本発明は上述した実施例以外にも、種々の異なる形態にて実施されてよいものである。そこで、以下では、本発明に含まれる他の実施例を説明する。
【０１２３】
［分散および統合］
また、図示した各装置の各構成要素は、必ずしも物理的に図示の如く構成されておらずともよい。すなわち、各装置の分散・統合の具体的形態は図示のものに限られず、その全部または一部を、各種の負荷や使用状況などに応じて、任意の単位で機能的または物理的に分散・統合して構成することができる。例えば、アプリ実行部１４、クラス記憶部１５、クラス変換部１６、トレース用クラスローダ管理部１７またはトレース用クラスローダ１８を情報処理装置１０の外部装置としてネットワーク経由で接続するようにしてもよい。また、アプリ実行部１４、クラス記憶部１５、クラス変換部１６、トレース用クラスローダ管理部１７またはトレース用クラスローダ１８を別の装置がそれぞれ有し、ネットワーク接続されて協働することで、上記の情報処理装置１０の機能を実現するようにしてもよい。
【符号の説明】
【０１２４】
１０    情報処理装置
１１    クラスファイル記憶部
１１ａ  ＭｙＡｐｐクラスファイル
１１ｂ  Ｕｔｉｌクラスファイル
１１ｃ  Ｔｒａｃｅクラスファイル
１２    クラス変換設定ファイル記憶部
１２ａ  クラス変換設定ファイル
１３    実行トレース記憶部
１３ａ  トレースファイル
１４    アプリ実行部
１５    クラス記憶部
１６    クラス変換部
１６ａ  クラス変換設定記憶部
１７    トレース用クラスローダ管理部
１７ａ  クラスローダ識別子記憶部
１７ｂ  トレース用クラスローダ対応記憶部
１８    トレース用クラスローダ
１８１  優先順位記憶部
【図１】
2017174024.tif 000003
【図２】
2017174024.tif 000004
【図３】
2017174024.tif 000005
【図４】
2017174024.tif 000006
【図５】
2017174024.tif 000007
【図６】
2017174024.tif 000008
【図７】
2017174024.tif 000009
【図８】
2017174024.tif 000010
【図９】
2017174024.tif 000011
【図１０】
2017174024.tif 000012
【図１１】
2017174024.tif 000013
【図１２】
2017174024.tif 000014
【図１３】
2017174024.tif 000015
【図１４】
2017174024.tif 000016
【図１５】
2017174024.tif 000017
【図１６】
2017174024.tif 000018