Вопрос

У меня есть класс, который управляет созданием документов RTF, и метод в этом классе, который вызывает редактор RTF с файлом XML для отображения.

Все пользователи, кроме одного, могут получить доступ к этому редактору без каких-либо проблем. Этот один пользователь постоянно сталкивается с проблемой, когда его приложение просто зависает. Там нет ошибок ни в одном журнале. Обычно такого рода проблемы легко идентифицировать, воспроизвести и исправить, однако я не могу за всю жизнь воспроизвести ее, поэтому мои попытки отладки проваливаются.

В основном код выглядит следующим образом:

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-файл и выполняю его на любом другом ПК, он выполняется без проблем. Я не вижу полезной информации в proc.getErrorStream () или proc.getOutputStream ().

Документация Javadoc JDK по этой проблеме (exec висит): Поскольку некоторые собственные платформы предоставляют ограниченный размер буфера только для стандартных входных и выходных потоков, невозможность оперативной записи входного потока или чтения выходного потока подпроцесса может привести к блокировке подпроцесса и даже к взаимной блокировке.

Я пытаюсь исчерпать этот поток перед тем, как дождаться завершения процесса, и это, кажется, не помогает, поскольку кажется, что он никогда не достигнет этой точки (второй System.out не отображается)

Я неправильно это реализовал? Я что-то упустил? Любые идеи о том, как получить больше информации из процесса, были бы отличными.

Я застрял ....

Это было полезно?

Решение

Runtime.exec () - обманчиво скверная работа. Я нашел эту статью (старая, но по-прежнему актуально) быть весьма полезным. Вы всегда можете перейти к странице 4 для некоторого примера кода, который можно легко продать. : -)

На первый взгляд, ваш код должен обрабатывать как proc.getOutputStream (), так и proc.getErrorStream (), что является хорошей причиной для обработки этих потоков в отдельных потоках.

Другие советы

Я хотел обновить это, потому что изменения вошли в производство сегодня и работали. Основываясь на предложениях BlairHippo, я заставил его работать с анонимным внутренним классом, чтобы создать отдельный поток для исчерпания потоков Error и Input.

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();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top