1

RTFドキュメントの作成を管理するクラスと、表示用のXMLファイルを使用してRTFエディターを呼び出すそのクラスのメソッドがあります。

1人を除くすべてのユーザーが、問題なくこのエディターにアクセスできます。この1人のユーザーは、アプリケーションがハングするという問題に常に遭遇します。ログにエラーはありません。通常、この種の問題は簡単に特定、再現、修正できますが、再現することができないため、デバッグの試みは失敗します。

基本的にコードは次のとおりです。

int exitVal = CUBSRTFEditor.runRTFEditor("c:\\tmp\\control"+ap_doc_id+".xml", xml,"I:\\AppealsLetters.exe /process \"c:\\tmp\\control"+ap_doc_id+".xml\"");

public static int runRTFEditor(String xmlLocation, String xmlContent, String executePath)
{
    int exitVal = 0;
    createLocalFile(xmlLocation, xmlContent);

    try
    {
        System.out.println("executePath must = "+executePath);
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec(executePath);
        System.out.println("after executePath runs");

        //exhaust that stream before waiting for the process to exit
        InputStream inputstream = proc.getInputStream();
        InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
        BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
        // read the ls output
        String line;
        while ((line = bufferedreader.readLine())!= null)
        {
            System.out.println(line);
        }
        exitVal = proc.waitFor();
    }
    catch (Throwable t)
    {
        t.printStackTrace();
    }

    CUBSRTFEditor.deleteTempFile(xmlLocation);

    return exitVal;
}

最後の出力は最初のSystem.outです。xmlファイルを取得して他のPCで実行すると、問題なく実行されます。proc.getErrorStream()またはproc.getOutputStream()に有用な情報が表示されません。

この問題に関するJDKのJavadocドキュメント(execのハング): 一部のネイティブプラットフォームは、標準の入力ストリームと出力ストリームに制限されたバッファサイズしか提供しないため、サブプロセスの入力ストリームの書き込みまたは出力ストリームの読み取りに失敗すると、サブプロセスがブロックされる可能性があります。そしてデッドロックさえ。

プロセスが終了するのを待つ前にそのストリームを使い果たしてみましたが、そのポイントに到達していないように見えるため、役に立たないようです(2番目のSystem.outは表示されません)

これを間違って実装しましたか?重要なものが欠けていますか?プロセスからより多くの情報を得る方法についてのアイデアは素晴らしいでしょう。

ハマった....

4

2 に答える 2

2

Runtime.exec()は、一見厄介な小さなスパッドです。この記事(古いですが、まだ関連性があります)は非常に役に立ちました。非常にガンクしやすいサンプルコードについては、いつでも4ページにスキップできます。:-)

一見すると、コードはproc.getOutputStream()とproc.getErrorStream()の両方を処理する必要があります。これは、これらのストリームを別々のスレッドで処理するのに十分な理由です。

于 2009-05-06T18:07:41.907 に答える
0

変更が本日本番環境に移行して機能したため、これを更新したいと思いました。BlairHippoの提案に基づいて、匿名の内部クラスと連携して、エラーストリームと入力ストリームの両方を使い果たすための個別のスレッドを作成するようにしました。

new Thread(new Runnable(){
    public void run()
    {
        try
        {
            BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
            String line;
            while ((line = br.readLine())!= null)
            {
                System.out.println(line);
            }
        }
        catch (Throwable t)
        {
            t.printStackTrace();
        }
    }
}).start();
于 2009-05-13T20:12:57.060 に答える