как я могу выполнить java-команду с помощью java-кода?

Я пытаюсь запустить многоагентную систему, используя код JADE. Обычно я могу запустить систему Jade из командной строки, используя следующую команду:

java jade.Boot -gui

Он также хорошо работает с IDE Netbeans, изменяя свойства проекта и указывая конфигурацию запуска на класс jade.Boot.

Моя проблема: я хочу запустить эту систему с помощью java-кода... скажем, когда пользователь нажимает кнопку, и, насколько я знаю, эта команда, указанная выше, должна работать, используя следующий код:

Process p=null;                                                                                                                                                     
try {
    p = Runtime.getRuntime().exec("java jade.Boot -gui;");
} 
catch (IOException ex) {
    Logger.getLogger(SimulationCreator.class.getName()).log(Level.SEVERE, null, ex);
}
            
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s;
try {
    while ((s = stdInput.readLine()) != null) {
           System.out.println(s);
    }
} catch (IOException ex) {
      Logger.getLogger(SimulationCreator.class.getName()).log(Level.SEVERE, null, ex);
}

Но я ничего не получаю, ни система JADE не работает, ни каких-либо ошибок.

Что мне не хватает?

P.S.: Я работаю над Ubuntu 20.0.

P.S.: запуск других команд с помощью кода, такого как ps -aux, работает очень хорошо!


person Ihab TALEB    schedule 24.06.2020    source источник
comment
Попробуйте прочитать и распечатать поток ошибок, чтобы увидеть, есть ли ошибки. Установлен ли путь к классам в папку, содержащую папку нефрита?   -  person NormR    schedule 24.06.2020
comment
@NormR да, похоже, проблема связана с путем к классу, спасибо! теперь я работаю над ее решением.   -  person Ihab TALEB    schedule 24.06.2020


Ответы (1)


Ваша проблема может заключаться в разнице между PATH текущей запущенной виртуальной машины, по сравнению с оболочкой (bash и т. д.), которую вы используете, и неявной передачей CLASSPATH. Проверьте расположение java, который which java в рабочей оболочке, и попробуйте использовать его в своем exec.

Кроме того, вы не увидите всех проблем при запуске, поскольку вы не получаете доступ к потоку ошибок одновременно с потоком вывода, переход на ProcessBuilder упрощает отладку, поскольку вы можете перенаправлять потоки out/err в файл. Но если JADE работает долго или выдает много вывода, вы должны использовать STDOUT+ERR в фоновых потоках.

Попробуйте это в jshell:

String[] cmd = new String[]{"java", "jade.Boot", "-gui"};
ProcessBuilder pb = new ProcessBuilder(cmd); 
File fileOut = new File("stdout.log"); 
File fileErr = new File("stderr.log"); 
pb.redirectError(fileErr); 
pb.redirectOutput(fileOut); 
Process p = pb.start(); 
int rc = p.waitFor();
String stdout = Files.readString(fileOut.toPath());
String stderr = Files.readString(fileErr.toPath());

System.out.println("Exit   : "+rc +' '+(rc == 0 ? "OK":"**** ERROR ****"));
System.out.println("STDOUT : "+stdout);
System.out.println("STDERR : "+stderr);
person DuncG    schedule 24.06.2020
comment
спасибо за ваш ответ, он хорошо работал на jshell, но дает ClassNotFoundException с кодом, как я могу решить проблему с путем к классам? что касается того, для какой java он дал тот же результат /usr/bin/java @DuncG - person Ihab TALEB; 24.06.2020
comment
Ваш вызов оболочки командной строки, который работает, вероятно, подхватывает нефрит, используя переменную среды CLASSPATH. Попробуйте echo $CLASSPATH, и, возможно, вы можете добавить -cp и это значение к своему запуску из ProcessBuilder (cmd) или передать значение при запуске вашего Java-приложения как -Dmyjade.classpath=whatever и обратиться к System.getProperty("myjade.classpath") после -cp. В качестве альтернативы, если в вашей оболочке уже все настроено, вы можете запустить оболочку, передав команду jade, например `cmd = {bash, -c, java jade.Boot -gui}. - person DuncG; 24.06.2020