Runtime exec и специальный редактор RTF
-
06-07-2019 - |
Вопрос
У меня есть класс, который управляет созданием документов 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();