2013-08-14 3 views
1

Я хочу запустить веб-сервис через исполняемый jar, который я создаю (чтобы в конечном итоге я мог использовать procrun, чтобы он запускался как служба Windows). В настоящее время веб-сервис запускается через командную строку, вызывая основной метод в классе.Java, как сохранить ссылку на процесс, чтобы я мог запускать process.destroy()

Вот мой код до сих пор:

public class test 
{  
    private static boolean stop = false; 
    private static Process process; 

    public static void start(String[] args) 
    { 
     String classpath = "my\\classpath\\test.jar"; 

     ProcessBuilder processBuilder = new ProcessBuilder("C:\\java\\jdk1.6.0_43\\bin\\java", 
                  "-cp", classpath, 
                  "com.test.theJavaWebServiceWithAMainMethod"); 
     try 
     { 
      process = processBuilder.start(); 
     } 
     catch (IOException e1) 
     { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
    } 

    public static void stop(String[] args) 
    { 
     stop = true; 

     process.destroy(); 
    } 

    public static void main(String[] args) 
    { 
     if (args != null && args.length > 0) 
     { 
      String command = args[0]; 

      if ("start".equals(command)) 
      { 
       start(args); 
      } 
      else if ("stop".equals(command)) 
      { 
       stop(args); 
      } 
     } 
     else 
     { 
      throw new IllegalArgumentException("command missing"); 
     } 
    } 

} 

Запуск работает отлично. Я вижу, что процесс запускается в диспетчере задач, и теперь я могу подтянуть WSDL. Однако, когда я иду, чтобы убить процесс через process.destroy() (вызывая основной метод с аргументом stop), я получаю исключение нулевого указателя, которое я предполагаю, потому что это новый экземпляр jvm, поэтому он не знает процесс с того момента, когда я start. Каков наилучший способ сохранить этот объект процесса или pid или что-то еще, поэтому, когда я перехожу к вызову stop, я могу найти и убить запущенный веб-сервис (java-процесс)?

+0

Вы правы, думая, что это другой процесс java (и JVM). –

ответ

0

Вы выполняете свою программу «тест» дважды, что приводит к двум полностью разным экземплярам программы, и они не имеют ссылки на друг друга. Поэтому, когда вы вызываете программу «test» с помощью команды stop, переменная process имеет значение null, поскольку она не была создана в текущей программе.

Варианты:

  • Перепишите ваш основной способ блокировать, ожидая команды "стоп". Это означало бы, что start/stop не были отдельными асинхронными программами. Вы должны запустить программу, и тогда вы дождитесь, когда вы войдете в команду остановки перед выходом.

  • Вы можете придумать способ передать другое приложение «удаленно» ... хотя все работает на одной машине. Это легко сделать с помощью простого сетевого сокета, и это очень распространенный подход. (Оформить заявку на запуск/остановку Tomcat для примера ... хотя это сложнее, чем вам нужно.) Подводя итог ... после запуска основная программа прослушивается на серверном сокете. Последующая «программа остановки» подключается к этому серверному сокету как клиент, чтобы уведомить основную программу, которую он должен остановить.

  • Вы можете использовать базовые инструменты ОС, чтобы найти и остановить программу. См. Этот ответ: How to find and kill running Win-Processes from within Java?. Трудно сделать кросс-платформу и в целом, хотя.

Это не совсем ясно, что именно вы хотите сделать, хотя и почему вы выполняете свой веб-сервис в виде отдельной программы через ProcessBuilder. В зависимости от ваших требований, может быть, вы могли бы вместо того, чтобы сделать что-то вроде этого:

public void start(String[] args) 
{ 
    try 
    { 
     com.test.theJavaWebServiceWithAMainMethod.main(args); 
    } 
    catch (IOException e1) 
    { 
     e1.printStackTrace(); 
    } 
} 

Это было бы начать службу, конечно, и тогда вы можете управлять-C для завершения программы.

+0

Спасибо за советы. Я пробовал первый пункт. Я добавил цикл while (while! Stop) к основному методу, поэтому мое приложение никогда не завершится, и это нормально.Я видел процесс java для запуска webservice (в дополнение к моему java-процессу для этого приложения-оболочки), но WSDL не отображался, пока я не уничтожу приложение-оболочку. Вы знаете, почему это произойдет? – yellavon

+0

Вы спали во время цикла? Если нет, то, возможно, цикл while потреблял 100% процессор, а служба WSDL просто слишком долго начинала или отвечала. Вместо цикла while попробуйте прочитать из System.in. Это будет заблокировано, пока вы не нажмете клавишу и не будете использовать циклы процессора. Пример: http://stackoverflow.com/questions/6032118/make-the-console-wait-for-an-user-input-to-close – kaliatech

+0

Спасибо за ваш обновленный ответ. Я действительно могу просто вызвать класс напрямую, не думал об этом: P Я добавил спать и вызвал класс напрямую, и веб-сервис снова начинается. – yellavon

0

Вместо того, чтобы запускать свою исполняемую банку, как и вы, вы можете конвертировать свою программу, чтобы начать работу с Windows. Затем он сможет реагировать на запрос на завершение работы Windows.