[WrapperManager.exec()] 関数は、 [Java-Runtime.exec()]の代替え案です。 [Java-Runtime.exec()]は一部のプラットフォームで 新しいプロセスを生成するのに[fork()]メソッドを 利用してメモリを無駄に消費する不利な点があります。 それらのプラットフォーム上での問題は、 もし、サイド・プロセスを開始したいペアレント(親)プロセスの場合、 [fork()]がチャイルド(子)用にペアレント(親)のメモリのクローンを作成します。 これは、短い時間、消費メモリが倍になります。 システム・メモリ・割り当て量に近い、わりと大きいアプリケーションが与えられると、 lsのような、 小さいアプリケーションの作成にも失敗する可能性があります。 あるいは、ハードディスクへそのメモリのスワッピングが発生する可能性もあり、パフォーマンスが劇的に低下することになります。
もう一つの問題としては、ペアレント(親)から開始している間、 チャイルド(子)のバインドやデタッチを緩和することです。 もしJavaプロセスが、期待どおりにしろ、予想外にしろ、終了する場合、 Wrapperは、まだ終了していない全てのバインド・プロセスをクリーンします。
より良い一貫性のために、可能な限り、Javaでの[Runtime.exec()]関数に近い、 [WrapperManager.exec()]関数が実装されました。
このセクションでは、コマンドをどのように実行するのかを説明します。 (さらに詳細は、このページを読み進めながら、ステップByステップで説明していきます)
WrapperProcess p = WrapperManager.exec("ls -lisa");
このコマンドは、 [-l]や[-s]の パラメーターで、[ls]コマンドを実行します。 そのプロセスのJava側の representation は、 返された[WrapperProcess]オブジェクトです。
もし、バイナリ(あるいはスクリプト)ファイルの完全なフル・パスが渡されていない場合、 システム・パス・ディレクトリー同様に、そのカレント作業ディレクトリーが確認され、 最初に見つかったものが実行されます。 カレント作業ディレクトリーから始まる相対アドレスも、サポートされます。
[exec]コマンドは、 単一の文字として、あるいは同様に、文字列群(StringArray)として、どちらでのコマンドでも受け入れます。 文字列群(StringArray)の場合、各パラメーターは、単一の配列フィールド(an single array field)に配置されます。
GUIアプリケーションでない限り、作成されたチャイルド(子)プロセスは、 OSのバックグランドで動作し、通常は見えません。 そのプロセスとコミニケーションするために、 [WrapperProcess]クラスは、 そのプロセスへの出力やエラーメッセージ、同様に、そのプロセスへの入力にアクセスするために、 3つのメソッドを提供します。
BufferedReaderで、返されたストリーム・オブジェクトをラップすることを推奨します。 リーダーを開けるには、下記のとおりに手順を進めてください。
BufferedReader br = new BufferedReader( new InputStreamReader(p.getWrapperProcessInputStream()));
これは、チャイルド(子)がその出力を書き出すインプット・ストリーム(InputStream)のリーダーを確立します。 エラーストリーム(ErrorStream)からデーターを読む、あるいは、 チャイルド(子)へデーターを書き出すには、 この例に似たように処理を進めてください。
一旦、リーダー/ライターが確立されると、データーを読む/書くができるようになります:
String line; while ((line = br.readLine()) != null) { system.out.println(line); } br.close();
この例を追うと、 そのチャイルド(子)プロセスが、自分側のストリームを閉じるまで、全てのデーターが読み込まれます のでご注意ください。
コマンドを実行するとき、 WrapperManagerは、チャイルド(子)プロセスを設定する可能性を提供します。 これは、[WrapperProcessConfig]オブジェクトを、 [exec()]関数へ引き渡すことで行われます。 次のセクションでは、WrapperProcessConfigurationによって作成されるコンフィギュレーションについて説明します。
このフィールドには、サブプロセスがWrapperからデタッチされて動作するのかを設定します。 もし、プロセスが「デタッチされた」とマークされた場合、Wrapperがシャットダウンする時、 そのプロセスを終了する必要はありません。 もし、マークされない場合、Wrapperはチャイルド(子)プロセスの経過を追い、 そのペアレント(親)プロセスを終了するべき時には、そのチャイルド(子)プロセスの終了を試みます。
デフォルトで、プロセスはそのペアレント(親)プロセスからデタッチされた状態で開始されません。
このフィールドでは、サブプロセスがOSによって、どのように開始されるのかスタート・タイプを指定します。 (このプロパティはWindowsでは無効です)
UNIX/Linuxで、チャイルド(子)プロセスを生成する一般的な手法です。 しかしながら、一部のOS(特にSolaris)上では、 このコールは、チャイルド(子)用に、初めにペアレント(親)のメモリを複製することになります。 z/OS上では、このスタート・タイプはWrapper初代リリースの時点でサポートされていません。 HP-UXシステム上では、Wrapperは[fork()]ではなく、 [vfork]を使うように自動的に切り替えます。
チャイルド(子)プロセスがペアレント(親)プロセスとコードやデーターを共有することができる場合に、 [vfork()]関数は、[fork()]とは異なります。 これは、 もし[vfork()]が誤用された場合、 ペアレント(親)プロセスのインテグリティ(整合性)にリスクを伴い、クローン動作が著しく加速します。 一部のシステム上では、[vfork]は[fork]と同じです。 z/OS上では、このスタート・タイプはWrapper初代リリースの時点でサポートされていません。
プロセスが生成され、何もメモリ複製を起こしません。 POSIX_SPAWN API これは、LINUX、SOLARIS (10+)、AIX、z/OS、MACOS上だけで有効です。
このスタート・タイプは、Wrapperが動作しているOS次第で、最適なスタート・タイプを選択します。 POSIX_SPAWNの利用中に作業ディレクトリーの変更をサポートしないため、 このプロパティでは作業ディレクトリーの変更がサポートされないことも意味しているので、注意してください。 作業ディレクトリーの変更も利用できる 試験的なプロパティ [wrapper.child.allowCWDOnSpawn] があります。
デフォルトで、スタート・タイプ[DYNAMIC]でプロセスが起動されます。
このフィールドではサブプロセスの作業ディレクトリーを指定するか、 サブプロセスがカレント・プロセスの作業ディレクトリーを継承する場合には、「null」を設定します。
POSIX_SPAWNを利用中には、 作業ディレクトリーを設定することはできませんので、ご注意ください。 お薦めの回避策は、スクリプト内で動かしたいコマンドをラップして、 そのコマンドの実行前に、ディレクトリー変更をすることです。
#!/bin/sh chdir $1 shift $*
もし、このプロパティが設定されない場合、 サブプロセスは、そのペアレント(親)プロセスから作業ディレクトリーを継承します。
このフィールドでは作成されたサブプロセスの環境を指定します。
このフィールドは文字配列です、各エレメントは「名前=値」形式で、環境変数を設定します。
もし、このプロパティが設定されない場合、 サブプロセスは、そのペアレント(親)プロセスから環境を継承します。
[wrapper.child.allowCWDOnSpawn]プロパティでは、 スタート・タイプ[POSIX_SPAWN]や[DYNAMIC] のとき、Wrapperが作業ディレクトリーの変更を試みるかをコントロールします。
このプロパティは実験的なもので、 ラップされたプロセスが Java ネイティブ・インターフェイス (JNI) コードを利用している場合、 問題を引き起こす可能性もあり、[POSIX_SPAWN] を使いチャイルド(子)プロセスの生成を試みることでしょう。
デフォルトで、このプロパティは「FALSE」に設定されます。
wrapper.child.allowCWDOnSpawn=TRUE