2013-11-07 6 views
3

Все,Java-программа, которая вызывает асинхронную внешнюю программу?

Первоначально у меня был сценарий оболочки, называемый SQLLoader (инструмент для загрузки данных Oracles).

Проблема заключалась в том, что SQLLoader вводит простой текстовый пароль в качестве входных данных, поэтому я решил создать приложение Java для вызова SQLLoader, передающего дешифрованный пароль в командную строку.

например.

SQLLDR пользователь/пасс @ контроль DbServer = ../sqlloader.ctl журнал = sqlloader.log данные = mydata.csv

Так что с моей Java обертку он стал это в моем сценарии оболочки

java -jar sqlloader.jar sqlloader.ctl mydata.csv 

Однако новая проблема возникла, когда SQLLoader жаловался, что загрузочного файла не было. После некоторой царапины головы было обнаружено, что последующая команда в моем сценарии оболочки, казалось, выполнялась, пока мое приложение Java все еще работало. Поэтому он вел себя асинхронно.

Следующая команда перемещала входной файл, который использовал sqlloader, прежде чем он сможет получить возможность использовать его. Поэтому я поставил команду спящего режима за 20 секунд, чтобы запустить мое приложение Java.

java -jar sqlloader.jar sqlloader.ctl mydata.csv 
echo $? 
sleep 20 
if [ $? -ne 0 ] 
    then 
     echo "SQLLoader failed during execution, please check the log : " 
     mv mydata.csv 

else 
    echo "SQLLoader successfully processed file : " 
    mv mydata.csv 
fi 

Кто-нибудь знает, почему Unix ведет себя таким образом, делает Java выполнить мой SQLLoader как другой пользователь/нить?

Это мой Java-код:

Runtime Rt; 
Process Prc; 
    Prc = Rt.exec("sqlldr user/[email protected] control=../sqlloader.ctl log=sqlloader.log data=mydata.csv); 
system.exit(0); 

Я проверил время выполнения класса для чего про то, что Асинхронный но не смог найти что-нибудь

http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

Любые теории или предложения?

Благодаря

+0

Что вы делаете в своем коде после exec? – Ingo

+1

system.exit (0); это моя последняя строка в java-программе – kaleeway

+0

Это может быть не в тему, но ...Каково намерение шифровать пароль? Вы действительно жестко задаете пароль в Java String, как ваш пример кода? Если это так, хакер может распаковать файл 'jar' и заглянуть в файл' .class', пароль будет просто открытым. Java 'Runtime.exec' является низкоуровневым и сложным для обработки, и должен быть более простой способ. – miaout17

ответ

3

Да. Если вы снова посмотрите на Runtime.exec, он определит, что он запустит новый процесс в указанной среде (например, независимо от текущей «среды» или, как вы ставите ее асинхронно). Вы должны использовать ProcessBuilder, чтобы создать Process, а затем ждать, пока этот процесс не завершится до вызова System.exit, что, безусловно, не является обязательным. Что-то вроде этого

public static void main(String[] args) { 
    // String command = "/usr/bin/sleep 5"; 
    List<String> command = new ArrayList<String>(); 
    command.add("c:/cygwin/bin/sleep"); 
    command.add("5"); 
    ProcessBuilder pb = new ProcessBuilder(command); 
    BufferedReader is = null; 
    try { 
     System.out.println("Starting command " + command); 
     Process p = pb.start(); 

     int ret = p.waitFor(); 
     is = new BufferedReader(new InputStreamReader(p.getInputStream())); 
     String line; 
     while ((line = is.readLine()) != null) { 
      System.out.println(line); 
     } 
     if (ret == 0) { 
      System.out.println("Command has completed."); 
      System.exit(ret); 
     } else { 
      System.out.println("Command completed with return code " + ret); 
      System.exit(ret); 
     } 
    } catch (Exception e) { 
     System.out.println("Caught Exception " + e.getMessage() 
       + " running command " + command); 
     e.printStackTrace(); 
    } finally { 
     if (is != null) { 
      try { 
       is.close(); 
      } catch (IOException e) { 
      } 
     } 
    } 
    System.out.println("COMMAND FAILED"); 
    System.exit(1); 
} 
+0

Пример кода, пожалуйста, – kaleeway

+0

Получится ли выход из процесса на консоль? – kaleeway

2

Вам нужно ждать завершения процесса, вы должны также прочитать все выходные данные (стандартный вывод и Stderr) от процесса вы начинаете.

Если вы вызовете exit() после exec(), Java сделает именно это - немедленно выйдите.

Настоящая статья содержит пояснения об ошибках Runtime.exec: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4 (также рассмотрим другие страницы).

+2

Чтобы добавить цвет, вызовите '' Prc.waitFor() ''. Избавьтесь от сна, это ошибка времени, ожидающая своего появления. – brettw

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