図1は、本発明の実施の形態の概要を説明するための図である。本発明の実施の形態において、複合機10は、アプリケーションを追加可能な画像形成装置の一例である。図中、複合機10が上下に二つ記載されているが、これは同一の複合機10を時間の経過に応じて示したものである。
本実施の形態において、新たに複合機10にインストールされるアプリケーションについては、まず、仮起動が行われる(S11)。仮起動とは、アプリケーションによるリソースの消費量や、アプリケーションが利用する複合機10内のサービス(機能)等(これらを示す情報を、以下「アプリケーション動作情報」という。)を調査するためにアプリケーションを起動することをいう。本実施の形態において、仮起動されたアプリケーションは、当該アプリケーションの本来の機能をユーザに対して提供することはできない。仮起動の際中、複合機10は、アプリケーション動作情報を仮起動ログとして出力する(S12)。仮起動が終了すると、複合機10は、仮起動ログに基づいて仮起動の成否を判定する(S13)。仮起動の成功とは、仮起動されたアプリケーションの動作が、予め定められた制限(リソースの消費量や、利用する複合機10内のサービス等に関する制限)の範囲内であることが確認されたことをいう。仮起動の失敗とは、仮起動されたアプリケーションの動作が、予め定められた制限に従っていないことが確認されたことをいう。
仮起動が成功すると、当該アプリケーションは複合機10にインストールされ、本起動が可能な状態となる。したがって、ユーザから起動指示があった場合は、本起動が行われる(S14)。本起動とは、仮起動に対する用語であり、アプリケーション本来の機能を発揮させるためにアプリケーションを起動するこという。すなわち、本起動によって、アプリケーションの通常の使用状態が実現される。本起動の際、複合機10は、仮起動ログに基づいて、アプリケーションの動作を制御する。例えば、アプリケーションの起動を拒否したり、アプリケーションの起動のタイミングを制限したり、アプリケーションの状態遷移(処理の進行)を制限したり、アプリケーションによる複合機10のサービスの使用を制限したりする。
以上のように、複合機10では、新たに追加(インストール)されるアプリケーションについて、予め仮起動を行い、仮起動の際に取得される仮起動ログに基づいて本起動の際の動作を制御することができる。したがって、予め定められたリソースの消費量等に関する制限を遵守していないアプリケーションの動作を制限したり、複数のアプリケーションが同時に(並列的に)起動された際において、各アプリケーションのリソースの消費のタイミングを制御したりすることが可能となる。
以下、具体的に説明する。図2は、本発明の実施の形態における複合機のハードウェア構成例を示す図である。図2において複合機10は、コントローラ201、オペレーションパネル202、ファクシミリコントロールユニット(FCU)203、撮像部121、及び印刷部122等を備える。
コントローラ201は、CPU211、ASIC212、NB221、SB222、MEM−P231、MEM−C232、HDD(ハードディスクドライブ)233、メモリカードスロット234、NIC(ネットワークインタフェースコントローラ)241、USBデバイス242、IEEE1394デバイス243、セントロニクスデバイス244により構成される。
CPU211は、種々の情報処理用のICである。ASIC212は、種々の画像処理用のICである。NB221は、コントローラ201のノースブリッジである。SB222は、コントローラ201のサウスブリッジである。MEM−P231は、複合機10のシステムメモリである。MEM−C232は、複合機10のローカルメモリである。HDD233は、複合機10のストレージである。メモリカードスロット234は、メモリカード235をセットするためのスロットである。NIC241は、MACアドレスによるネットワーク通信用のコントローラである。USBデバイス242は、USB規格の接続端子を提供するためのデバイスである。IEEE1394デバイス243は、IEEE1394規格の接続端子を提供するためのデバイスである。セントロニクスデバイス244は、セントロニクス仕様の接続端子を提供するためのデバイスである。
オペレーションパネル202は、オペレータが複合機10に入力を行うためのハードウェア(操作部)であると共に、オペレータが複合機10から出力を得るためのハードウェア(表示部)である。
図3は、本発明の実施の形態における複合機のソフトウェア構成例を示す図である。図3において、複合機10のソウトウェアは、JSDKアプリ30、JSDKプラットフォーム40、リクエスト経路制御部50、及びネイティブサービスレイヤ60等より構成されている。これらの各ソフトウェアは、メモリカード235やその他の記憶装置に記録されたプログラムがCPU211によって処理されることにより機能する。
ネイティブサービスレイヤ60は、複合機10のハードウェアやソフトウェアに基づく機能を利用させるためのインタフェースを上位モジュールに対して提供し、当該インタフェースの呼び出し(機能の利用要求)に応じて、当該機能を実現するための制御を行う。例えば、ネイティブサービスレイヤ60には、ネットワーク通信の制御に関するインタフェースを提供するモジュール、ファクシミリの制御に関するインタフェースを提供するモジュール、蓄積文書(HDD233に保存されている文書(画像)データ)の配信処理の制御に関するインタフェースを提供するモジュール、撮像部121や印刷部122の制御に関するインタフェースを提供するモジュール。メモリやHDD233等の制御に関するインタフェースを提供するモジュール、オペレーションパネル202の制御に関するインタフェースを提供するモジュール、認証処理や課金処理の制御に関するインタフェースを提供するモジュール、ユーザ情報の管理に関するインタフェースを提供するモジュール等が含まれる。
JSDKプラットフォーム40は、JSDKアプリ30の実行環境を提供するソフトウェアプラットフォームであり、ネイティブサービスレイヤ60に対するJava(登録商標)インタフェースを上位モジュールに対して提供する。JSDKプラットフォーム40は、Java(登録商標)の標準のクラスや、複合機10用に拡張されたクラスに関するクラスライブラリ、及びJava(登録商標)仮想マシン等を含む。例えば、図中では、JSDKプラットフォーム40の一部として、セキュリティマネージャ41やロギングサービス42が示されている。
セキュリティマネージャ41は、予めポリシーファイルに定義されたアクセス制御情報に基づいて、JSDKアプリ30による、ファイル、ネットワークソケット、及びプリンタ等のリソースへのアクセスを制限する。すなわち、JSDKプラットフォーム40は、リソースへのアクセスが発生する際に、セキュリティマネージャ41に対する呼び出しが発生するように構成されている。セキュリティマネージャ41は、その呼び出しに応じてリソースへのアクセスの可否を判断する。なお、セキュリティマネージャ41は、Java(登録商標)の標準におけるSecurityManagerクラスを用いて実現してもよい。
ロギングサービス42は、JSDKアプリ30の仮起動の際に、仮起動ログ80を出力する。
なお、JSDKプラットフォーム40は、OSGi(Open Service Gateway initiative)プラットフォームとして実装されている。OSGi(Open Service Gateway initiative)プラットフォームとは、OSGiアライアンスによる標準化技術であり、Java(登録商標)言語に基づいたオープンなソフトウェア部品化技術に基づいて作成されたソフトウェア部品の実行環境を提供するソフトウェアプラットフォームである。OSGiプラットフォーム上において、Java(登録商標)言語のソフトウェアは「バンドル」と呼ばれるソフトウェア部品の形で実装される。一つのバンドルは、一つのJAR(Java ARchive)ファイルによって構成され、それぞれ独立して動的に(装置の再起動を要することなく)インストール可能である。
JSDKアプリ30は、JSDKプラットフォーム40において公開されている専用のSDK(ソフトウェア開発キット)を使用して作成されたアプリケーション(以下「SDKアプリ」という。)である。SDKアプリのうち、特にJava(登録商標)を言語を使用して開発されたアプリケーションをJSDKアプリといい、本実施の形態において仮起動の対象とされる。
図中では、JSDKアプリ30の例として、SAS(SDK Application Service)マネージャ31、アプリケーションバンドル32、及びサービスバンドル33等が存在する。SASマネージャ31は、他のJSDKアプリ30(アプリケーションバンドル32やサービスバンドル33等)のインストール(追加)、アンインストール(削除)、起動、及び起動解除等の制御を行う。
アプリケーションバンドル32は、オペレーションパネル202に操作画面を表示させ、当該操作画面を介してエンドユーザから直接利用(操作)されるJSDKアプリ30としてのバンドルである。図中では、アプリケーションバンドル32の一例としてスキャンアプリ321が示されている。スキャンアプリ321は、撮像部121による原稿からの画像の読み取りを実現するアプリケーションである。
サービスバンドル33は、アプリケーションバンドル32等に対してサービスを提供するためのJSDKアプリ30としてのバンドルである。すなわち、サービスバンドル33は、アプリケーションバンドル32等からの呼び出しに応じて各サービスバンドル33に応じた処理を実行し、その処理結果をアプリケーションバンドル32等に返却する。図中では、サービスバンドル33の一例として、スキャンサービス331、パネルサービス332、及び仮起動サービス333等が示されている。
スキャンサービス331は、画像の読み取り機能に関するサービスを提供する。パネルサービス332は、オペレーションパネル202の表示制御に関するサービスを提供する。仮起動サービス333は、仮起動スクリプト70の記述内容に基づいて仮起動の処理制御に関するサービスを提供する。仮起動スクリプト70の詳細については後述する。
なお、本実施の形態において、アプリケーションバンドル32やサービスバンドル33等のアプリケーションは、init状態→pause状態→active状態→destroy状態の順で状態が遷移する(処理が進行する)状態遷移モデルに従って動作する。init状態は、初期状態であり、初期処理等が行われる。起動直後のアプリケーションは、まず、init状態に遷移する。pause状態は、待機状態である。pause状態のアプリケーションは、実行可能となるまで待機する。active状態は、アプリケーション本来の機能が実行される状態である。destroy状態は、終了状態である。終了するアプリケーションは、destroy状態に遷移し、終了化処理(リソースの開放等)を行った後、終了する。
斯かる状態遷移モデルを実現するため、アプリケーションバンドル32やサービスバンドル33は、次のように構成される。図4は、アプリケーションバンドルやサービスバンドルの状態遷移モデルの実装例を示す図である。図4に示されるように、アプリケーションバンドル32やサービスバンドル33(図4の説明においては、「アプリケーションバンドル32等」という。)は、状態ごとにインスタンス化されたオブジェクトによって構成される。すなわち、init状態、pause状態、active状態、destroy状態に対応させて、init状態オブジェクト341、pause状態オブジェクト342、active状態オブジェクト343、destroy状態オブジェクト344がインスタンス化される。
アプリケーションバンドル32等は、状態遷移を発生させるイベント(メッセージ)を受けると、遷移元のオブジェクトから遷移先のオブジェクトへと処理の制御(当該アプリケーションの制御)を移動させる。例えば、init状態オブジェクト341からpause状態オブジェクト342へ処理の制御が移動する。この制御の移動によって状態の遷移が実現される。
なお、アプリケーションバンドル32等が状態遷移モデルに従って動作することは、本発明を適用するために、アプリケーションが或る状態遷移モデルに従って実装されなければならないことを意図するものではない。
リクエスト経路制御部50は、JSDKアプリ30によるネイティブサービスレイヤ60に対する要求(所定の機能の利用要求)を監視し、当該要求の発行元のJSDKアプリ30が、仮起動中であるか否かに応じて、当該要求の通知経路を制御する。すなわち、仮起動中であるJSDKアプリ30からの要求については、仮起動サービス333に通知し、仮起動中でない(本起動中)のJSDKアプリ30からの要求については、ネイティブサービスレイヤ60に通知する。
図5は、リクエスト経路制御部の主な機能を説明するための図である。図5中、図3と同一部分には同一符号を付している。図5において、アプリA322は、本起動されているアプリケーションバンドル32である。アプリB323は、仮起動されているアプリケーションバンドル32である。図中に示されるように、リクエスト経路制御部50は、本起動されているアプリA322に関しては、JSDKプラットフォーム40を介して行われるネイティブサービスレイヤ60に対する呼び出しを通過させる(S21)。したがって、この場合、ネイティブサービスレイヤ60による制御により、複合機10が実際に動作する。
一方、リクエスト経路制御部50は、仮起動されているアプリB323に関しては、JSDKプラットフォーム40を介して行われるネイティブサービスレイヤ60に対する呼び出しをネイティブサービスレイヤ60には通知せず、仮起動サービス333に対して通知する(S22)。この場合、仮起動サービス333は、擬似的にネイティブサービスレイヤ60のように振る舞い、その結果をアプリB323に対してネイティブサービスレイヤ60と同じ形式で応答する。したがって、アプリB323からは、ネイティブサービスレイヤ60が正常に呼び出され、その機能が実行されたように見える。このように、仮起動の際は、リクエスト経路制御部50によってネイティブサービスレイヤ60以下を機能させずに(すなわち、実際に複合機10を動作させずに)、JSDKアプリ30の検証が行われる。
次に、仮起動スクリプト70及び仮起動サービス333の詳細について説明する。図6は、仮起動スクリプト及び仮起動サービスを説明するための図である。
図6に示されるように、仮起動スクリプト70は、メインスクリプト71、シナリオスクリプト72、及び振る舞いスクリプト73の三つのスクリプトファイルより構成される。メインスクリプト71には、仮起動に使用するシナリオスクリプト72及び振る舞いスクリプト73を特定するための情報や仮起動の成否の判断基準等が定義される。シナリオスクリプト72には、仮起動のシナリオが定義される。シナリオとは、仮起動されるアプリケーションに対するオペレーションパネル202を介した操作手順をいう。振る舞いスクリプト73には、リクエスト経路制御部50によって仮起動サービス333に通知されたネイティブサービスレイヤ60の呼び出しに対する振る舞い(エミュレーションの内容)が定義される。
メインスクリプト71は、仮起動サービス333によって解釈される。したがって、仮起動サービス333は、メインスクリプト71に従って仮起動を制御する。仮起動サービス333は、シナリオスクリプト72を解釈するためのスレッド(シナリオサービス334)と、振る舞いスクリプト73を解釈するためのスレッド(振る舞いサービス335)を生成する。
シナリオサービス334は、シナリオスクリプト72に従って、仮起動中のアプリケーションに対する操作指示を入力する擬似的な操作者として機能する。シナリオサービス334の操作指示に応じて発生する当該アプリケーションに基づくネイティブサービスレイヤ60の呼び出しは、リクエスト経路制御部50によって振る舞いサービス335に通知される。振る舞いサービス335は、振る舞いスクリプト73の定義に従って、通知された呼び出しに対するエミュレーションを行い、その結果として、ネイティブサービスレイヤ60と同じ形式の応答を行う。ネイティブサービスレイヤ60と同じ形式の応答が行われることで、アプリケーションからは、ネイティブサービスレイヤ60が呼び出されたように見える。
以下、複合機10の処理手順について説明する。図7は、第一の実施の形態における複合機の仮起動に関する処理手順を説明するためのシーケンス図である。
アプリケーションのインストールが指示されると、SASマネージャ31は、複合機10本体のメモリカードスロット234に挿入されているSDカードに記録されているアプリケーション管理ファイルを検索し、検索された全てのアプリケーション管理ファイルをSDカード内より取り出す(S101)。ここで、アプリケーション管理ファイルとは、アプリケーションの構成要素やインストール等に必要な情報、及びその他の管理情報等(以下、「アプリケーション情報」という。)が記録されているファイルである。アプリケーション管理ファイルは、アプリケーションごとに添付されている。したがって、SDカード内に複数のJSDKアプリ30が記録されている場合は、複数のアプリケーション管理ファイルが取り出される。
例えば、図8は、スキャンアプリのアプリケーション管理ファイルに記録されているアプリケーション情報の例を示す図である。図8に示されるアプリケーション情報410は、XML(eXtensible Markup Language)形式をベースとしたJNLP(Java Network Launching Protocol(JSR−56仕様))を拡張した形式によって表現されている。
アプリケーション情報410は、主に、<information>タグで囲まれたinformation要素411、<rsource>タグで囲まれたresource要素412、<pseudo−boot>タグで囲まれたpseudo−boot要素413、<xlet−desc>タグで囲まれたxlet要素414等より構成される。
information要素411には、主に、アプリケーション(スキャンアプリ321)を識別するための情報が記録されている。例えば、product−id要素4111にはスキャンアプリ321のプロダクトIDが、title要素4112にはスキャンアプリ321のタイトル(アプリケーション名)が、vendor要素4113にはスキャンアプリ321の開発ベンダ名(記述4113)が記録されている。
resource要素412には、スキャンアプリ321の実行に必要なリソースに関する情報が記録されている。例えば、jar要素4121のhref属性の値として、スキャンアプリ321のJARファイルのファイル名(パス名)が記録されている。
pseudo−boot要素413には仮起動に関する情報が定義されている。例えば、pseudo−boot要素413のtrigger属性4131の値には、仮起動を実行するタイミングが指定されている。図中の例では「install」とされている。これは、スキャンアプリ321のインストール時に仮起動を実行することを示す。また、platform属性4132の値には、仮起動を行うプラットフォームが指定されている。図中の例では「same」とされている。これは、本起動と同一のプラットフォーム上で仮起動が実行されることを示す。また、pb要素4133のhref属性の値として、スキャンアプリ321の仮起動スクリプト70のメインスクリプト71のファイル名(「ScanApp.pb」)が指定されている。なお、pseudo−boot要素413は、仮起動が必要とされる場合に記録されている。したがって、pseudo−boot要素413の有無に応じて、仮起動の要否を判断することができる。
xlet要素414のvisible属性4141の値には、スキャンアプリ321がオペレーションパネル202に画面表示を行うか否かが記録されている。図中の例では「visible」とされている。これは、スキャンアプリ321が画面表示を行うことを意味する。
なお、図8は、スキャンアプリ321のアプリケーション情報の例を示すものであるが、他のアプリケーションについても、同様の形式によってアプリケーション情報が定義される。
続いて、SASマネージャ31は、取得されたアプリケーション管理ファイルに基づいて、複合機10にインストール可能なアプリケーションを判定し、インストール可能とされたアプリケーションの一覧(例えば、アプリケーション名の一覧)をオペレーションパネル202に表示させる(S102、S103)。
操作者は、オペレーションパネル202に表示されたアプリケーションの一覧の中から、インストールを行うアプリケーションを選択する。ここでは、スキャンアプリ321が選択されたこととする。スキャンアプリ321が選択されることにより、スキャンアプリ321のインストールの開始要求がSASマネージャ31に通知される(S104)。
SASマネージャ31は、インストールの開始要求に応じ、スキャンアプリ321のアプリケーション管理ファイルの内容(アプリケーション情報410)に従って、スキャンアプリ321のインストールをJSDKプラットフォーム40に要求する(S105)。JSDKプラットフォーム40は、スキャンアプリ321をバンドルとしてインストールする(S106)。
続いて、SASマネージャ31は、アプリケーション情報410に仮起動の指示(pseudo−boot要素413)が記録されているか否かを確認し、当該指示が記録されている場合は、スキャンアプリ321の仮起動を開始する(S107)。仮起動サービス333が起動されていない場合、SASマネージャ31は、仮起動サービス333の起動を開始する(S108)。まず、SASマネージャ31が、JSDKプラットフォーム40に対して仮起動サービス333のインストール要求を行うと(S109)、JSDKプラットフォーム40は、仮起動サービス333をインストールする(S110)。続いて、SASマネージャ31が、JSDKプラットフォーム40に対して仮起動サービス333の起動要求を行うと(S111)、JSDKプラットフォーム40は、仮起動サービス333を起動する(S112)。
仮起動サービス333は、起動されると自ら(仮起動サービス333)が提供できるサービスのインタフェース情報をJSDKプラットフォーム40に登録する(S113)。続いて、仮起動サービス333は、リクエスト経路制御部50のインタフェース情報をJSDKプラットフォーム333より取得する(S114)。ここで、インタフェース情報とは、リクエスト経路制御部50を呼び出すために必要とされる情報をいう。なお、リクエスト経路制御部50は、複合機10の起動時等において起動され、その際にインタフェース情報がJSDKプラットフォーム40に登録されている。
続いて、SASマネージャ31は、JSDKプラットフォーム40より仮起動サービス333のインタフェース情報を取得する(S115)。続いて、SASマネージャ31は、アプリケーション情報410のpb要素4133を参照し、pb要素4133にそのファイル名(「ScanApp.pb」)が指定されているメインスクリプト71を取得する。SASマネージャ31は、メインスクリプト71とスキャンアプリ321のアプリケーション名とを仮起動サービス333に転送することにより、スキャンアプリ321の仮起動の制御を仮起動サービス333に要求する(S116)。
図9は、第一の実施の形態におけるメインスクリプトの定義例を示す図である。図9に記述されたメインスクリプト71の各記述の内容は、当該記述が実行されるステップにおいて説明する。なお、本実施の形態において、メインスクリプト71や、シナリオスクリプト72及び振る舞いスクリプト73は、対象とするアプリケーションと同じSDカード内に記録されている。
仮起動サービス333は、仮起動の対象とされたスキャンアプリ321のアプリケーション名をリクエスト経路制御部50に通知し、スキャンアプリ321からのネイティブサービスレイヤ60に対する呼び出し要求(メッセージ)を仮起動サービス333に通知するように、リクエスト経路制御部50に要求する(S117)。リクエスト経路制御部50は、ここで通知されるアプリケーション名を保持しておき、仮起動の対象とされているアプリケーションを識別する。
続いて、仮起動サービス333は、メインスクリプト71の記述711を実行する。記述711には、ファイル名が「ScanApp.s」であるシナリオスクリプト72と、ファイル名が「ScanApp.b」である振る舞いスクリプト73とを使用して仮起動を実行することが定義されている。したがって、仮起動サービス333は、シナリオサービス334を起動(生成)し、シナリオサービス334に対してシナリオスクリプト72(ScanApp.s)を転送する(S118)。また、仮起動サービス333は、振る舞いサービス335を起動(生成)し、振る舞いサービス335に対して振る舞いスクリプト73(ScanApp.b)を転送する(S119)。
図10は、第一の実施の形態におけるシナリオスクリプトの定義例を示す図である。図10に記述されたシナリオスクリプト72には、スキャンアプリ321の操作画面の表示後、3秒経過してからスタートボタンを押下し、操作画面に「Complete」という文字の表示が確認できたらシナリオ通り動作したと判断することが定義されている。斯かる定義は、スキャンアプリ321の操作画面が以下のようなものであることが前提とされている。
図11は、スキャンアプリの操作画面の例を示す図である。図11には、二つの操作画面が表示されている。左側の操作画面510aは、初期状態(操作画面の表示直後の状態)を示す。右側の操作画面510bは、スキャンアプリ321の正常終了時の状態を示す。なお、以下において双方を区別しない場合、「操作画面510」という。
本実施の形態において、操作画面510は、対象がスキャンアプリ321であることを示すラベル511と、スタートボタン512と、Resultラベル513とより構成される。スタートボタン512は、スキャンアプリ321の実行の開始指示をユーザに入力させるためのボタンである。Resultラベル513は、スキャンアプリ321の処理結果が表示されるラベルであり、正常終了した場合(スキャンに成功した場合)、操作画面510bに示されるように、「Complete」という文字列が表示され、異常終了した場合(スキャンに失敗した場合)、例えば、「Error」という文字列が表示される。なお、操作画面510aに示されるように、初期状態では、Resultラベル513には何も表示されない。
また、図12は、第一の実施の形態における振る舞いスクリプトの定義例を示す図である。振る舞いスクリプト73における各記述は、ステップごとに実行される定義ではなく、振る舞いサービス335に対する設定情報としての意味を持つ。すなわち、記述731では、スキャンサービス(ネイティブサービスレイヤ60においてスキャナ(撮像部121)に関するサービスを提供するモジュール)に関する要求等に関しては、正常動作をしたように振る舞う(エミュレートする)ことが設定されている。また、記述732では、パネルサービス(ネイティブサービスレイヤ60においてオペレーションパネル202に関するサービスを提供するモジュール)に関する要求等に関しては、正常動作したように振る舞う(エミュレートする)ことが設定されている。
続いて、SASマネージャ31は、JSDKプラットフォーム40に対してスキャンアプリ321の起動要求を行う(S120)。但し、スキャンアプリ321は仮起動サービス333によって、仮起動となる。JSDKプラットフォーム40は、スキャンアプリ321の起動要求に応じ、スキャンアプリ321の状態をinit状態へ遷移させ、スキャンアプリ321がinit状態に遷移したことをロギングサービス42に通知する(S121)。ロギングサービス42は、通知された情報を仮起動ログ80として記録する。
仮起動ログ80は、例えば、以下のような構文によってファイルに記録される。図13は、仮起動ログの構文の例を説明するための図である。図13では、一行分(一回の記録分)の仮起動ログの構文がツリー形式によって記載されている。ツリーの各ノードは、仮起動ログを構成する項目を示す。
図示されるように、仮起動ログ80には、第1項目として番号、第2項目として日付、第3項目として時刻、第4項目としてアプリ名が記録される。番号は、ログの記録順を示す番号である。日付及び時刻は、当該ログが記録された日時である。アプリ名は、仮起動されているアプリケーションのアプリケーション名である。但し、プロダクトIDでもよい。続いて、第5項目には、ログの記録内容の種別が記録される。種別としては、「Bundle」、「Memory」、「Scan」、「Panel」、又は「hdd」が記録される。
「Bundle」は、バンドル(アプリケーション)の状態遷移に関するログであることを示す。この場合、第6項目には、遷移後のバンドルの状態として、例えば、「initState」又は「activeState」が記録される。「initState」は、init状態を示す。「activeState」は、active状態を示す。
「Memory」は、メモリの確保又は開放に関するログであることを示す。この場合、第6項目には、当該アプリケーションによるヒープメモリの消費量の合計値が「Heap=<Size>」の形式で記録される。第7項目には、当該アプリケーションによるスタック領域の消費量の合計値が「Stack=<Size>」の形式で記録される。第8項目には、新たにメモリが確保された対象の種別として、例えば、「Object」が記録される。「Object」は、オブジェクトを示す。第9項目には、新たにメモリが確保された対象の型又はクラス名とそのサイズが記録される。なお、図中では、「Heap」、「Stack」、及び「Object」が選択的な関係であるかのように記載されているが、上記のように、各項目が直列的に記録される。
「Scan」は、スキャナ(撮像部121)の操作に関するログであることを示す。この場合、第6項目として、スキャナに関する操作の種別として、例えば、「setup」、「start」、又は「complete」が記録される。「setup」は、スキャナのセットアップを示す。「start」は、スキャンの開始を示す。「complete」は、スキャンの成功を示す。「setup」の場合、第6項目として、属性設定を意味する値(「attribute」)が記録され、第7項目として、モノクロスキャン(「mono」)であるのか、カラースキャン(「color」)であるのかが記録される。
「Panel」は、オペレーションパネル202の操作に関するログであることを示す。この場合、第6項目には、オペレーションパネル202の操作の種別として、例えば、「show」が記録される。「show」は、オペレーションパネル202に対する情報(画面又はメッセージ等)の表示を示す。
「hdd」は、HDD233の操作に関するログであることを示す。この場合、第6項目には、操作の種別として、例えば「read」又は「write」が記録される。「read」は情報の読み取りを示す。「write」は情報の書き込みを示す。
図14は、仮起動ログの具体例を示す図である。図14に示される仮起動ログ80は、図13において説明した構文に従って記録された例である。図14では、各項目の値がカンマによって区切られたCSV(Comma Separated Values)形式によって記録された例が示されている。図中、1行目は、ステップS121の通知に応じて記録されるログの例を示す。すなわち、「0001」は、番号を示し、「2007.05.10」は、日付を示し、「11:30:24:04」は時刻を示し、「ScanApp」は、スキャンアプリ321のアプリケーション名を示す。また、第5項目が「Bundle」であり、第6項目が「initState」であることから、1行目のログは、スキャンアプリ321がinit状態に遷移したことを記録したものであることが分かる。
図7に戻る。ステップS121に続いて、JSDKプラットフォーム40は、スキャンアプリ321の起動要求に応じ、スキャンアプリ321の状態をactive状態へ遷移させ、スキャンアプリ321がactive状態に遷移したことをロギングサービス42に通知する(S122)。ロギングサービス42は、通知された情報を仮起動ログ80として記録する。ここで、記録されるログは、図14の2行目に相当する。なお、図7では、便宜上、スキャンアプリ321のpause状態への遷移は省略されている。
続いて、JSDKプラットフォーム40は、スキャンアプリ321のバンドルを起動する(S123)。スキャンアプリ321は、起動されると、スキャンアプリ321自身が使用するサービスバンドル33のインタフェース情報をJSDKプラットフォーム40より取得する(S124)。ここでは、スキャンサービス331及びパネルサービス332のインタフェース情報が取得される。なお、スキャンサービス331及びパネルサービス332は、複合機10の起動時等において起動され、その際にインタフェース情報がJSDKプラットフォーム40に登録されている。
続いて、スキャンアプリ321は、スキャンサービス331のインタフェース情報に基づいて、スキャンサービス331を利用するために必要とされるスキャンサービス331のオブジェクト(ScanServiceクラスのインスタンス)を生成する。以降、スキャンアプリ321からスキャンサービス331への要求の通知は、厳密には当該オブジェクトを介して行われる。スキャンサービス331等のサービスバンドル33のオブジェクトの生成は、セキュリティマネージャ41によるアクセス制御の対象とされる。したがって、スキャンサービス331のオブジェクトの生成は、当該オブジェクトのコンストラクタにおいてセキュリティマネージャ41に通知される(S125)。セキュリティマネージャ41は、当該通知に応じて、オブジェクトの生成元(スキャンアプリ321)のクラス名を識別し、スキャンアプリ321によってメモリが消費されたことを、そのクラス名及びオブジェクトのサイズと共にロギングサービス42に通知する(S126)。オブジェクトのサイズは、クラス名に基づいて判定することができる。なお、セキュリティマネージャ41が、オブジェクトの生成元をどのように識別するかについては後述する。
ロギングサービス42は、通知された情報を仮起動ログ80として記録する。ここで、記録されるログは、図14の3行目に相当する。図14の3行目には、「Memory,Heap=2MB,Stack=100KB,Object,ScanService=1MB」と記録されている。これは、スキャンアプリ321によるヒープメモリの現在の総消費量は2MB、スタック領域の現在の総消費量は100KBで、ScanServiceクラスのオブジェクトが生成され、そのサイズは1MBであることを示す。
続いて、スキャンアプリ321は、スキャンサービス331のインタフェース情報に基づいて、スキャンアプリ321の振る舞いに対応したスキャン処理を構築するための初期設定(すなわち、モノクロスキャンの初期設定)をスキャンサービス331に対して行う(S127)。スキャンサービス331は、スキャンアプリ321からの初期設定要求をリクエスト経路制御部50を介してネイティブサービスレイヤ60に通知しようとする(S128)。但し、初期設定の要求元のスキャンアプリ321は仮起動中であるため、リクエスト経路制御部50は、初期設定要求をネイティブサービスレイヤ60へは通知せず、振る舞いサービス335に通知する(S129)。なお、リクエスト経路制御部50が、呼び出し元(ここでは、初期設定の要求元)が仮起動中であるか否かをどのように判定するかについては後述する。
振る舞いサービス335は、スキャナの初期設定のエミュレーションを行い、その処理結果をリクエスト経路制御部50経由で要求元(スキャンアプリ321)へ通知する。ここでは、振る舞いスクリプト73の記述731における設定に従って、正常に初期設定が行われたことが通知される。したがって、スキャンアプリ321は、スキャンの初期設定は正常に行われたものと判断する。なお、スキャンアプリ321が仮起動中でなければ(本起動中であれば)、リクエスト経路制御部50に通知された要求は、ネイティブサービスレイヤ60に通知され、実際に初期設定が行われる。
続いて、振る舞いサービス335は、モノクロスキャンの初期設定が要求されたことをロギングサービス42に通知する(S130)。ロギングサービス42は、通知された情報を仮起動ログ80として記録する。ここで、記録されるログは、図14の4行目に相当する。振る舞いサービス335は、また、モノクロスキャンの初期設定(のエミュレーション)が完了したことをシナリオサービス334に通知する(S131)。シナリオサービス334は、アプリケーションの擬似的な操作者として機能するサービスである。したがって、オペレーションパネル202に、アプリケーションの操作画面510aが表示されるまでは機能することができない。よって、シナリオサービス334は、オペレーションパネル202への操作画面510aの描画(表示)の完了が通知されるまでは、シナリオスクリプト72の定義内容の実行は開始せずに、振る舞いサービス335からの通知は無視する。
なお、振る舞いサービス335による、ロギングサービス42及びシナリオサービス334への通知は、振る舞いサービス335に予め組み込まれているロジックによって実行される処理である(振る舞いスクリプト73に基づいて実行される処理ではない。)。すなわち、振る舞いサービス335は、リクエスト経路制御部50によって経路変更されたサービス要求が通知されたときは、当該サービス要求を受けたことをロギングサービス42に通知すると共に、当該サービス要求に応じて振る舞いサービス335がエミュレーションした結果をシナリオサービス42に通知するように実装されている。
続いて、スキャンアプリ321は、パネルサービス332のインタフェース情報に基づいて、パネルサービス332を利用するために必要とされるパネルサービス332のオブジェクト(PanelServiceクラスのインスタンス)を生成する。以降、スキャンアプリ321からパネルサービス332への要求の通知は、厳密には当該オブジェクトを介して行われる。パネルサービス332のオブジェクトの生成は、当該オブジェクトのコンストラクタにおいてセキュリティマネージャ41に通知される(S132)。セキュリティマネージャ41は、当該通知に応じて、オブジェクトの生成元(スキャンアプリ321)のクラス名を識別し、スキャンアプリ321によってメモリが消費されたことを、そのクラス名及びオブジェクトのサイズと共にロギングサービス42に通知する(S133)。ロギングサービス42は、通知された情報を仮起動ログ80として記録する。ここで、記録されるログは、図14の5行目に相当する。図14の5行目には、「Memory,Heap=3MB,Stack=300KB,Object,PanelService=1MB」と記録されている。これは、スキャンアプリ321によるヒープメモリの現在の総消費量は3MB、スタック領域の現在の総消費量は300KBで、PanelServiceクラスのオブジェクトが生成され、そのサイズは1MBであることを示す。
続いて、スキャンアプリ321は、パネルサービス332のインタフェース情報を用いて、スキャンアプリ321の操作画面510aのオペレーションパネル202の描画要求をパネルサービス332に通知する(S134)。
続いて、パネルサービス332は、スキャナアプリ321の操作画面510aをオペレーションパネル202に描画させるためにネイティブサービスレイヤ60に通知すべき画面情報を構築(生成)し、当該画面情報に基づく操作画面510aの描画要求をリクエスト経路制御部50を介してネイティブサービスレイヤ60に通知しようとする(S135)。但し、操作画面510aの描画の要求元のスキャンアプリ321は仮起動中であるため、リクエスト経路制御部50は、描画要求をネイティブサービスレイヤ60へは通知せず、画面情報と共に振る舞いサービス335に通知する(S136)。
振る舞いサービス335は、画面情報に基づく操作画面510aの描画のエミュレーションを行う。その結果、仮想的に操作画面510aの描画が行われる。ここで「仮想的に」とは、実際には、オペレーションパネル202には操作画面510aが表示されないことをいう。但し、振る舞いサービス335内において、操作画面510aの画面情報は保持される。続いて、振る舞いサービス335は、操作画面510aの描画のエミュレーションの結果をリクエスト経路制御部50経由で要求元(スキャンアプリ321)へ通知する。ここでは、振る舞いスクリプト73の記述732における設定に従って、正常に描画が行われたことが通知される。
続いて、振る舞いサービス335は、操作画面510aの描画が要求されたことをロギングサービス42に通知する(S137)。ロギングサービス42は、通知された情報を仮起動ログ80として記録する。ここで、記録されるログは、図14の6行目に相当する。振る舞いサービス335は、また、操作画面510aの描画(のエミュレーション)が完了したことをシナリオサービス334に通知する(S138)。
操作画面510aの描画の完了の通知に応じ、シナリオサービス334は、シナリオスクリプト72の定義内容に応じた処理を開始する。まず、図10の記述721に基づいて、操作画面510a(図11)におけるスタートボタン512のオブジェクト(以下、「スタートボタンオブジェクト」という。)を取得する。スタートボタンオブジェククトは、操作画面510の画面情報を構成するオブジェクト群の一つであり、記述721に記載される関数の呼び出しに応じて、振る舞いサービス335より取得される。続いて、記述722に記載された関数に基づいて、当該関数の引数に指定された時間(3秒間)待機する。続いて、記述723に基づいて、スタートボタン512が押下されたことを示すメッセージをリクエスト経路制御部50に通知する(S139)。なお、スタートボタン512の押下の通知を行うまでに3秒間待機するのは、シナリオサービス334による擬似的な操作入力を、実際のユーザによる操作入力により近いものとするためである。すなわち、実際のユーザは、操作画面510aの表示直後にスタートボタン512を押下することはなく、だいたい3秒くらいたってから、操作入力を開始するからである。
続いて、シナリオサービス334は、シナリオスクリプト72の記述724に基づいて、操作画面510のResultラベル513のオブジェクト(以下「Resultラベルオブジェクト」という。)を取得する。Resultラベルオブジェクトは、操作画面510の画面情報を構成するオブジェクト群の一つであり、記述724に記載される関数の呼び出しに応じて、振る舞いサービス335より取得される。
続いて、シナリオサービス334は、シナリオスクリプト72の記述725に基づいて、Resultラベル513が更新されるまで待機状態となる。したがって、記述726以降の処理は、この段階では実行されない。
一方、ステップS139において、シナリオサービス334よりスタートボタン512の押下の通知するメッセージを受けたリクエスト経路制御部50は、当該メッセージをパネルサービス332に通知する(S140)。
パネルサービス332は、スタートボタン512の押下の通知を受けて、スキャンアプリ321に対して、スタートボタン512が押下されたことを通知する(S141)。スキャンアプリ321は、スタートボタン512の押下の通知を受けて、スキャンサービス331に対してスキャンの開始を要求する(S142)。スキャンサービス331は、スキャンアプリ321からのスキャン開始要求をリクエスト経路制御部50を介してネイティブサービスレイヤ60に通知しようとする(S143)。但し、スキャン開始の要求元のスキャンアプリ321は仮起動中であるため、リクエスト経路制御部50は、スキャン開始要求をネイティブサービスレイヤ60へは通知せず、振る舞いサービス335に通知する(S144)。
続いて、振る舞いサービス335は、スキャンの開始が要求されたことをロギングサービス42に通知する(S145)。ロギングサービス42は、通知された情報を仮起動ログ80として記録する。ここで、記録されるログは、図14の7行目に相当する。振る舞いサービス335は、また、スキャンが開始されることをシナリオサービス334に通知する(S146)。ここで、シナリオサービス334は、Resultラベル513の更新待ち状態であるため、何も行わない。
続いて、振る舞いサービス335は、スキャンのエミュレーションを行い、その処理結果をリクエスト経路制御部50へ通知する(S147)。ここでは、振る舞いスクリプト73の記述731における設定に従って、正常にスキャンが行われたこと(正常終了)を示すメッセージが通知される。振る舞いサービス335は、また、スキャンの正常終了をロギングサービス42及びシナリオサービス334に通知する(S148、S149)。ロギングサービス42は、通知された情報を仮起動ログ80として記録する。ここで、記録されるログは、図14の8行目に相当する。また、シナリオサービス334は、Resultラベル513の更新待ち状態であるため、スキャンの正常終了の通知に応じて何も行わない。
一方、ステップS147において、振る舞いサービス335よりスキャンの正常終了を通知するメッセージを受けたリクエスト経路制御部50は、当該メッセージをスキャンサービス331に通知する(S150)。スキャンサービス331は、スキャン開始の要求元であるスキャンアプリ321にスキャンの正常終了を通知する(S151)。
スキャンアプリ321は、スキャンの正常終了の通知を受けて、操作画面510のResultラベル513に文字列「Complete」を表示させるようにパネルサービス332に対して要求する(S152)。パネルサービス332は、スキャンアプリ321からの要求を受けて、文字列「Complete」の表示要求をリクエスト経路制御部50を介してネイティブサービスレイヤ60に通知しようとする(S153)。但し、文字列「Complete」の表示要求の要求元のスキャンアプリ321は仮起動中であるため、リクエスト経路制御部50は、文字列「Complete」の表示要求をネイティブサービスレイヤ60へは通知せず、振る舞いサービス335に通知する(S154)。
振る舞いサービス335は、仮想的に、Resultラベル513に文字列「Complete」を表示させる。具体的には、保持している画面情報におけるResultラベルオブジェクトに対して、文字列「Complete」をセットすることにより、文字列「Complete」の表示処理のエミュレーションを行う。続いて、振る舞いサービス335は、エミュレーションの結果をリクエスト経路制御部50経由で要求元(スキャンアプリ321)へ通知する。ここでは、振る舞いスクリプト73の記述732における設定に従って、正常に文字列「Complete」の表示が行われたことが通知される。
続いて、振る舞いサービス335は、操作画面510の更新が要求されたことをロギングサービス42に通知する(S155)。ロギングサービス42は、通知された情報を仮起動ログ80として記録する。ここで、記録されるログは、図14の9行目に相当する。振る舞いサービス335は、また、Resultラベル513に文字列「Complete」が表示されたことをシナリオサービス334に通知する(S156)。
シナリオサービス334は、当該通知に応じて、Resultラベル513が更新されるまでの待機状態から復帰し、シナリオスクリプト72(図10)の記述726に基づいて、Resultラベル513に表示された文字列が、「Complete」であるか否かを判定する。Resultラベル513に表示された文字列が、「Complete」である場合、シナリオサービス334は、記述727に基づいて、仮起動の対象とされているアプリケーション(スキャンアプリ321)はシナリオ通り動作したこと(シナリオの成功)を仮起動サービス333に通知する(S157)。一方、Resultラベル513に表示された文字列が、「Complete」でない場合、シナリオサービス334は、記述728に基づいて、仮起動の対象とされているアプリケーションはシナリオ通りには動作しなかったこと(シナリオの失敗)を仮起動サービス333に通知する。
仮起動サービス333は、シナリオの成功の通知を受けると、メインスクリプト71(図9)の記述712に基づいて、アプリケーション名が「ScanApp」のアプリケーション(スキャンアプリ321)の仮起動ログの検索をロギングサービス42に要求する。ロギングサービス42は、アプリケーション名に基づいて、仮起動ログ80よりスキャンアプリ321の仮起動ログを検索し、その検索結果を仮起動サービス333に通知する(S159)。図14の仮起動ログ80には、スキャンアプリ321のログ情報のみが記録された例が示されている。したがって、ここでは、図14に示される仮起動ログ80の9行目までの内容がそのまま仮起動サービス333に通知される。
続いて、仮起動サービス333は、メインスクリプト71(図9)の記述713に基づいて、仮起動の成否の判定を行う。記述713では、消費メモリが5MB以下であること、HDD233への書き込みが無いこと、及びスキャンモードはモノクロであることが仮起動の成功の条件とされている。したがって、仮起動サービス333は、仮起動ログ80内おいて、「Memory,Heap=×××MB」という形式で記録されているヒープメモリの消費量のログの中で最大値を検索し、当該最大値が5MB以下であるか否かを確認する。また、仮起動サービス333は、仮起動ログ80内において、「hdd,write」といった記述を検索し、HDD233への書き込みの有無を確認する。更に、仮起動サービス333は、仮起動ログ80内において、「Scan,setup,attribute,mono」といった記述を検索し、スキャンモードがモノクロであるか否かを確認する。
本実施の形態における仮起動ログ80によれば、ヒープメモリの消費量の最大値は5行目より3MBであり、5MB以下である。また、「hdd,write」といった記述は存在せず、HDD233への書き込みは行われていない。更に、4行目に「Scan,setup,attribute,mono」といった記述が存在し、スキャンモードはモノクロである。したがって、仮起動の成功条件は満たされている。そこで、仮起動サービス333は、メインスクリプト71の記述714に基づいて、仮起動は成功したことをSASマネージャ31に通知する(S160)。
SASマネージャ31は、仮起動の成功通知を受けて、仮起動中のスキャンアプリ321を終了させるようにJSDKプラットフォーム40に要求する(S161)。JSDKプラットフォーム40は、スキャンアプリ321をdestroy状態へ遷移させることをロギングサービス42に通知する(S162)。ロギングサービス42は、通知された情報を仮起動ログ80として記録する。ここで、記録されるログは、図14の10行目に相当する。続いて、JSDKプラットフォーム40は、スキャンアプリ321を終了させる(S163)。
一方、SASマネージャ31は、ステップS161においてスキャンアプリ321の終了を要求した後、スキャンアプリ321のインストールが完了したことをオペレーションパネル202に表示させる(S164)。当該表示によって、操作者は、スキャンアプリ321が正常にインストールされたことを認識する(S165)。そこで、操作者は、スキャンアプリ321を利用するため、スキャンアプリ321の本起動の指示をオペレーションパネル202を介して入力する(S166)。スキャンアプリ321の本起動の指示は、SASマネージャ31に通知される(S167)。SASマネージャ31は、JSDKプラットフォーム40に対して、スキャンアプリ321の本起動を要求する(S168)。JSDKプラットフォーム40は、スキャンアプリ321を本起動させる(S169)。
以降、本起動されたスキャンアプリ321にからの要求は、リクエスト経路制御部50によって経路変更されずにネイティブサービスレイヤ60に通知される。したがって、実際に、操作画面の表示が行われ、操作画面を介した操作者からの入力に応じ、スキャンが実行される。
なお、仮起動に失敗した場合、例えば、仮起動されたスキャンアプリ321がシナリオ通りに動作しなかった場合、又は、仮起動の成功の条件(メインスクリプト71の記述713)が満たされなかった場合は、ステップS160において、仮起動サービス333は、メインスクリプト71(図9)の記述715に基づいて、仮起動の失敗をSASマネージャ31に通知する。当該通知に応じ、SASマネージャ31は、スキャンアプリ321のインストールに失敗したことをオペレーションパネル202に表示させ、スキャンアプリ321のインストールを無効とする。したがって、操作者はスキャンアプリ321を本起動させること(実際に利用すること)はできない。
次に、ステップS126等において、セキュリティマネージャ41が、オブジェクトの生成元をどのように識別するかについて説明する。図15は、セキュリティマネージャによるオブジェクトの生成元の識別方法を説明するための図である。図15では、スキャンアプリ321によってスキャンサービス331のオブジェクトが生成される場合を例としている。したがって、図7におけるステップS125及びS126に対応する。
図中、「ScanApp」は、スキャンアプリ321のクラス名である。「ScanService」は、スキャンサービス331のクラス名である。「a:ScanApp」は、ScanAppクラスのオブジェクトa(すなわち、インスタンス化されたスキャンアプリ321)を示す。また、「b:ScanService」は、ScanServiceクラスのオブジェクトb(すなわち、インスタンス化されたスキャンサービス331)を示す。
オブジェクトaが、ScanServiceクラスのコンストラクタを呼び出してオブジェクトbを生成すると(S21)、オブジェクトaのクラス名(「ScanApp」)がスタックに格納される(S22)。オブジェクトbが、そのコンストラクタ内でセキュリティマネージャ41を呼び出すと(S23)、オブジェクトbのクラス名(「ScanService」)がスタックに格納される(S24)。セキュリティマネージャ41は、オブジェクトbからの呼び出しに応じ、スタック内をトレースすることで、呼び出し元のクラス名が「ScanApp」であること、すなわち、オブジェクトbの生成元がスキャンアプリ321であることを識別することができる(S25)。
次に、ステップS129等において、リクエスト経路制御部50が、ネイティブサービスレイヤ60の呼び出し要求元のアプリケーションが仮起動中であるが否かをどのように判定するかについて説明する。まず、前提として、リクエスト経路制御部50には、仮起動の対象とされているアプリケーションが予め登録される(例えば、ステップS116)。したがって、リクエスト経路制御部50内において、呼び出し要求元のアプリケーション名を識別することができれば、当該アプリケーションが仮起動中であるか否かを判定することができる。
本実施の形態では、JSDKアプリ30であるアプリケーションバンドル32が仮起動の対象とされている。ここで、JSDKアプリ30は、Java(登録商標)アプリケーションである。したがって、例えば、Java(登録商標)の標準クラスであるスレッドグループ(ThreadGroup)を用いて、アプリケーションを識別することができる。スレッドグループとは、スレッド(Thread)やスレッドグループの集合であり、一つ以上のThreadをTreadGroupに関連付けることができる。また、スレッドグループには、名前(スレッドグループ名)を付加することができる。そして、各スレッド内では、当該スレッドが属するスレッドグループを識別することができる。なお、本実施の形態において、アプリケーションバンドル32及びサービスバンドル33は、「バンドル」として実装されているが、バンドルとは、動的リンク可能なライブラリ(関数又はクラスの集合)である。また、リクエスト経路制御部50もライブラリ(関数又はクラスの集合)したがって、いずれもプロセスとして起動されるものではなく、呼び出された側は、呼び出し元のスレッド上で動作する。
斯かる仕組みに基づけば、リクエスト経路制御部50では、以下のように呼び出し元のアプリケーション名を識別することができる。図16は、スレッドグループを用いた呼び出し元のアプリケーション名の識別方法を説明するための図である。図16では、便宜上、各モジュールの上下関係が図3と異なっている。
図中、GPx(xはa〜c)は、スレッドグループを示す。thx(xは、a〜d)は、スレッドを示す。図16の例では、スキャンアプリ321には、スレッドグループGPbが関連付けられており、スレッドグループ名としてスキャンアプリ321のアプリケーション名が付加されている。また、スキャンサービス331にはスレッドグループGPcが関連付けられている。
スキャンアプリ321には、メソッドAを実行中のスレッドthaと、メソッドBを実行中のスレッドthbとが存在する。ここで、スレッドthaとスレッドthbとは、スレッドグループGPbに属する。例えば、スキャンアプリ321のメソッドB内より、スキャンサービス331のメソッドCが呼び出された場合、メソッドCは、スレッドthb上で動作する。更に、メソッドCよりリクエスト経路制御部50の関数Dが呼び出された場合、関数Dは、スレッドthb上で動作する。したがって、関数D内で、現在のスレッドを確認するとスレッドthbが特定され、更にスレッドthbが属するスレッドグループを確認するとスレッドグループGPbが特定される。そこで、関数B内で、スレッドグループGPbのスレッドグループ名を取得することにより、関数B(すなわち、リクエスト経路制御部50)の呼び出し元のアプリケーション名が取得される。更に、取得されたアプリケーション名(スレッドグループ名)と、予め登録されている仮起動中のアプリケーション名とを比較することにより、関数Bの呼び出し元が仮起動中であるか否かを判定することができる。
但し、呼び出し元のアプリケーションの識別方法は、必ずしもスレッドグループを用いなくてもよい。例えば、各メソッドや各関数の引数によって呼び出し元のアプリケーション名を引き継ぐようにしてもよい。
上述したように、第一の実施の形態における複合機10によれば、実際にアプリケーションが利用される前に、当該アプリケーションについて仮起動を実行し、その振る舞いに関するログ(仮起動ログ80)を記録しておく。そして、仮起動ログ80に基づいて、予め設定された制限が満たされているか否かを各アプリケーションについて確認することができる。したがって、予め設定された制限を満たしていないアプリケーションの動作を防止することができ、アプリケーションによる不正動作の可能性を低減させることができる。
また、仮起動の成否の判断基準や、仮起動時のアプリケーションに対する操作内容、仮起動時の振る舞いサービス335の振る舞いは、プログラムからは分離されたファイルである仮起動スクリプト70(メインスクリプト71、シナリオスクリプト72、振る舞いスクリプト73)に定義されている。したがって、各アプリケーションや複合機10の資源の変化(例えば、メモリの増設等)に合わせて、これらの情報(判断基準、操作内容、振る舞い等)を容易に変更することができる。特に、本実施の形態のように、テキスト形式のファイルであれば、その変更は容易である。
また、振る舞いサービス335が、ネイティブサービスレイヤ60として(ネイティブサービスレイヤ60と同様の形式で)アプリケーションに対する応答を行うため、アプリケーションは、仮起動であるか否かを意識する必要はない。したがって、仮起動を実現するために、各アプリケーションに改めて実装を行う必要はない。
なお、仮起動中は、ネイティブサービスレイヤ60は呼び出されず、複合機10に特有のハードウェア(例えば、画像処理を行うためのハードウェア)は利用されない。したがって、仮起動は、一般的なPC(Personal Computer)等のコンピュータにおいて行ってもよい。この場合、当該コンピュータにでは、図3において、ネイティブサービスレイヤ60以外のソフトウェアが動作可能であればよい。
次に第二の実施の形態について説明する。第一の実施の形態では、仮起動ログ80に基づいて、アプリケーションごとに消費メモリが制限値(5MB)以内であるか否かが判定されていた。しかし、複数のアプリケーションが並列的に起動される場合、第一の実施の形態における判定だけでは不十分な場合がある。
図17は、複数のアプリケーションを並列して起動した場合のメモリの消費の様子を説明するための図である。
図17において、(A)は、或るアプリケーションバンドル32(以下「アプリA」という。)による、時間の経過(アプリケーションの状態遷移)とヒープメモリの消費量の最大値との関係を示したものである。図示されるように、アプリAは、init状態、pause状態、active状態の各状態において、それぞれ、最大で3MB、1MB、4MBのヒープメモリを消費する。この場合、全状態を通して、アプリAのヒープメモリの最大の消費量は4MBであり、第一の実施の形態における制限である5MBを満たしている。したがって、アプリAについては、仮起動は成功であると判定され、本起動が可能となる。
図中(B)は、アプリAとは別のアプリケーションバンドル32(以下「アプリB」という。)による、時間の経過(アプリケーションの状態遷移)とヒープメモリの消費量の最大値との関係を示したものである。図示されるように、アプリBは、init状態、pause状態、active状態の各状態において、それぞれ最大で3MB、1MB、1MBのヒープメモリを消費する。この場合、全状態を通して、アプリBのヒープメモリの最大の消費量は3MBであり、第一の実施の形態における制限である5MBを満たしている。したがって、アプリBについても、仮起動は成功であると判定され、本起動が可能となる。
図中(C)は、アプリAとアプリBとが同時に起動された場合の時間の経過とヒープメモリの消費量の最大値との関係を示したものである。すなわち、本起動が許可された二つのアプリケーションが同時に起動され、同じタイミングで状態遷移が行われた場合、二つのアプリケーションによって、init状態、pause状態、active状態の各状態において、それぞれ最大で、3+3=6MB、1+1=2MB、1+4=5MBのヒープメモリが消費される。そうすると、init状態において、制限値である5MBを超えてしまい、アプリケーションが正常に動作しない可能性がある。
そこで、第二の実施の形態では、斯かる課題を解決した例について説明する。なお、第二の実施の形態は、第一の実施の形態との差分についてのみ説明する。したがって、特に言及しない点については、第一の実施の形態と同様でよい。
第二の実施の形態において、メインスクリプト71は、次のように定義される。図18は、第二の実施の形態におけるメインスクリプトの記述例を示す図である。図18中、図9と同一部分には同一符号を付し、その説明は省略する。なお、第二の実施の形態において、メインスクリプト71は、メインスクリプト71aとして説明する。
メインスクリプト71aは、第一の実施の形態と比較して記述716が異なる。すなわち、記述716では、スクリプト関数pbCase1のインタフェースが定義されているが、第二の実施の形態では、仮起動ログを格納する変数(PseudoBootLog log)が、参照渡しのOUT型の引数として定義されている。当該引数の値は、記述712において格納される。
第二の実施の形態における、複合機10の仮起動に関する処理手順は、図7とほぼ同様である。但し、メインスクリプト71aにおける記述716に基づいて、ステップS160において、仮起動サービス333は、仮起動の成否を示す情報と共に、仮起動ログ80の内容をSASマネージャ31に通知する。SASマネージャ31は、通知された仮起動ログ80を仮起動の対象とされていたアプリケーションバンドル32(図7の例ではスキャンアプリ321)と関連付けて、例えば、HDD233に保存し、管理する。関連付けは、例えば、仮起動ログ80のファイル名を、当該アプリケーションバンドル32のアプリケーション名とすることにより行ってもよい。
第二の実施の形態では、また、ステップS167においてアプリケーションの起動要求を受けた際におけるSASマネージャ31による、起動中(起動開始時も含む)のアプリケーションの管理に関する処理が異なる。
図19は、第二の実施の形態におけるSASマネージャによる起動中のアプリケーションの管理処理を説明するためのフローチャートである。なお、図19の処理は、本起動のアプリケーション(すなわち、仮起動が成功したアプリケーション)に関して行われる。
複合機10において、状態遷移(起動によるinit状態への遷移も含む)の必要なアプリケーション(以下、「アプリA」という。)が発生すると(S201でYes)、SASマネージャ31は、アプリAの遷移先の状態のメモリ消費量の最大値と、現在本起動中の他のアプリケーションのそれぞれの状態におけるメモリ消費量の最大値との合計が予め設定されている制限値(例えば、5MB)以下であるか否かを判定する(S202)。
なお、SASマネージャ31は、アプリAの遷移先の状態のメモリ消費量の最大値や、各アプリケーションの現在の状態のメモリ消費量の最大値をそれぞれのアプリケーションに関連付けられている仮起動ログ80に基づいて判定する。また、SASマネージャ31は、状態遷移するアプリケーションの発生を、当該アプリケーションからの通知によって検知する。
メモリ消費量の最大値の合計が制限値以下である場合(S202でYes)、SASマネージャ31は、アプリAの状態遷移を許可する。その結果、アプリAは、状態遷移を行う(S203)。一方、メモリ消費量の合計が制限値を超えている場合(S202でNo)、SASマネージャ31は、アプリAの状態遷移を待機させ、アプリAの状態遷移を待機させていることを示す情報(以下、「待機情報」という。)を状態遷移待機キューに登録する。待機情報は、例えば、アプリAの識別情報及び遷移先の状態の識別情報等より構成される。但し、遷移先の状態の識別情報の代わりに遷移先の状態のメモリ消費量の最大値を待機情報に含めても良い。そうすることにより、アプリAの遷移先の状態のメモリ消費量について改めて仮起動ログ80を参照する処理を省くことができる。また、状態遷移待機キューは、待機情報のキュー又はリストである。すなわち、状態遷移待機キューによって、状態遷移待ちであるアプリケーションの一覧が把握され得る。
ステップS203において、アプリAの状態遷移が行われた場合、アプリAの状態の遷移によって、各アプリのそれぞれの状態のメモリ消費量の最大値の合計が変化する。したがって、状態遷移待ちアプリの状態遷移を許可できる可能性がある。そこで、SASマネージャ31は、ステップS205以降の処理を実行する。
すなわち、SASマネージャ31は、状態遷移待機キューにおける待機情報の有無を確認することにより、状態遷移待ちのアプリケーションの有無を判定する(S205)。状態遷移待ちのアプリケーションが存在しない場合(状態遷移待機キューが空の場合)(S205でNo)、ステップS201に戻る。
一方、状態遷移待ちのアプリケーションが存在する場合(S205でYes)、SASマネージャ31は、状態遷移待機キューより一つの待機情報を取り出す(S206)。状態遷移待機キューからの待機情報の取り出す順序は、FIFO(First-In First-Out)又はLRU(Least Recently Used)に従ってもよいし、アプリケーションに優先順位を付け、その優先順位に従ってもよい。当該優先順位は、HDD233等に予め記録しておけばよい。
続いて、SASマネージャ31は、取り出された待機情報(以下、「カレント待機情報」という。)に係るアプリケーションの遷移先の状態のメモリ消費量の最大値と他のアプリケーションのそれぞれの状態におけるメモリ消費量の最大値との合計が予め設定されている制限値以下であるか否かを判定する(S207)。
メモリ消費量の最大値の合計が制限値以下であり場合(S207でYes)、SASマネージャ31は、カレント待機情報を状態遷移待機キューより削除し(S208)、状態遷移待ちだったアプリケーションの状態を遷移させる(S203)。なお、当該アプリケーションの状態の遷移に応じて、更に、他の状態遷移待ちのアプリケーションの状態遷移の可否を判定するため、続いて、ステップS205以降の処理が実行される。
一方、ステップS207において、メモリ消費量の最大値の合計が制限値を超える場合(S207でNo)、ステップS201に戻る。但し、ステップS206に戻るようにしてもよい。この場合、状態遷移待機キューにその待機情報が登録されているアプリケーションの中で、制限値内で遷移可能なアプリケーションの状態遷移が優先的に実行される。
以上、図19において説明したように、アプリケーションの状態遷移を制限することにより、図17において説明したような状況の発生を回避することがでる。図17の例に関しては、次のように改善される。図20は、状態遷移の制限によってメモリ消費量が適切に管理される様子を示す図である。
図20では、アプリAのinit状態とアプリBのinit状態が重なると、制限値(5MB)を超えてしまうため、アプリAのinit状態への遷移は、アプリBのpause状態への遷移後に行われている。そうすることにより、アプリAとアプリBとの消費メモリの合計値が、全過程を通して、制限値内に抑制されている。
上述したように、第二の実施の形態における複合機10によれば、複数のアプリケーションが並列的に動作する場合であっても、各アプリケーションの仮起動中に記録された仮起動ログ80に記録された情報に基づいて、アプリケーションの振る舞い(挙動)を変化させることができる。すなわち、複数のアプリケーションによるメモリ消費量の合計値が、予め設定された制限値以下に維持されるようにすることができる。したがって、アプリケーションによる不正動作の可能性を低減させることができる。
なお、第二の実施の形態では、仮起動時に、全状態を通したメモリの消費量の最大値が制限値以下であるか否かが判断された例を示した(メインスクリプト71a(図18)の記述713参照)。したがって、当該制限を満たしたアプリケーションのみが、本起動の対象とされる前提で、図19の処理手順を説明した。しかし、アプリケーションが本起動されるときに、SASマネージャ31が、当該アプリケーションの仮起動ログ80を参照して、全状態を通したメモリの消費量の最大値を判定し、その最大値が制限値を超える場合は、当該アプリケーションの本起動を拒否するようにしてもよい。この場合、必ずしも仮起動時にメモリの消費量の最大値のチェックを行わなくても良い。すなわち、メインスクリプト71aの記述713における「log.Maxmem<5MB」という記述を削除してもよい。
また、図19の処理は、JSDKプラットフォーム40が行うようにしてもよい。
ところで、上記においては、仮起動をアプリケーションの適否の事前チェックのための手段として用いる例について説明した。しかし、仮起動の用途は、これだけに限られない。例えば、アプリケーションの本起動中に発生した障害の原因解析のための手段としても利用することができる。以下、仮起動を障害の原因解析に適用した例を、第三及び第四の実施の形態として説明する。
図21は、第三の実施の形態における仮起動を用いた障害解析の方法を説明するための図である。図21において、障害対応サーバ20は、インターネット等のネットワークを介して複合機10と接続され、複合機10を遠隔より監視するコンピュータである。障害対応サーバ20は、例えば、複合機10のベンダによって運用される。
操作者による指示に応じ、複合機10のSASマネージャ31は、アプリケーション(例えば、スキャンアプリ321)を本起動させる(S301)。アプリケーションの本起動中に障害が発生すると、パネルサービス332は、オペレーションパネル202に障害が発生したことを通知する警告画面を表示させる(S302)。続いて、SASマネージャ31は、障害対応サーバ20に障害内容を示す情報(例えば、エラーコード等)を送信する(S303)。
障害対応サーバ20は、障害内容を示す情報に基づいて、障害の原因を調査するために適切な仮起動スクリプト70を複合機10に送信する(S304)。例えば、障害対応サーバ20の記憶装置には、アプリケーションごと、かつ、障害内容ごとに、当該障害内容の原因を調査するために適切な仮起動スクリプト70が予め保存されている。障害内容の原因を調査するために適切な仮起動スクリプト70とは、その障害を解析するために適切なシナリオが定義されたシナリオスクリプト72や、その障害を解析するための適切なエミュレーションの内容が定義された振る舞いスクリプト73を含む仮起動スクリプト70をいう。
複合機10は、受信した仮起動スクリプト70を利用して、障害が発生したアプリケーションを仮起動する(S305)。この際の処理手順は、図7において説明した通りである。その結果、仮起動ログ80が生成される。そこで、複合機10のSASマネージャ31は、仮起動ログ80を障害対応サーバ20に送信する(S306)。
障害対応サーバ20は、仮起動ログ80を解析し、原因の特定を行う。原因の特定は、自動的に行われても良いし、人的に行われてもよい。原因が特定されると、操作者に障害の解析結果について報告が行われる(S307)。当該報告は、電子メール等によって自動的に行われても良い。また、アプリケーションのバグであった場合、障害対応サーバ20から修正版を複合機10にリモートインストールするようにしてもよい。
なお、障害内容ごとの仮起動スクリプト70を複合機10に予め保存しておき、複合機10の側で、原因の解析を行っても良い。この場合、障害対応サーバ20は、必ずしも必要ではない。
次に、第四の実施の形態について説明する。図22は、第四の実施の形態における仮起動を用いた障害解析の方法を説明するための図である。図22中、図21と同一部分には同一符号を付し、その説明は省略する。なお、第四の実施の形態では、障害対応サーバ20に、JSDKアプリ30、JSDKプラットフォーム40、及びリクエスト経路制御部50等が実装されていることとする。
図22において、ステップS401〜S403は、図21のステップS301〜S303と同様である。
続いて、障害対応サーバ20は、障害内容を示す情報に基づいて、障害の原因を調査するために適切な仮起動スクリプト70を記憶装置の中から選択する(S404)。続いて、障害対応サーバ20は、仮起動スクリプト70を利用して、障害が発生したアプリケーションを仮起動し、その結果生成される仮起動ログ80を解析し、原因の特定を行う。原因が特定されると、障害対応サーバ20は、操作者に障害の解析結果について報告を行う(S406)。アプリケーションのバグであった場合、障害対応サーバ20から修正板を複合機10にリモートインストールするようにしてもよい。
上述したように、障害に対応した仮起動スクリプト70に基づいてアプリケーションの仮起動を実行することにより、その結果生成される仮起動ログ80に基づいて、適切に原因の解析を行うことができる。
以上、本発明の実施例について詳述したが、本発明は斯かる特定の実施形態に限定されるものではなく、特許請求の範囲に記載された本発明の要旨の範囲内において、種々の変形・変更が可能である。