World Map
Java Service Wrapperは、御社Javaアプリケーション製品の安定した信頼性を高める最短最善の方法です。
  • Free Trial
  • Buy Now
Wrapper ネイティブ実行

Wrapper ネイティブ実行の概要

概要

WrapperManager.exec()] 関数は、 [Java-Runtime.exec()]あるいは[Java-ProcessBuilder]の代替え案であり、 新しいプロセスを生成するのに[fork()]メソッドを 利用して、一部のプラットフォームでメモリを無駄に消費する不利な点があります。 それらのプラットフォーム上での問題は、サイドプロセスを開始したいペアレント(親)プロセスにおいて、 [fork()]がチャイルド(子)用にペアレント(親)のメモリヒープのクローンを作成します。 そのため、短時間で消費メモリが倍になります。 システムメモリの割り当て量に近い、わりと大きいアプリケーションが与えられると、 [ls]のような、小さいアプリケーションの作成にも失敗する可能性があります。 あるいは、ハードディスクへそのメモリのスワッピングが発生する可能性もあり、パフォーマンスが劇的に低下することになります。

もう一つの問題としては、ペアレント(親)から開始している間、チャイルド(子)のバインドやデタッチ(切り離し)を緩和することです。 もし Java プロセスが、期待どおりにしろ、予想外にしろ、終了する場合、 Wrapper は、まだ終了していない全てのバインドプロセスをクリーンします。

より良い一貫性のために、可能な限り、Java での[Runtime.exec()]関数に近い、 WrapperManager.exec()]関数が実装されました。

実行する

スタート

このセクションでは、コマンドをどのように実行するのかを説明します。 (さらに詳細は、このページを読み進めながら、ステップByステップで説明していきます)

WrapperProcess p = WrapperManager.exec("ls -lisa");

上記は、[-l]、[-i]、[-s]や[-a]パラメータで、[ls]コマンドを実行し、そのプロセスを表現する[WrapperProcess]オブジェクトをアサインします。

もし、バイナリ(あるいはスクリプト)ファイルの完全なフルパスが渡されていない場合、 システムパスディレクトリー同様に、そのカレント作業ディレクトリーが確認され、 最初に見つかったものが実行されます。 カレント作業ディレクトリーから始まる相対アドレスも、サポートされます。

注意

exec]コマンドは、 単一の文字(String)として、あるいは同様に、文字列群(StringArray)として、どちらでのコマンドでも受け入れます。 文字列群(StringArray)の場合、各パラメータは、単一の配列フィールド(a single array field)に配置されます。

プロセスの I/O

GUI アプリケーションでない限り、作成されたチャイルド(子)プロセスは、 OS のバックグランドで動作し、通常は見えません。 そのプロセスとコミニケーションするために、 [WrapperProcess]クラスは、 そのプロセスへの出力やエラーメッセージ、同様に、そのプロセスへの入力にアクセスするために、 3つのメソッドを提供します。

BufferedReader で、返されたストリームオブジェクト(StreamObject)をラップすることを推奨します。 リーダーを開けるには、下記のとおりに手順を進めてください。

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 では無効です。

  • [FORK_EXEC] :

    UNIX/Linux で、チャイルド(子)プロセスを生成する一般的な手法です。 しかしながら、一部の OS(特に Solaris)上では、 このコールは、チャイルド(子)用に、初めにペアレント(親)のメモリを複製することになります。 z/OS 上では、このスタートタイプは Wrapper 初代リリースの時点でサポートされていません。 HP-UX システム上では、Wrapper は[fork()]ではなく、 [vfork]を使うように自動的に切り替えます。

  • [VFORK_EXEC] :

    チャイルド(子)プロセスがペアレント(親)プロセスとコードやデーターを共有することができる場合に、 [vfork()]関数は、[fork()]とは異なります。 これは、 もし[vfork()]が誤用された場合、 ペアレント(親)プロセスのインテグリティ(整合性)にリスクを伴い、クローン動作が著しく加速します。 一部のシステム上では、[vfork]は[fork]と同じです。 z/OS 上では、このスタートタイプは Wrapper 初代リリースの時点でサポートされていません。

  • [POSIX_SPAWN] :

    プロセスが生成され、何もメモリ複製を起こしません。 POSIX_SPAWN API これは、LINUX、SOLARIS (10+)、AIX、z/OS、MacOS 上だけで有効です。

  • [DYNAMIC] :

    このスタートタイプは、Wrapper が動作している OS 次第で最適なスタートタイプを選択します。 POSIX_SPAWNの利用中に作業ディレクトリーの変更をサポートしないため、 このプロパティでは作業ディレクトリーの変更がサポートされないことも意味しているので、注意してください。 作業ディレクトリーの変更も利用できる 試験的なプロパティ [wrapper.child.allowCWDOnSpawn] があります。

