2016-12-09 4 views
1

開発中のシステム内から明示的にJVMを呼び出すのは、例えばsystemAです。 。別のJREインスタンスにコマンドを処理するためにコマンドラインで「クロスボーダー」RuntimeExceptionをキャッチする - あるjarに由来し、別のjarでスローされた

これを行うためのコマンドは

java -cp thisJar.jar;thatJar.jar -Djava.security.manager=mySM -Djava.security.policy=my.policy TheClass 

ある、と私はProcessProcessBuilderを使用して、このコマンドを実行している:

StringBuilder sbResult = new StringBuilder(); 
    ProcessBuilder builder = new ProcessBuilder(command); 
    builder.redirectErrorStream(true); 
    Process p=null; 
    try { 
     p = builder.start(); 
     p.waitFor(); 
     try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) { 
      String line = ""; 
      while ((line = br.readLine()) != null) 
       sbResult.append(line+System.getProperty("line.separator")); 
     } catch (Throwable t) { commandResult.error.add(t); } 
     commandResult.text = sbResult.toString(); 
    } catch (Throwable e1) { commandResult.error.add(e1); } 

タイプCommandResultはプレーンで十分です:systemAで「注目」のエラーがありますたび

public static class CommandResult { 
    public String text=""; 
    public List<Throwable> error = new LinkedList<>(); 
    public int statusCode; 
} 

、私がキャッチしe.printStackTrace()でそれをプリントアウトしています。これで、私はそれが上記のコードによってキャプチャされることを期待しています。 しかし、tiはそうではありません。コマンドプロンプトでエラーがスローされ、エコーされます。ただし、上記コードのBufferedReaderには表示されません。これは、のエラーが1つのjarファイルで発生しているため、他のjarファイル(?)のクラスにスローされているためです()。

このエラーをプログラムで取り込む方法はありますか?

私が考えることができる唯一の方法は、エラーをスローするクラスが他のjarのクラスを読むことができるようにファイルに書き込むことです。メソッドを呼び出すことによって、他のjarクラスのクラスにエラーテキストを渡すことができます。よりよい解決策が必要です。

TIA。

// --------------------------

UPDATE

AR.3の便利な提案以下、次のことを試してみました:

StringBuilder sbResult = new StringBuilder(); 
ProcessBuilder builder = new ProcessBuilder(command); 
Process p=null; 
try { 
    p = builder.start(); 
    p.waitFor(); 
    try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) { 
     String line = ""; 
     while ((line = br.readLine()) != null) 
      sbResult.append(line+System.getProperty("line.separator")); 
    } catch (Throwable t) { commandResult.error.add(t); } 
    commandResult.text = sbResult.toString(); 

    try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()))) { 
     String line = ""; 
     while ((line = br.readLine()) != null) 
      sbResult.append(line+System.getProperty("line.separator")); 
    } catch (Throwable t) { commandResult.error.add(t); } 
    commandResult.text += sbResult.toString(); 

} catch (Throwable e1) { commandResult.error.add(e1); } 

StringBuilder sbResult = new StringBuilder(); 
ProcessBuilder builder = new ProcessBuilder(command); 
Process p=null; 
try { 
    p = builder.start(); 
    p.waitFor(); 
    try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()))) { 
     String line = ""; 
     while ((line = br.readLine()) != null) 
      sbResult.append(line+System.getProperty("line.separator")); 
    } catch (Throwable t) { commandResult.error.add(t); } 
    commandResult.text = sbResult.toString(); 
} catch (Throwable e1) { commandResult.error.add(e1); } 

はまだその例外を見ていません。以前からの変更はありません。

+0

を、例外スタックトレースを 'commandResult.text'文字列フィールドに格納する必要があります。 'commandResult.error'は、サブプロセスからの例外をすべて検出しません。それは2つの別々のJavaプロセスでどのように動作するかではありません。 – manouti

+0

私はそれらを探しています - .textと.error。そのエラーはどこにもありません。 – Roam

+0

原則として、デバッグインタフェースを使用して例外ブレークポイントを設定することはできますが、これは本番環境で行うことは望ましくありません。その代わりに、アプリケーション間に明示的な通信チャネルのいくつかの形式を実装する必要があります – the8472

答えて

0

Javaアプリケーション間に「クロスボーダー」がスローされるという概念はありません。フォークプロセスとサブプロセスは、異なるJVMで実行される完全に独立したプロセスです。通常、サブプロセスのエラーストリームに例外が出力されます。そのような例外やエラーストリームに出力されたエラーを検出するには、出力ストリームで行ったのと同様の方法で、そのストリームを読み取る必要があります。

ただし、このステートメントはエラーストリームを出力ストリームにリダイレクトするため、builder.redirectErrorStream(true);というステートメントを削除する必要があります。このため、2種類の出力を区別することが困難です。エラー出力をキャッチするためには、ちょうどProcess#getErrorStream読み:あなたのアップデートで

sbResult = new StringBuilder(); 
// this read the error stream of the subprocess 
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()))) { 
    String line = ""; 
    while ((line = br.readLine()) != null) { 
     sbResult.append(line+System.getProperty("line.separator")); 
    } 
    // errorString would contain the error generated by the subprocess, including thrown exceptions 
    commandResult.errorString = sbResult.toString(); 
} 
+0

変更 - 同じ結果。 – Roam

+0

更新されたコードを投稿できますか?そして 'builder.redirectErrorStream(true)'を削除しましたか?あなたの質問をより再現性のあるものにすると、それはあなたにもっと役立ちます。 – manouti

+0

もう少し見てみましょう。このprjの間に中途半端なこと - 再現するのは難しい – Roam

関連する問題