Из программы Java запустите скрипт Python, который прослушивает соединения сокетов из указанной программы Java

Я пытаюсь запустить скрипт python из моей программы Java. Скрипт python прослушивает соединения сокетов из программы Java и отвечает данными. Для этого я попытался использовать API ProcessBuilder, чтобы:

  1. активировать python virtualenv (находится в моем рабочем каталоге)
  2. запустите мой скрипт Python predprobability.py так, чтобы он начал прослушивать соединения из моей Java-программы. это то, что у меня есть до сих пор:
public class MLClassifierProcess{
                                                //bash location        //activate python venv  //python interpreter      //script
    final String[] command_to_run = new String[] { "/bin/bash", "-c", "/env/bin/activate;", "/env/bin/python","predictprobability.py;" };
    public void startML(){
        ProcessBuilder builder = new ProcessBuilder(command_to_run);
        Process pr = null;

        try {
            pr = builder.start();
        } catch (IOException ioException) {
            System.out.println("error");
        }

    }
    public static void main(String[] args){
        MLClassifierProcess p = new MLClassifierProcess();
        p.startML();
    }

}

однако выполнение основной функции сразу же прекращается, когда скрипт predprobability.py должен продолжать работать бесконечно. Я новичок в API ProcessBuilder, поэтому любые указания о том, как действовать, были бы очень признательны.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
26
2

Ответы 2

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

Если вы хотите, чтобы ваша программа Java продолжала работать до тех пор, пока программа Python не завершит выполнение, вам необходимо, чтобы код Java ожидал надлежащим образом. Вот как это сделать:

public class MLClassifierProcess{
    //bash location        //activate python venv  //python interpreter      //script
    final String[] command_to_run = new String[] { "/bin/bash", "-c", "/env/bin/activate;", "/env/bin/python","predictprobability.py;" };
    public Process startML(){
        ProcessBuilder builder = new ProcessBuilder(command_to_run);
        Process pr = null;

        try {
            pr = builder.start();
        } catch (IOException ioException) {
            System.out.println("error");
        }
        return pr;
    }
    public static void main(String[] args){
        MLClassifierProcess p = new MLClassifierProcess();
        Process pr = p.startML();
        if (pr != null)
            pr.waitFor();
    }
}

Это имеет смысл, однако запуск этого кода дает нулевое значение для pr - может ли это означать, что мой command_to_run сформирован неправильно, поэтому мой скрипт не выполняется?

Michael 04.04.2021 18:19

Да, похоже, что казнь не удалась. Согласно документации, builder.start() не может вернуть значение null. Значит, это должно вызывать исключение. Ваш код перехватит это исключение и напечатает «ошибку». Это делает это? Если это так, вы должны напечатать исключение, чтобы вы могли видеть, в чем заключается ошибка. При желании вы можете остановиться внутри catch в своем отладчике и таким образом проверить исключение.

CryptoFool 04.04.2021 19:49

Я вижу несколько конкретных вещей: 1) действительно ли ваша виртуальная среда находится в каталоге с именем env в корне вашей файловой системы? 2) Вы уверены, что ваш скрипт python находится в текущем рабочем каталоге, так что он будет найден Python без компонента пути. Вы можете устранить вторую проблему, указав полный путь к вашему скрипту.

CryptoFool 04.04.2021 19:54

В конце концов решение было простым:

 Process process = Runtime.getRuntime().exec("<path/to/venv/python_interpreter> "+"path/to/scripytorun.py)

В моем случае успешная команда была

    Process process = Runtime.getRuntime().exec( System.getProperty("user.dir")+"/env/bin/python "+System.getProperty("user.dir")+"/predictprobability.py");
process.waitFor();

@CryptoFool был прав, указав, что необходим абсолютный путь к ресурсам, поэтому System.getProperty("user.dir") добавлен к относительным путям.

Другие вопросы по теме