2009-03-13 4 views
2

Я унаследовал кодовую базу веб-сервисов Java (BEA/Oracle Weblogic) и вам нужно запустить/запустить внешнее фоновое приложение с веб-сервиса.Лучший способ запуска внешнего процесса с веб-службы Java?

Я уже пробовал:

ProcessBuilder pb = new ProcessBuilder(arg); 
pb.start(); 

, а также:

Runtime.exec(cmdString); 

Но я испытываю странное поведение при запуске приложения таким образом (то есть запущенное приложение перестает работать, даже если процесс по-прежнему активен. - Приложение отлично работает при ручном запуске из обычной командной строки).

Есть ли лучший способ запуска внешних процессов?

EDIT: ----------------------

У меня есть некоторая дополнительная информация, которая может помочь пролить свет на эту проблему.

  • Процесс, который мы пытаемся начать потребует часов, чтобы завершить так дожидаясь завершения (с использованием waitfor()) в WebService не будет идеальный сценарий.
  • Да, процесс, который мы пытаемся начать с WebService был создан одним из членов команды [кия: ваши глаза ролл ... теперь]

Я имел успех когда я использую процесс строителя для запуска сценария bash, где внешнее приложение запускается как фоновый процесс (с использованием «&»).

#!/bin/bash 
java -jar myApp.jar & 

Это явно создает осиротевший процесс, но по крайней мере приложение продолжает выполнять.

ответ

2

Проще говоря: если запущенное приложение пишет SDTOUT/STDIN и не смывать их часто (см Process.getErrorStream/Process.getInputStream), то процесс будет блокировать, когда буфер заполнен (это действительно мало, 4 КБ или меньше).

Я рекомендую вам вызвать ProcessBuilder.redirectErrorStream() перед началом процесса. Затем создайте поток с методом run() в соответствии с строками:

public void run() { 
    BufferedReader reader = 
     new BufferedReader(new InputStreamReader(process.getInputStream())); 
    String line; 
    while ((line = reader.readLine()) != null) { 
     System.out.println(line); 
    } 
} 
0

Я предполагаю, что проблема может быть в потоке, который запускает процесс, ПРЕКРАЩАЕТСЯ или что-то еще после завершения запроса. Попробуйте использовать один поток в приложении, который, как вы уверены, всегда поддерживается в жизни, вы можете использовать его для запуска процессов, выполняя вызовы с него из других потоков.

1

Правильно ли вы обрабатываете стандартный ввод и вывод процесса? Если стандартный ввод или вывод обрабатывается вашим приложением, и вы неправильно его обрабатываете, тогда выполняемый процесс будет зависать в ожидании ввода-вывода.

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

2

Во-первых, это происходит в Windows или Linux? Кроме того, что такое запущенное приложение, которое должно быть более или менее выполнено? (это сценарий? это бинарный? ваш двоичный?)

EDIT

ОК, так что начиная bash скрипт (используя ProcessBuilder), который в свою очередь порождает новую JVM (java -jar myApp.jar) работает.

Что происходит, когда вы пытаетесь создать новую JVM напрямую используя ProcessBuilder? Изначально вы сказали:

запущенного приложения перестает работать

  1. По запущенного приложения вы имеете в виду "Java -jar MyApp.jar", когда вызывается непосредственно, не через промежуточный bash сценарий ?
  2. Каковы точные и полные параметры (и их значения), которые вы передаете различным методам ProcessBuilder (и в каком порядке) при попытке запустить Java напрямую, и эта новая JVM перестает работать? (Например, предоставить аннотированный код)
  3. При установке lsof на вашем * NIX машины, какой файл будет показано, что связано с файловым дескриптором 2 (посмотреть на FD колонки) при запуске: lsof -p 1234 (где 1234 идентификатор процесса из «висели» JVM?) Возможно, было бы интересно прикрепить весь вывод команды lsof.
  4. Что добавлено к файлу, указанному на шаге 3 выше (для дескриптора файла 2), до нескольких секунд после выдачи команды: kill -QUIT 1234 (где 1234 - это идентификатор процесса «висячей» JVM?)
+0

Спасибо за дополнительные вопросы. Я отредактировал мой вопрос, чтобы включить следующее: «Да, процесс, который мы пытаемся начать с веб-службы, был создан другим членом команды [cue: your eyes roll ... now]» – Nate

+0

Также показано то же поведение как в Windows, так и в Linux. – Nate

2

«перестает работать, несмотря на то, что процесс все еще активен» Предполагаю, что вы можете ожидать выхода из приложения, которое вы запустили и ничего не получаете.

Попробуйте использовать следующее:

ProcessBuilder pb = new ProcessBuilder(arg); 
Process p = pb.start(); 
p.waitFor(); 

WAITFOR() вызывает текущий поток ждать, если это необходимо, до тех пор, процесс, представленный этим объектом процесса не прекращается.

http://java.sun.com/javase/6/docs/api/java/lang/Process.html#waitFor()

+0

Спасибо за предложение Мартина. К сожалению, я не могу использовать «waitFor()», поскольку процесс, который я пытаюсь запустить, может занять до 4 часов. - С тех пор я отредактировал мой главный вопрос. – Nate

Смежные вопросы