Runtime.getRuntime (). Exe c не находит версию по умолчанию python - PullRequest
1 голос
/ 01 апреля 2020

Я хотел использовать Runtime.getRuntime().exec для выполнения простого python сценария Runtime.getRuntime().exec("python test.py"), который содержит только несколько импортов, но он завершился ошибкой 1. Я отследил ошибку и обнаружил, что некоторые библиотеки не найдены:

Traceback (most recent call last):
File "/Users/firetiti/NetBeans/FiReTiTiLiB/Test.py", line 6, in <module>
from PIL import Image
ImportError: No module named PIL

Когда я выполнял тот же скрипт в терминале, все было хорошо. Поэтому я заменил python абсолютным путем к python Runtime.getRuntime().exec("/somewhere/in/my/computer/python3.6 test.py"), и это сработало.

Так что, похоже, Runtime.getRuntime().exec не использует настроенную версию python. Как я могу это исправить?

1 Ответ

2 голосов
/ 01 апреля 2020

Если вы запустите exec("python test.py") в Java, попытаетесь преобразовать python в исполняемый файл так же, как это делает любое другое приложение.

Предполагая, что вы используете UNIX, Linux или Ma c OSX, последовательность примерно такая:

  1. JVM выполняет системный вызов fork для создания дочернего процесса. Дочерний процесс наследует переменные среды родительского (JVM) процесса.

  2. Дочерний процесс выполняет системный вызов exe c, передавая ему имя команды, аргументы и переменные среды.

  3. Если имя команды является простым именем, системный вызов пытается преобразовать имя в путь путем поиска в каталогах на пути поиска команд исполняемого файла; то есть с соответствующим набором разрешений на выполнение.

  4. Если исполняемый файл найден, он либо загружается в дочерний процесс, либо интерпретируется как скрипт в зависимости от его подписи.

In В вашем случае это шаг 3, который не работает. В частности, он находит неправильную версию python в пути поиска. Путь поиска определяется переменной среды PATH ... как унаследованной от родительской JVM.

Итак, если вы получаете разные результаты в интерактивной оболочке и из Java, это, скорее всего, означает, что у них разные PATH переменные. Это первое, что нужно проверить. Например, в вашем приложении Java посмотрите, что это выводит:

  System.out.println(System.environ().get("PATH"));

и убедитесь, что первая найденная команда python - это версия, которую вы хотите.

Возможно Решения:

  • Установите PATH перед запуском JVM
  • Используйте ProcessBuilder для выполнения внешней команды с измененной средой
  • Используйте абсолютный путь для команда python.
  • Если это Python 2 против 3, введите имя команды как python2 или python3. (Типичный пакет Linux et c будет ссылаться с python2 и python3 на правильные исполняемые файлы.)
...