質問

全て、

私はもともと、Sqlloader(Oracles Dataアップロードツール)と呼ばれるシェルスクリプトを持っていました。

問題は、Sqlloaderが入力としてプレーンテキストのパスワードを取得することでした。そのため、Sqloaderが復号化されたパスワードをコマンド文字列に内部的に渡すJavaアプリケーションを構築することにしました。

例えば

sqlldr user/pass@dbserverコントロール= ../sqlloader.ctl log = sqlloader.log data = mydata.csv

だから私のjavaラッパーでそれは私のシェルスクリプトでこれになりました

java -jar sqlloader.jar sqlloader.ctl mydata.csv

しかし、Sqlloaderがロードするファイルがないと訴えたときに新しい問題が発生しました。いくつかの頭を掻いた後、私のシェルスクリプトの後続のコマンドが私のJavaアプリケーションがまだ実行されている間に実行されているように見えることが発見されました。したがって、それは非同期に振る舞っていました。

次のコマンドは、SQLLoaderが使用する前に使用していた入力ファイルを移動することでした。そこで、私は20秒の睡眠コマンドを入れて、Javaアプリケーションを実行する時間を与えました。

java -jar sqlloader.jar sqlloader.ctl mydata.csv
echo $?
sleep 20
if [ $? -ne 0 ]
    then
        echo "SQLLoader failed during execution, please check the log : " 
        mv mydata.csv

else
    echo "SQLLoader successfully processed file : "
    mv mydata.csv
fi

Unixがこのように振る舞っている理由を誰かが知っていますか?Javaは私のSQLLoaderを別のユーザー/スレッドとして実行しますか?

これは私のJavaコードです:

    Runtime Rt;
Process Prc;
    Prc = Rt.exec("sqlldr user/decryptedpass@DBServer control=../sqlloader.ctl log=sqlloader.log data=mydata.csv);
system.exit(0);

私はそれが非同期であるが何も見つけることができなかったことについて何でもランタイムクラスをチェックしました

http://docs.oracle.com/javase/7/docs/api/java/lang/runtime.html

理論や提案はありますか?

ありがとう

役に立ちましたか?

解決

はい。 Runtime.execをもう一度見ると、指定された環境で新しいプロセスを起動することが指定されています(例:現在の「環境」とは独立して、または非同期に置くと)。使用する必要があります ProcessBuilder Aを作成します プロセス そして、System.Exitを呼び出す前に、そのプロセスが終了するのを待ちます。これは確かに必須ではありません。このようなもの

public static void main(String[] args) {
    // String command = "/usr/bin/sleep 5";
    List<String> command = new ArrayList<String>();
    command.add("c:/cygwin/bin/sleep");
    command.add("5");
    ProcessBuilder pb = new ProcessBuilder(command);
    BufferedReader is = null;
    try {
        System.out.println("Starting command " + command);
        Process p = pb.start();

        int ret = p.waitFor();
        is = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while ((line = is.readLine()) != null) {
            System.out.println(line);
        }
        if (ret == 0) {
            System.out.println("Command has completed.");
            System.exit(ret);
        } else {
            System.out.println("Command completed with return code " + ret);
            System.exit(ret);
        }
    } catch (Exception e) {
        System.out.println("Caught Exception " + e.getMessage()
                + " running command " + command);
        e.printStackTrace();
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
            }
        }
    }
    System.out.println("COMMAND FAILED");
    System.exit(1);
}

他のヒント

プロセスの完了を待つ必要があります。また、すべての出力を読み取る必要があります(stdout Stderr)あなたが開始しているプロセスから。

exec()の後にexit()を呼び出すと、Javaはまさにそれを行います - すぐに終了します。

これは、Runtime.execの落とし穴を説明する記事です。 http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4 (他のページも検討してください)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top