Я запускаю wkhtmltopdf из моего Java-приложения (часть сервера Tomcat, работающего в режиме отладки в Eclipse Helios на 64-битной Win7): я хотел бы дождаться его завершения, затем Do More Stuff.
String cmd[] = {"wkhtmltopdf", htmlPathIn, pdfPathOut};
Process proc = Runtime.getRuntime().exec( cmd, null );
proc.waitFor();
Но waitFor()
никогда не возвращается.Я все еще вижу процесс в диспетчере задач Windows (с командной строкой, которую я передал exec (): выглядит хорошо).И ЭТО РАБОТАЕТ.wkhtmltopdf создает PDF-файл, который я ожидал, именно там, где я и ожидал.Я могу открыть его, переименовать, что угодно, даже когда процесс еще запущен (до того, как я вручную завершу его).
Из командной строки все в порядке:
c:\wrk>wkhtmltopdf C:\Temp\foo.html c:\wrk\foo.pdf
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
Процесс завершается очень хорошо, и жизнь продолжается.
Так что же такое runtime.exec()
в результате чего wkhtmltopdf никогда не завершится?
Я мог бы взять proc.getInputStream () и поискать "Done", но это ... подло.Я хочу что-то более общее.
Я вызывал exec () с рабочим каталогом и без него.Я пробовал с и без пустого массива "env".Никакой радости.
Почему мой процесс зависает, и что я могу сделать, чтобы это исправить?
PS: я пробовал это с парой других приложений командной строки, и они оба показываюттакое же поведение
Дальнейшие проблемы с исполнением.
Я пытаюсь прочитать стандартную ошибку и ошибку, но безуспешно.Из командной строки я знаю, что должно быть что-то удивительно похожее на мой опыт работы с командной строкой, но когда я читаю поток ввода, возвращаемый proc.getInputStream (), я сразу получаю EOL (-1, я использую inputStream.read()
).
Я проверил JavaDoc для процесса и обнаружил это
Родительский процесс использует эти потоки для подачи входных данных и получения выходных данных из подпроцесса.Поскольку некоторые собственные платформы предоставляют ограниченный размер буфера только для стандартных входных и выходных потоков, невозможность оперативной записи входного потока или чтения выходного потока подпроцесса может привести к блокировке подпроцесса [b] и даже к тупиковой блокировке [/ b].
Акцент добавлен.Я попробовал это.Первое чтение () в Standard Out inputStream блокировалось до тех пор, пока я не завершил процесс ...
WITH WKHTMLTOPDF
С общей командной строкой ap & no paramsпоэтому он должен «сбросить использование и прекратить», он высасывает соответствующий std :: out, а затем завершает.
Интересно!
Проблема с версией JVM?Я использую 1.6.0_23.Последняя версия ... v24.Я только что проверил журнал изменений и не вижу ничего многообещающего, но все равно попробую обновить.
Хорошо.Не позволяйте входным потокам заполняться, иначе они будут блокироваться.Проверьте..close()
также может предотвратить это, но не очень ярко.
Это работает в целом (включая общие приложения командной строки, которые я тестировал).
В частности однако, оно падает.Похоже, что wkhtmltopdf использует некоторые манипуляции с терминалом / курсор для создания ASCII-графического индикатора выполнения.Я считаю, что это заставляет inputStream немедленно возвращать EOF, а не давать мне правильные значения.
Есть идеи?Едва ли это соглашение, но определенно было бы приятно иметь.