注意

デフォルト値は、スタートタイプ[DYNAMICでプロセスが起動されます。

作業ディレクトリー

このフィールドではサブプロセスの作業ディレクトリーを指定するか、 サブプロセスがカレントプロセスの作業ディレクトリーを継承する場合には、「NULL」を設定します。

POSIX_SPAWN を利用中には、 作業ディレクトリーを設定することはできませんので、ご注意ください。 お薦めの回避策は、スクリプト内で動かしたいコマンドをラップして、 そのコマンドの実行前に、ディレクトリー変更をすることです。

#!/bin/sh

chdir $1
shift
$*

注意

もし、このプロパティが設定されない場合、 サブプロセスは、そのペアレント(親)プロセスから作業ディレクトリーを継承します。

wrapper.child.allowCWDOnSpawnプロパティ

wrapper.child.allowCWDOnSpawn]プロパティでは、 スタートタイプ[POSIX_SPAWN]や[DYNAMIC] のとき、Wrapperが作業ディレクトリーの変更を試みるかをコントロールします。

このプロパティは実験的なもので、 ラップされたプロセスが Java ネイティブインターフェイス(JNI)コードを利用している場合、 問題を引き起こす可能性もあり、[POSIX_SPAWN] を使いチャイルド(子)プロセスの生成を試みることでしょう。

このプロパティのデフォルト値は「FALSE」に設定されます。

wrapper.child.allowCWDOnSpawn=TRUE

環境を設定する

このフィールドでは作成されたサブプロセスの環境を指定します。

このフィールドは文字配列です、各エレメントは「名前=値」形式で、環境変数を設定します。

注意

もし、このプロパティが設定されない場合、 サブプロセスは、そのペアレント(親)プロセスから環境を継承します。

チャイルド終了に軽いタイムアウトを設定する

Wrapper バージョン 3.5.5 から、 各プロセスにそれぞれのソフトタイムアウトを指定することが可能になり、 Wrapper はチャイルド(子)プロセスに自力で終了する機会が与えられますが、 [java.lang.Process.destroy()]メソッドは常に強制シャットダウンを引き起こし、プロセスに自力で終了する機会を与えません。 Wrapper バージョン 3.5.5 より以前では、機能性を一定に保つために、タイムアウトは常にデフォルトで5秒でした。

このタイムアウトは、チャイルド(子)プロセスが[WrapperProcessConfig]クラスで作成されているときに指定することができます。

WrapperProcessConfig wpConfig = new WrapperProcessConfig().setSoftShutdownTimeout(10);

上記のコンフィギュレーション例では、そのコンフィギュレーションで作成されたとおり、 Wrapper を10秒間までチャイルド(子)プロセス待ちにさせます。 もし、チャイルド(子)プロセスが 10 秒以内に終了しない場合、Wrapper は強制終了させます。

タイムアウトの可能な値は、次のとおり:

  • [>0] :

    強制終了される前に、チャイルド(子)プロセスが自力で終了するまで、Wrapper が待機する秒数を指定します。

  • [0] :

    Wrapper が即座にチャイルド(子)プロセスの終了を強制します。

  • [-1] :

    Wrapper はチャイルド(子)プロセスを強制終了しませんが、 そのチャイルド(子)プロセスが自力で終了するまで永久に待機します。

アクティブユーザー用にチャイルド(子)プロセスを作成する

Windows 上で、 [WrapperProcessConfig.setCreateForActiveUser(boolean)]は、サービスが動作しているアクティブセッション(OS の「SE_TCB_NAME」特権を持つユーザー)ではなく、現在のアクティブセッション内で、チャイルド(子)プロセスが起動するかどうかを指定します。 Windows 以外のプラットフォーム上で、あるいはコンソールモードで起動されている場合、この設定は静かに無視されます。

デフォルト値は「FALSE」に設定されています。