(57)【特許請求の範囲】
【請求項１】
ロード済のクラスを記憶する第１の記憶部と、前記第１の記憶部に記憶されているクラスの完全修飾クラス名とロード元を示す格納場所情報と変更前パッケージ名との組を記憶する第２の記憶部と、前記第１および第２の記憶部に接続されたプロセッサとを備え、
前記プロセッサは、
前記第１の記憶部に記憶されているクラスから参照されているクラスが前記第１の記憶部に記憶されているか否かを、参照先のクラスの完全修飾クラス名に一致する完全修飾クラス名が前記第２の記憶部に記憶されており、且つ、当該記憶されている完全修飾クラス名と同じ組の格納場所情報と参照元のクラスの定義ファイルに記述されている参照先のクラスのロード元を示す格納場所情報とが一致するか否かによって判断し、
前記参照されているクラスが前記第１の記憶部に記憶されていない場合、参照元のクラスに対応する定義ファイルに記述されている参照先のクラスの格納場所情報で示される場所から参照先のクラスを前記第１の記憶部にロードし、
前記ロードした参照先のクラスの完全修飾クラス名が前記第２の記憶部に記憶されていれば、前記参照先のクラスのバイトコードに出現する、前記参照先のクラスの完全修飾クラス名におけるパッケージ名を、異なるパッケージ名に、前記第１の記憶部上で変更すると共に、前記参照元のクラスのバイトコードに出現する、前記参照先のクラスの完全修飾クラス名におけるパッケージ名を、前記異なるパッケージ名に、前記第１の記憶部上で変更し、
前記ロードした参照先のクラスに関して、当該クラスの完全修飾クラス名が前記第２の記憶部に記憶されていなかったならば、当該クラスの完全修飾クラス名とロード元を示す格納場所情報とを含み変更前パッケージ名を有しない組を前記第２の記憶部に記憶し、当該クラスの完全修飾クラス名が前記第２の記憶部に記憶されていたならば、当該クラスのパッケージ名変更後の完全修飾クラス名とロード元を示す格納場所情報と変更前パッケージ名との組を前記第２の記憶部に記憶する
ようにプログラムされている、情報処理装置。
【請求項２】
前記プロセッサは、さらに、
前記ロードした参照先のクラスが参照する他のクラスに関して、当該他のクラスの完全修飾クラス名と同一となる変更前完全修飾クラス名に相当する完全修飾クラス名と変更前パッケージ名とを含む組であって、当該組の格納場所情報が前記ロードした参照先のクラスの定義ファイルに記述されている当該他のクラスのロード元を示す格納場所情報と一致する組が存在するか否かを判断し、存在する場合、前記ロードした参照先のクラスのバイトコードに出現する、参照している当該他のクラスの完全修飾クラス名を、前記第１の記憶部上で、前記存在した組における完全修飾クラス名に変更する
ようにプログラムされている請求項１に記載の情報処理装置。
【請求項３】
前記パッケージ名の変更が行われるクラスは、クラスライブラリのクラスである
請求項１または２に記載の情報処理装置。
【請求項４】
前記クラスライブラリの定義ファイルに、当該クラスライブラリのクラスのパッケージ名を変更する規則が記述されており、前記パッケージ名の変更では、前記規則に従って前記パッケージ名の変更を行う
請求項３に記載の情報処理装置。
【請求項５】
外部定義ファイルに、前記クラスライブラリのクラスのパッケージ名を変更する規則が記述されており、前記パッケージ名の変更では、前記規則に従って前記パッケージ名の変更を行う
請求項３に記載の情報処理装置。
【請求項６】
前記規則が、複数種類記述されている
請求項４または５に記載の情報処理装置。
【請求項７】
ロード済のクラスを記憶する第１の記憶部と、前記第１の記憶部に記憶されているクラスの完全修飾クラス名とロード元を示す格納場所情報と変更前パッケージ名との組を記憶する第２の記憶部と、前記第１および第２の記憶部に接続されたプロセッサとを備えた情報処理装置が実行するプログラム実行方法であって、
前記プロセッサが、
前記第１の記憶部に記憶されているクラスから参照されているクラスが前記第１の記憶部に記憶されているか否かを、参照先のクラスの完全修飾クラス名に一致する完全修飾クラス名が前記第２の記憶部に記憶されており、且つ、当該記憶されている完全修飾クラス名と同じ組の格納場所情報と参照元のクラスの定義ファイルに記述されている参照先のクラスのロード元を示す格納場所情報とが一致するか否かによって判断し、
前記参照されているクラスが前記第１の記憶部に記憶されていない場合、参照元のクラスに対応する定義ファイルに記述されている参照先のクラスの格納場所情報で示される場所から参照先のクラスを前記第１の記憶部にロードし、
前記ロードした参照先のクラスの完全修飾クラス名が前記第２の記憶部に記憶されていれば、前記参照先のクラスのバイトコードに出現する、前記参照先のクラスの完全修飾クラス名におけるパッケージ名を、異なるパッケージ名に、前記第１の記憶部上で変更すると共に、前記参照元のクラスのバイトコードに出現する、前記参照先のクラスの完全修飾クラス名におけるパッケージ名を、前記異なるパッケージ名に、前記第１の記憶部上で変更し、
前記ロードした参照先のクラスに関して、当該クラスの完全修飾クラス名が前記第２の記憶部に記憶されていなかったならば、当該クラスの完全修飾クラス名とロード元を示す格納場所情報とを含み変更前パッケージ名を有しない組を前記第２の記憶部に記憶し、当該クラスの完全修飾クラス名が前記第２の記憶部に記憶されていたならば、当該クラスのパッケージ名変更後の完全修飾クラス名とロード元を示す格納場所情報と変更前パッケージ名との組を前記第２の記憶部に記憶する
プログラム実行方法。
【請求項８】
ロード済のクラスを記憶する第１の記憶部と、前記第１の記憶部に記憶されているクラスの完全修飾クラス名とロード元を示す格納場所情報と変更前パッケージ名との組を記憶する第２の記憶部とに接続されたプロセッサに、
前記第１の記憶部に記憶されているクラスから参照されているクラスが前記第１の記憶部に記憶されているか否かを、参照先のクラスの完全修飾クラス名に一致する完全修飾クラス名が前記第２の記憶部に記憶されており、且つ、当該記憶されている完全修飾クラス名と同じ組の格納場所情報と参照元のクラスの定義ファイルに記述されている参照先のクラスのロード元を示す格納場所情報とが一致するか否かによって判断するステップと、
前記参照されているクラスが前記第１の記憶部に記憶されていない場合、参照元のクラスに対応する定義ファイルに記述されている参照先のクラスの格納場所情報で示される場所から参照先のクラスを前記第１の記憶部にロードするステップと、
前記ロードした参照先のクラスの完全修飾クラス名が前記第２の記憶部に記憶されていれば、前記参照先のクラスのバイトコードに出現する、前記参照先のクラスの完全修飾クラス名におけるパッケージ名を、異なるパッケージ名に、前記第１の記憶部上で変更すると共に、前記参照元のクラスのバイトコードに出現する、前記参照先のクラスの完全修飾クラス名におけるパッケージ名を、前記異なるパッケージ名に、前記第１の記憶部上で変更するステップと、
前記ロードした参照先のクラスに関して、当該クラスの完全修飾クラス名が前記第２の記憶部に記憶されていなかったならば、当該クラスの完全修飾クラス名とロード元を示す格納場所情報とを含み変更前パッケージ名を有しない組を前記第２の記憶部に記憶し、当該クラスの完全修飾クラス名が前記第２の記憶部に記憶されていたならば、当該クラスのパッケージ名変更後の完全修飾クラス名とロード元を示す格納場所情報と変更前パッケージ名との組を前記第２の記憶部に記憶するステップと
を行わせるためのプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、オブジェクト指向言語で作成されたプログラムをロードして実行する情報処理装置およびそのプログラム実行方法に関する。
【背景技術】
【０００２】
Java（登録商標）仮想マシンを備えた情報処理装置では、Javaアプリケーションを実行するとき、必要とするクラスを装置内あるいは装置外に存在するクラスライブラリ（単にライブラリとも称す）からロードする（例えば特許文献１参照）。このロードを司る部分は、クラスローダと呼ばれる。
【０００３】
ライブラリは、或る特定の機能を持ったプログラムを一つのクラスとして部品化し、関連する複数のクラスを一つのファイルにまとめたものである。こうしたクラスはプログラムの部品として利用できるため、良く使われる汎用的なものをライブラリに集めておくことで、プログラミングの労力を軽減することができる。また、ライブラリは、パッケージと呼ばれる単位で機能ごとに分類されている。
【０００４】
クラスのクラス名とそのクラスが属するパッケージのパッケージ名とを組み合わせた名前を、完全修飾クラス名と呼ぶ。完全修飾クラス名を使用することにより、同じクラス名を持つクラスであっても、パッケージ名によって区別することができる。Java仮想マシンでは、メモリにロードしたクラスのバイトコード上におけるクラス間の参照関係は完全修飾クラス名を使用して解決されている。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開2007-206965号公報
【発明の概要】
【発明が解決しようとする課題】
【０００６】
上述したようにJava仮想マシンでは、メモリにロードしたクラスのバイトコード上におけるクラス間の参照関係は完全修飾クラス名を使用して解決されている。従って、メモリにロードされる複数のクラスの完全修飾クラス名が全く同じ場合、クラス間の参照関係を一意に決定することができない。それ故、同じ完全修飾クラス名を持つ複数のクラスを一つのアプリケーションで利用する場合、事前に当該クラスのパッケージ名の変更が必要であった。例えば、パッケージ名およびクラス名が同じで、バージョンの異なる複数のライブラリを一つのアプリケーションで利用する場合、完全修飾クラス名の競合が発生しないように事前にライブラリの書き換えを行う必要があった。
【０００７】
本発明の目的は、上述した課題、すなわち、同じ完全修飾クラス名を持つ複数のクラスを一つのアプリケーションで使用するためには、完全修飾クラス名の競合が発生しないように事前にパッケージ名の書き換えが必要になる、という課題を解決する情報処理装置およびプログラム実行方法を提供することにある。
【課題を解決するための手段】
【０００８】
本発明の一形態にかかる情報処理装置は、
ロード済のクラスを記憶する第１の記憶部と、前記第１の記憶部に記憶されているクラスの完全修飾クラス名とロード元を示す格納場所情報と変更前パッケージ名との組を記憶する第２の記憶部と、前記第１および第２の記憶部に接続されたプロセッサとを備え、
前記プロセッサは、
前記第１の記憶部に記憶されているクラスから参照されているクラスが前記第１の記憶部に記憶されているか否かを、参照先のクラスの完全修飾クラス名に一致する完全修飾クラス名が上記第２の記憶部に記憶されており、且つ、当該記憶されている完全修飾クラス名と同じ組の格納場所情報と参照元のクラスの定義ファイルに記述されている参照先のクラスのロード元を示す格納場所情報とが一致するか否かによって判断し、
上記参照されているクラスが上記第１の記憶部に記憶されていない場合、参照元のクラスに対応する定義ファイルに記述されている参照先のクラスの格納場所情報で示される場所から参照先のクラスを上記第１の記憶部にロードし、
上記ロードした参照先のクラスの完全修飾クラス名が上記第２の記憶部に記憶されていれば、上記参照先のクラスのバイトコードに出現する、上記参照先のクラスの完全修飾クラス名におけるパッケージ名を、異なるパッケージ名に、上記第１の記憶部上で変更すると共に、上記参照元のクラスのバイトコードに出現する、上記参照先のクラスの完全修飾クラス名におけるパッケージ名を、上記異なるパッケージ名に、上記第１の記憶部上で変更し、
上記ロードした参照先のクラスに関して、当該クラスの完全修飾クラス名が上記第２の記憶部に記憶されていなかったならば、当該クラスの完全修飾クラス名とロード元を示す格納場所情報とを含み変更前パッケージ名を有しない組を上記第２の記憶部に記憶し、当該クラスの完全修飾クラス名が上記第２の記憶部に記憶されていたならば、当該クラスのパッケージ名変更後の完全修飾クラス名とロード元を示す格納場所情報と変更前パッケージ名との組を上記第２の記憶部に記憶する
ようにプログラムされている。
【発明の効果】
【０００９】
本発明は上述した構成を有するため、同じ完全修飾クラス名を持つ複数のクラスを一つのアプリケーションで使用することができる。また、完全修飾クラス名の競合が発生しないように事前にパッケージ名を書き換える必要がない。
【図面の簡単な説明】
【００１０】
【図１】本発明の第１の実施形態のブロック図である。
【図２】本発明の第１の実施形態における処理の一例を示すフローチャートである。
【図３】本発明の第１の実施形態における記憶部の或る時点の内容の一例を示す図である。
【図４】本発明の第１の実施形態における記憶部の別の時点における内容の一例を示す図である。
【図５】本発明の第１の実施形態における記憶部の更に別の時点における内容の一例を示す図である。
【図６】本発明の第２の実施形態の構成図である。
【図７】本発明の第２の実施形態におけるライブラリの定義ファイルの内容例を示す図である。
【図８】本発明の第２の実施形態における変更記録表の一例を示す図である。
【図９】本発明の第２の実施形態における処理の一例を示すフローチャートである。
【図１０】本発明の第３の実施形態におけるライブラリの定義ファイルの内容例を示す図である。
【図１１】本発明の第４の実施形態における処理の一例を示すフローチャートである。
【図１２】本発明の第５の実施形態におけるライブラリの定義ファイルの内容例を示す図である。
【図１３】本発明の第５の実施形態におけるパッケージ名の変更イメージの一例を示す図である。
【図１４】本発明の第６の実施形態におけるクラスローダの階層構造の一例を示す図である。
【発明を実施するための形態】
【００１１】
次に本発明の実施の形態について図面を参照して詳細に説明する。
[第１の実施形態]
図１を参照すると、本発明の第１の実施形態にかかる情報処理装置は、記憶部101〜103と、記録媒体104と、記憶部101〜103および記録媒体104に接続されたプロセッサ105とを有する。また、通信I/F部（通信インターフェース部）106、操作入力部107、および画面操作部108を有していてもよい。
【００１２】
記憶部101は、例えばRAMで構成され、ロード済のクラスを記憶する。
【００１３】
記憶部102は、例えばRAMで構成され、記憶部101にロード済のクラスの完全修飾クラス名と、当該クラスが格納されていたロード元の場所の情報（例えばファイル名）と、当該クラスの完全修飾クラス名がパッケージ名をロード時に変更して生成したものである場合には変更前のパッケージ名との組を記憶する。
【００１４】
記憶部103は、ROMやハードディスク等で構成され、アプリケーション111とライブラリ112、113とを記憶する。アプリケーション111とライブラリ112、113は、Javaバイトコードで記述されている。
【００１５】
アプリケーション111は、複数のクラス121〜123と、それぞれのクラス121〜123の定義ファイル131〜133とを有する。定義ファイル131〜133には、クラス121〜123から参照（利用）するクラスを格納している場所の情報（例えばファイル名）が記述されている。
【００１６】
ライブラリ112は、クラス141を有し、ライブラリ113はクラス151を有する。
【００１７】
プロセッサ105は、CPU等のマイクロプロセッサとその周辺回路とを有し、装置全体を制御する機能を有する。
【００１８】
記録媒体104は、半導体メモリ、CDROM、磁気ディスク等のコンピュータ読み取り可能は記録媒体であり、プログラム181を記憶する。記録媒体104に記録されたプログラム181は、プロセッサ105の起動時にプロセッサ105に読み取られ、プロセッサ105の動作を制御することにより、プロセッサ105上にJava仮想マシン161を生成する。
【００１９】
Java仮想マシン161は、インタプリタ171とクラスローダ172とを有する。
【００２０】
インタプリタ171は、Javaのバイトコードを解釈および実行する機能を有する。
【００２１】
また、インタプリタ171は、記憶部101に記憶されているクラスから参照されているクラスが記憶部101に記憶されているか否かを、参照先のクラスの完全修飾クラス名に一致する完全修飾クラス名が記憶部102に記憶されており、且つ、当該記憶されている完全修飾クラス名と同じ組の格納場所情報と参照元のクラスの定義ファイルに記述されている参照先のクラスのロード元を示す格納場所情報とが一致するか否かによって判断する機能を有する。
【００２２】
クラスローダ172は、アプリケーション111を実行するとき、必要とするクラスをアプリケーション111およびライブラリ112、113からロードする機能を有する。
【００２３】
また、クラスローダ172は、インタプリタ171から要求されたクラスが記憶部101に記憶されていない場合、参照元のクラスに対応する定義ファイルに記述されている参照先のクラスの格納場所情報で示される場所から参照先のクラスを記憶部101にロードする機能を有する。
【００２４】
また、クラスローダ172は、ロードしたクラスの完全修飾クラス名が記憶部102に記憶されていれば（即ち、ロードしたクラスの完全修飾クラス名が既にロード済みの他のクラスの完全修飾クラス名と競合していれば）、記憶部101にロードした当該クラスのバイトコードに出現する、当該クラスの完全修飾クラス名におけるパッケージ名を、異なるパッケージ名に変更すると共に、当該クラスの参照元のクラスのバイトコードに出現する、当該クラスの完全修飾クラス名におけるパッケージ名を、上記異なるパッケージ名に変更する機能を有する。
【００２５】
また、クラスローダ172は、ロードしたクラスに関して、当該クラスの完全修飾クラス名が記憶部102に記憶されていなかったならば、当該クラスの完全修飾クラス名とロード元を示す格納場所情報とを含み、変更前パッケージ名は有しない組を記憶部102に記憶し、当該クラスの完全修飾クラス名が記憶部102に記憶されていたならば、当該クラスのパッケージ名変更後の完全修飾クラス名とロード元を示す格納場所情報と変更前パッケージ名との組を記憶部102に記憶する機能を有する。
【００２６】
また好ましくは、クラスローダ172は、ロードしたクラスが参照する他のクラスに関して、当該他のクラスの完全修飾クラス名と同一となる変更前完全修飾クラス名に相当する完全修飾クラス名と変更前パッケージ名とを含む組であって、当該組の格納場所情報が当該ロードしたクラスの定義ファイルに記述されている当該他のクラスのロード元を示す格納場所情報と一致する組が存在するか否かを判断し、存在する場合、当該ロードしたクラスのバイトコードに出現する、参照している当該他のクラスの完全修飾クラス名を、上記存在した組における完全修飾クラス名に変更する機能を有する。但し、或るクラスが参照（依存）するクラスが、当該或るクラスのロード後にロードされる構成では、当該機能は省略してよい。
【００２７】
通信I/F部（通信インターフェース部）106は、専用のデータ通信回路からなり、通信回線を介して接続された各種装置との間でデータ通信を行う機能を有している。操作入力部107は、キーボードやマウスなどの操作入力装置からなり、オペレータの操作を検出してプロセッサ105に出力する機能を有している。画面表示部108は、LCDやPDPなどの画面表示装置からなり、プロセッサ105からの指示に応じて、各種情報を画面表示する機能を有している。
【００２８】
図２は、本実施形態におけるアプリケーションの実行手順の一例を示すフローチャートである。以下、図２のフローチャートを参照してアプリケーション111の実行手順の概要を説明する。
【００２９】
まずクラスローダ172は、アプリケーション111から最初に呼び出すクラス（アプリケーションクラス）を記憶部101にロードする（ステップS101）。次に、インタプリタ171は、実行するクラスを記憶部101から読み出し、解釈および実行する（ステップS102）。次に、インタプリタ171は、アプリケーション111が終了したか否かを判定し（ステップS103）、終了したら図２に示す実行手順を終了する。
【００３０】
アプリケーション111が終了していない場合、インタプリタ171は、次の実行に必要なクラスが、記憶部101にロードされているか否かを判定する（ステップS104）。この判定方法の詳細については後述する。ロード済みの場合、インタプリタ171は、記憶部101からクラスを読み出して解釈および実行を行うステップS102に戻る。
【００３１】
他方、必要なクラスがロード済でない場合、インタプリタ171は、クラスローダ172に対して当該必要なクラスのロードを要求する（ステップS105）。クラスローダ172は、この要求を受けて、要求されたクラスをライブラリ130、140等から記憶部101にロードする（ステップS106）。このロード時の詳細な動作は後述する。そして、そのクラスのロードが完了すると、ステップS102に戻り、インタプリタ171がそのクラスを解釈および実行する。
【００３２】
次に、以下の事項を前提として、本実施形態の動作を詳細に説明する。
【００３３】
・ライブラリ112のパッケージ名はcom.abc、クラス141のクラス名はBとする。ライブラリ112は、フォルダlib配下に存在する、ファイル名が/lib/L1-1のフォルダに記憶されている。
・ライブラリ113のパッケージ名はcom.abc、クラス151のクラス名はBとする。即ち、ライブラリ112、113のクラス141、151は同じ完全修飾クラス名を持つ。このような例は、ライブラリ112、113がバージョンのみ相違するような場合にしばしば発生する。ライブラリ113は、フォルダlib配下に存在する、ファイル名が/lib/L1-2のフォルダに記憶されている。
・定義ファイル131は、クラス121がライブラリ112を使用することを、ライブラリ112の格納場所を示すファイル名/lib/L1-1をクラスパスとして記述することで明らかにしている。
・定義ファイル132は、クラス122がライブラリ113を使用することを、ライブラリ113の格納場所を示すファイル名/lib/L1-2をクラスパスとして記述することで明らかにしている。
・定義ファイル133は、クラス123がライブラリ113を使用することを、ライブラリ113の格納場所を示すファイル名/lib/L1-2をクラスパスとして記述することで明らかにしている。
・アプリケーション111の実行が既に開始されており、記憶部101、102の内容は図３に示すようになっているものとする。即ち、クラス121、このクラス121が使用するライブラリ112のクラス141、および、クラス122が、記憶部101にロードされており、記憶部102にクラス121、141、122の完全修飾クラス名とその格納場所情報との組が記憶されている。また、これらロード済のクラスのパッケージ名の変更は行われていないため、変更前パッケージ名は何れもNULLである。
【００３４】
以上の前提の下、インタプリタ171がクラス122の実行に必要なライブラリ113のクラス151が記憶部101に記憶されているか否かを判断する場面から、本実施形態の動作を詳細に説明する。
【００３５】
インタプリタ171は、ステップS104において、クラス122のバイトコード上に出現している、参照するライブラリ113のクラス151の完全修飾クラス名com.abc.Bで記憶部102を検索すると、ライブラリ112のクラス141の完全修飾クラス名com.abc.Bを発見する。次に、インタプリタ171は、ステップS104において、この発見した完全修飾クラス名com.abc.Bに対応して記憶部102に記憶されているクラス141の格納場所情報であるファイル名/lib/L1-1と、クラス122に対応する定義ファイル132に記述されているライブラリ113の格納場所情報であるファイル名/lib/L1-2とを比較する。この結果、双方のファイル名が相違するので、インタプリタ171は、クラス122の実行に必要なライブラリ113のクラス151は記憶部101にロードされていないと判断し、ステップS105において、クラスローダ172に対して、クラス122から参照しているクラス151の完全修飾クラス名com.abc.Bを指定してロードを要求する。
【００３６】
クラスローダ172は、クラス122に対応する定義ファイル132に記述されているファイル名/lib/L1-2のファイルから、ライブラリ113のクラス151を読み出して、図４に示すように記憶部101にロードする。
【００３７】
次にクラスローダ172は、クラス151の完全修飾クラス名com.abc.Bが既に記憶部102に記憶されているので、クラス151の完全修飾クラス名のパッケージ名を、競合が解消される別のパッケージ名に変更する。ここでは、例えば、パッケージ名Xに変更したものとする。
【００３８】
次にクラスローダ172は、記憶部101にロードしたライブライ113のクラス151のバイトコードに出現する完全修飾クラス名com.abc.Bを、図４に示すようにcom.abc.Xに変更する。また、クラスローダ172は、記憶部101にロードされている、クラス151を参照するクラス122のバイトコードに出現する完全修飾クラス名com.abc.Bを、図４に示すように、com.abc.Xに変更する。これによって、クラス122とクラス151との間の参照関係が維持される。
【００３９】
次にクラスローダ172は、記憶部101にロードしたライブラリ113のクラス151に関して、当該クラス151の完全修飾クラス名com.abc.Bと同一の完全修飾クラス名が記憶部102に記憶されていたので、図４に示すように、クラス151のパッケージ名変更後の完全修飾クラス名com.abc.Xと格納場所情報であるファイル名/lib/L1-2と変更前パッケージ名Bとの組を記憶部102に記憶する。そして、クラスローダ172は、制御をインタプリタ171に戻す。
【００４０】
インタプリタ171は、再び、クラス122が利用するライブラリ113のクラス151の完全修飾クラス名com.abc.Xで記憶部102を検索すると、ライブラリ113のクラス151の完全修飾クラス名com.abc.Xを発見する。次に、インタプリタ171は、この発見した完全修飾クラス名com.abc.Xに対応して記憶部102に記憶されているクラス151の格納場所情報であるファイル名/lib/L1-2と、クラス122に対応する定義ファイル132に記述されているライブラリ113の格納場所情報であるファイル名/lib/L1-2とを比較する。この結果、双方のファイル名が一致するので、インタプリタ171は、クラス122の実行に必要なライブラリ113のクラス151は記憶部101にロードされていると判断し、その実行を行う。これによって、クラス122からライブラリ113のクラス151を利用することができる。
【００４１】
次に、パッケージ名を動的に変更されたライブラリ113のクラス151を参照するクラス123が、その後にロードされた時の動作を説明する。
【００４２】
クラスローダ172は、アプリケーション111のクラス123を図５に示すように記憶部101にロードすると、ロードしたクラス123が参照している他のクラス毎に、以下の処理を行う。
【００４３】
まずクラスローダ172は、クラス123が参照している他のクラスの完全修飾クラス名と同一の完全修飾クラス名になる変更前完全修飾クラス名に相当する完全修飾クラス名と変更前パッケージ名とを含む組が記憶部102に存在するか否かを調べる。ここで、記憶部102には、完全修飾クラス名と、それがパッケージ名を変更したものである場合には変更前のパッケージ名とが記憶されているため、完全修飾クラス名中のパッケージ名を変更前のパッケージ名に置き換えれば、変更前の完全修飾クラス名になる。
【００４４】
次にクラスローダ172は、上記のような組が記憶部102に記憶されている場合、当該組の格納場所情報がクラス123の定義ファイルに記述されている当該他のクラスのロード元を示す格納場所情報と一致するか否かを判断する。一致した場合、クラス123が参照している当該他のクラスは、パッケージ名を変更して記憶部101にロードされていることになる。そこで、クラスローダ172は、記憶部101上のクラス123のバイトコードに出現する、参照している当該他のクラスの完全修飾クラス名を、上記組における完全修飾クラス名に変更する。例えば、クラス123がライブラリ113のクラス151を参照している場合、クラス151の完全修飾クラス名は、図５に示すように、記憶部101上でcom.abc.Bからcom.abc.Xに変更されているので、それを参照するクラス123のバイトコードに出現するクラス151の完全修飾クラス名com.abc.Bを、図５に示すようにcom.abc.Xに変更する。これにより、パッケージ名を変更して記憶部101にロードされているライブラリ113のクラス151を参照するクラス123が、クラス151の後にロードされる場合であっても、クラス123とクラス151との参照関係が維持される。
【００４５】
このように本実施形態によれば、事前にパッケージ名を書き換えることなく、同じ完全修飾クラス名を持つ複数のクラスを一つのアプリケーションで使用することができる。このため、同じ完全修飾クラス名を持つ複数のクラスが、ライブラリクラスの場合、事前にライブラリを書き換えることなく、同じ完全修飾クラス名を持つ複数のライブラリを一つのアプリケーションで使用することができる。
【００４６】
本実施形態では、ライブラリ112、113にはそれぞれ１つのクラス141、151しか格納されていないが、それぞれ複数のクラスが格納されていてよい。また、ライブラリ113に格納されるクラス151以外のクラスのうち、ライブラリ112に格納されるクラスと完全修飾クラス名が競合するクラスについては、クラス151のロード時と同様にパッケージ名の動的な変更が行われる。また、ライブラリ113に格納されるクラス151以外のクラスのうち、ライブラリ112に格納されるクラスと完全修飾クラス名が競合しないクラスについては、パッケージ名の動的な変更は必要ないが、クラス151と同様にパッケージ名を変更してもよい。
【００４７】
次に本発明の他の実施形態について説明する。
【００４８】
[第２の実施形態]
[本実施形態が解決しようとする課題]
近年様々なコミュニティでオープンソースソフトウェア(OSS)の開発が盛んに行われており、ソフトウェア開発においてもそれらのソースコードの一部を使用したり、様々なライブラリ（成果物）を利用する機会が増えてきた。特にアプリケーションサーバでは、サーバ自体がそういったOSSのライブラリを使用するうえに、アプリケーションごとに使用するライブラリのバージョンが異なったりする構成をプロセス上で実行することがあるため、ライブラリの競合が問題となってきている。
【００４９】
この問題に対する解決手段として、手動でパッケージ名を静的に変更することが考えられる。この方法は非常に有効な手段ではあるが、元となるOSSのバージョンアップの取り込みなど、OSSからの差分修正を取り込んだり修正を行うたびに考慮しなければならないこと、また変更量が莫大になってしまうことがあり、開発者による手動ではなく、動的に完全修飾クラス名の競合を回避する手段が望まれていた。
【００５０】
[本実施形態の概要]
オブジェクト指向言語において、クラスのパッケージ名の別名をあらかじめ定義しておき、クラスローダによるロードにおいて完全修飾クラス名の競合が発生した場合に動的に変更することで競合を回避して、同じ完全修飾クラス名を持つクラスを1つのクラスローダツリー上で同時に複数ロードすることを可能とする。
【００５１】
またそれらのクラスを使用するプログラムでは、ロード時に参照先パッケージ名を書き換えることで参照関係を保つ。
【００５２】
このように本実施形態では、完全修飾クラス名の競合が発生したときに、競合したクラスのパッケージ名を動的に変えることで解決する。変更するパッケージ名はあらかじめライブラリの定義ファイルに命名規則として定義しておき、その規則にしたがってロード時に置き換える。そのクラスを参照するクラスでは、クラスパスやライブラリの定義ファイルから依存していることを調べて、ロード時にバイトコード内の参照先パッケージ名を変更して参照関係を解決する。
【００５３】
本実施形態では、プログラムAにおいて、クラスP1がライブラリL1-1を使用し、クラスP2がライブラリL1-2を競合を回避して使用する例を示す。
【００５４】
[本実施形態の構成]
本実施形態の構成図を図６に示す。図６を参照すると、アプリケーションプログラムがクラスP1,P2から構成されており（そのようなアプリケーションプログラムをAとする）、クラスP1はライブラリL1-1のAPIを呼び出して処理を行い、クラスP2はライブラリL1-2のAPIを呼び出して処理を行う。それぞれのクラスでは、そのクラスの定義ファイル内でクラスパスとしてライブラリL1-1とライブラリL1-2をそれぞれファイル名で指定しており、P1とL1-1、P2とL1-2はそれぞれ独立した環境では実行可能とする。
【００５５】
ライブラリL1-1とライブラリL1-2は、ライブラリL1のバージョン１とバージョン2で、ほぼ同じ機能を提供する。これらは内部的にもほぼ同じパッケージ名・クラス名構成で、同じフォルダF1（lib）に置かれている。ただし、ライブラリL1の定義ファイルには、パッケージの別名の命名規則が書かれている。図７は、ライブラリL1の定義ファイルの内容例である。この例では、ライブラリL1のパッケージの別名は、com.xyzである。
【００５６】
本実施形態にかかるクラスローダCLは、アプリケーションプログラムA用に定義されている。クラスローダCLは、ロード済ライブラリ一覧LT1と変更履歴表T1との２種類の制御テーブルを参照更新して、アプリケーションAの実行に必要なクラスのロードを行う。また本実施形態では、クラスローダCLが第１の実施形態におけるインタプリタ171の機能を兼ね備えているものとして説明する。
【００５７】
ロード済ライブラリ一覧LT1は、メモリにロードされているクラスの完全修飾クラス名とそのロード元を示す格納場所の情報との組を記録するテーブルである。また、変更履歴表T1は、メモリにロードされているクラスのロード元を示す格納場所とそのクラスの変更前パッケージ名との組を記録するテーブルである。これらのテーブルT1,LT1は、第１の実施形態における記憶部102に相当する。
【００５８】
[本実施形態の動作]
プログラムAでクラスP1が実行されると、クラスローダCLはクラスP1の定義ファイルを確認し、依存するライブラリL1-1をロードして実行を完了する。
【００５９】
さらに同プロセス内でクラスP2が実行されると、従来ではクラスローダCLがL1-2をロードしようとするが、ライブラリの完全修飾クラス名の競合のためエラーとなって終了する。本実施形態では、この課題を以下のように解決する。
【００６０】
プログラムAでクラスP1が実行されたとき、クラスローダCLはライブラリL1-1をロードする。ロードが完了した時点で、ロード済みライブラリ一覧LT1にライブラリの完全修飾クラス名を追加する。
【００６１】
プログラムAでクラスP2が実行されたとき、クラスローダCLはライブラリL1-2のロードを行う。このときロード中にライブラリL1-2内のクラスとロード済みライブラリ一覧LT1とを突き合わせて、完全修飾クラス名の競合を確認する。本実施形態ではこのとき競合が発生するので、以降ではライブラリL1-2のパッケージ名の変更を試みる。
【００６２】
クラスローダCLは、ライブラリL1-2内の定義ファイルを確認し、パッケージの命名規則を見つける。見つかった命名規則を用いてライブラリL1-2に含まれるクラスのパッケージ名をロードしながらメモリ上で変更する。Javaの場合、仮想マシン仕様によると、パッケージ名はバイトコード内で完全修飾クラス名に展開されているので、バイトコードをロードしたときにライブラリL1-2のパッケージ名がclass宣言のクラス名、クラスファイルの位置、そして各クラスファイル内の相互参照箇所に現れた場合、それらを命名規則にしたがって置換する。
【００６３】
そしてクラスローダCLは、ライブラリL1-2のファイル名と命名規則とを変更記録表T1に追加する。また、クラスローダCLはパッケージ名変更後のライブラリ内のクラスファイル名を、ロード済みライブラリ一覧LT1に追加する。
【００６４】
クラスローダCLは、他のライブラリをロードするたびに変更記録表T1とそのライブラリの定義ファイルを確認し、それがライブラリL1-2を参照するかを調べる。参照している場合、ライブラリロード時にライブラリL1-2への参照パッケージ名を、変更後のパッケージ名にあわせるように書き換える。
【００６５】
変更記録表T1の例を図８に示す。図８の１行目は、パッケージ名変更後のライブラリ内のクラスファイル名./lib/L1-2に格納されているクラスは、パッケージ名がcom.xyzに変更されていることを表している。２行目以降は、図６には表れていない別のクラスの変更記録を示す。
【００６６】
本実施形態のクラスローダLCの処理の流れを図９に示す。クラスローダLCは、或るクラスをロードすると（ステップS201）、当該クラスの定義ファイルに記述されている依存ライブラリのファイル名の確認を行い（ステップS201）、当該クラスの完全修飾クラス名とロード済みライブラリ一覧LT1中の完全修飾クラス名との比較結果、および当該クラスの依存ライブラリのファイル名とロード済みライブラリ一覧LT1中のファイル名との比較の結果に基づき、依存するライブラリがロード済か否かを判断する（S203）。
【００６７】
依存するライブラリがロード済みでなければ、当該依存するライブラリのクラスの完全修飾クラス名を確認し（ステップS204）、そのライブラリのクラスのロードを行う（ステップS205）。そして、ステップS205でロードしたライブラリクラスの完全修飾クラス名が既にロードされているライブラリクラスの完全修飾クラス名と競合したか否かを判定する（ステップS206）。競合していなければ、クラスの実行等の処理を行う（ステップS2139）。
【００６８】
ステップS205でロードしたライブラリクラスの完全修飾クラス名が他のクラスと競合している場合、ステップS205でロードしたライブラリの定義ファイルでパッケージ名の命名規則を確認し（ステップS207）、その命名規則を用いて当該ロードしたライブラリクラスのバイトコードに出現する、当該ロードしたライブラリクラスのパッケージ名の変更を行う（ステップS208）。次に、当該ロードしたライブラリクラスを参照（依存）している、既にロード済みのクラスのバイトコードに出現する、当該ロードしたライブラリクラスのパッケージ名を変更する（ステップS209）。そして、変更記録表T1にパッケージ名を変更したクラスのライブラリファイル名と命名規則とを追加する（ステップS210）。そして、クラスの実行等の処理を行う（ステップS2139）。
【００６９】
他方、ステップS201でロードしたクラスが依存するライブラリクラスがロード済みであれば、当該依存するライブラリクラスのパッケージ名が変更されているか否かを変更記録表T1に基づいて判断する（ステップS211）。そして、パッケージ名が変更されていれば、ステップS201でロードしたクラスのバイトコードに出現する、当該クラスが依存するクラスのパッケージ名を変更後のパッケージ名に変更する（ステップS212）。そして、ステップS201でロードしたクラスの事項等の処理を行う（ステップS213）。
【００７０】
[本実施形態の効果]
本実施形態によれば、ライブラリ間で完全修飾クラス名の競合が発生しても、実行時にパッケージ名を動的に置換することで競合を回避し、競合する両方のクラスの使用が可能となる。その結果、プログラム間で重複しないライブラリは共有でき、競合するライブラリは独立性が確保できる。
【００７１】
[第３の実施形態]
本実施形態は、ライブラリ内の定義ファイルに複数の別名を定義する例である。或る一つの別名に変更してもパッケージ名がなおも競合した場合に、さらに他の名前に変更して競合を回避する。
【００７２】
この場合、競合するライブラリ間で双方のパッケージ名の変更可能性を確認し、変更できる方のパッケージ名の変更と、参照する他のクラスとの参照関係の修正を行う。
【００７３】
命名規則を複数記述した定義ファイルの例を図１０に示す。この例では、com.xyzとcom.XYZとjp.coとの３つのパッケージ名の別名が定義されている。
【００７４】
[第４の実施形態]
本実施形態は、ライブラリ内の定義ファイルではなく、外部定義ファイルにパッケージ名の命名規則を定義する例である。
【００７５】
外部の定義ファイルに命名規則を定義することで、複数のライブラリの命名規則をまとめて定義することができ、また実行時にパッケージ名の変更によっても競合を解決できなかった場合に、ライブラリ本体の修正なしで容易に変更する手段を提供する。
【００７６】
外部設定ファイルには、ライブラリのファイルパス名と命名規則のペアとが表形式で書かれており、クラスローダは、完全修飾クラス名の競合を検知すると、外部設定ファイルを確認してからライブラリ内の設定ファイルを確認する。外部設定ファイルに対象となるライブラリの命名規則が書かれていた場合、ライブラリ内部の定義ファイルより優先してその命名規則を使用する。
【００７７】
本実施形態におけるクラスローダの処理の流れを図１１に示す。図９と相違する箇所は、ステップS301,S302である。
【００７８】
[第５の実施形態]
本実施形態は、パッケージ名の変更をライブラリ内の全クラスではなく、条件に合う一部のパッケージのみに対して行う例である。
【００７９】
ライブラリファイル内に複数の異なるパッケージが含まれているときに、命名規則に、置換対象とするパッケージ名の規則と置き換える先のパッケージ名のペアとを書くことで実現する。
【００８０】
本実施形態で使用するライブラリの定義ファイルの例を図１２に示す。図１２の命名規則では、=の左辺に置換対象(com.abc)を指定し、右辺に置換後のパッケージ名(com.xyz)を定義している。この命名規則を適用してパッケージ名を変更した変更イメージを図１３に示す。
【００８１】
[第６の実施形態]
本実施形態は、クラスローダが階層構成の委譲モデルの形を取っており、競合するライブラリL1-1,L1-2が異なるフォルダに置かれている場合の例である。
【００８２】
クラスローダが図１４に示すような階層構成をとっており、ライブラリL1-1とL1-2が異なるクラスローダCL1,CL2が見る場所にそれぞれ置かれている。CL1とCL2は親子関係になっており、CL1がCL2の親である。クラスP1、クラスP2の定義ファイルにはL1-1、L1-2のパスが書かれているものとする。
【００８３】
プログラムがクラスP1を実行するとき、クラスローダCL1がライブラリL1-1を探し、ロードする。クラスローダCL1は委譲モデルにより、システムクラスローダ、ブートストラップクラスローダまでさかのぼり、再びCL1まで戻ってCL1が見える場所に置かれているライブラリL1-1をロードするという動きとなる。
【００８４】
次にプログラムがクラスP2を実行すると、クラスローダCL2は、CL1,システムクラスローダ、ブートストラップクラスローダまでさかのぼり、CL1に戻ったところでパッケージ名から前のステップでロードされたL1-1を使用することとなる。しかし、クラスP2はL1-2を使うことを想定していたため、想定外のバージョンのライブラリを使用したことによりエラーとなってしまう。そこで、本実施形態ではこの問題を以下のように解決する。
【００８５】
(1)プログラムがクラスP1を実行するとき、クラスローダCL1ではライブラリL1-1をロードし、ロード済みライブラリ一覧LT1にライブラリのファイルパス名とパッケージ名を追加する。
(2)クラスP1を実行する
(3)プログラムがクラスP2を実行するとき、クラスP2の定義ファイルから、必要とするライブラリL1-2を確認し、またロード済みライブラリ一覧を確認して、ライブラリL1-1がロードされていることを確認する。その後、クラスローダCL2からクラスのロードを委譲していき、CL1でロードしたライブラリL1-1のパッケージは無視して、クラスの探索を続ける。そしてクラスローダCL2でライブラリL1-2をロードする。このときL1-1とL1-2でライブラリの競合が発生するので、パッケージ名の置換を行い、競合を回避する。パッケージ名の置換後、変更記録表T1に置換を行ったライブラリファイルパス名と命名規則を追加する。
(4)クラスP2を実行する。
【００８６】
以上本発明の実施形態について説明したが、本発明は以上の実施形態にのみ限定されず、その他各種の付加変更が可能である。
【産業上の利用可能性】
【００８７】
本発明は、Java等に代表されるオブジェクト指向言語で記述されたプログラムを実行する情報処理装置、特にアプリケーションサーバなどの基盤部分と他のアプリケーションが同プロセス上で実行され、複数のライブラリを使用する構成をとる情報処理装置に利用することができる。
【符号の説明】
【００８８】
101〜103…記憶部
104…記録媒体
105…プロセッサ
106…通信I/F部
107…操作入力部
108…画面表示部
111…アプリケーション
112、113…ライブラリ
121、122、123…アプリケーションのクラス
131、132、133…定義ファイル
141、151…ライブラリのクラス
161…Java仮想マシン
171…インタプリタ
172…クラスローダ
【図１】
0005895616.tif 000002
【図２】
0005895616.tif 000003
【図３】
0005895616.tif 000004
【図４】
0005895616.tif 000005
【図５】
0005895616.tif 000006
【図６】
0005895616.tif 000007
【図７】
0005895616.tif 000008
【図８】
0005895616.tif 000009
【図９】
0005895616.tif 000010
【図１０】
0005895616.tif 000011
【図１１】
0005895616.tif 000012
【図１２】
0005895616.tif 000013
【図１３】
0005895616.tif 000014
【図１４】
0005895616.tif 000015