Команда Maven mvn запускается без ошибок из терминала, но не из python - PullRequest
5 голосов
/ 21 марта 2020

Я пытаюсь запустить проект maven из python скрипта. Я установил apache Maven. Выполнение команды: mvn exec:java -D"exec.mainClass"="org.matsim.project.RunMatsim" из терминала в папке проекта, где находится pom. xml, не создает ошибок и проект работает правильно.

Но при запуске следующего кода из моего python script

import subprocess as sp

def execute(cmd):
    popen = sp.Popen(cmd, stdout=sp.PIPE, universal_newlines=True,shell=True)
    for stdout_line in iter(popen.stdout.readline, ""):
        yield stdout_line 
    popen.stdout.close()
    return_code = popen.wait()
    if return_code:
        raise sp.CalledProcessError(return_code, cmd)

for path in execute(["mvn", "exec:java" ,'-D"exec.mainClass"="org.matsim.project.MatsimRun"']):
    print(path, end="")

Я получил следующую ошибку:

[ОШИБКА] Цели для этой сборки не указаны. Вы должны указать действительную фазу жизненного цикла или цель в формате: или: [:] :. Доступные этапы жизненного цикла: проверка, инициализация, генерация-источники, процессы-источники, генерация-ресурсы, процессы-ресурсы, компиляция, классы процесса, генерация-тестирование источников, процесс-тестирование-источники, генерация-тестирование-ресурсы, процесс -test-resources, test-compile, process-test-classes, test, prepare-package, package, pre -интеграционный тест, интеграционный тест, post-интеграционный тест, verify`

Почему это дело? Что может быть не так?

Полученные предупреждения одинаковы для обоих случаев (терминал, python скрипт).

Ответы [ 4 ]

4 голосов
/ 08 апреля 2020

Обычно, когда у меня возникают проблемы с аргументами при запуске программы из java / python / et c. Я обертываю команду, которую хочу использовать, в sh -c, например так:

sp.Popen(['/bin/sh', '-c', "mvn exec:java -D\"exec.mainClass\"=\"org.matsim.project.MatsimRun\""])

Вышеприведенное, кажется, работает правильно для меня. Имейте в виду, что это может иметь последствия для безопасности, убедитесь, что команда, введенная в качестве третьего параметра sh, никогда не подключается к inte rnet hate.

Хорошо, теперь почему ваш код не работает?

python документы говорят, что shell=True эквивалентно:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

Итак, хорошая гипотеза состоит в том, что sh игнорирование arg[1] и дальнейших аргументов. Вы можете проверить это, выполнив:

<censored>@debian:~$ sh -c echo "sfaklg"

<censored>@debian:~$ 

Посмотрите, как echo не получает ожидаемые аргументы. Это согласуется с разными методами / оболочками:

<censored>@debian:~$ dash -c echo "sfaklg"

<censored>@debian:~$ bash -c echo "sfaklg"

<censored>@debian:~$ zsh -c echo "sfaklg"

<censored>@debian:~$ zsh -c echo sfaklg

<censored>@debian:~$ bash -c echo sfaklg

<censored>@debian:~$ 

Страница man для bash говорит:

Если присутствует опция - c, то команды читать из первого неопционального аргумента command_string. Если после command_string есть аргументы, первый аргумент присваивается $ 0, а все остальные аргументы присваиваются позиционным параметрам. Присвоение $ 0 устанавливает имя оболочки, которое используется в предупреждениях и сообщениях об ошибках.

Другими словами sh -c предназначено для запуска сценариев оболочки, которые ожидают, что аргументы будут переданы с $1, $2, ....

Так что же вам делать?

Подозревается, что вы хотите запустить maven в оболочке, потому что для этого требуется JAVA_HOME или аналогичные переменные среды, чтобы быть набор. Этот вопрос дает примеры того, как установить / изменить переменные среды, хотя вам все еще может понадобиться shell=True. В этом ответе также предлагается использовать команду env для переопределения переменных среды.

Наконец, вы можете найти этот вопрос полезным.

0 голосов
/ 10 апреля 2020

Лично я думаю, что одной из самых больших проблем, стоящих перед программистами, которые пишут код в разных средах программирования, является использование двойных кавычек ("") и одинарных кавычек (''), которые могут вызывать раздражающие проблемы, подобные вашей.

Чтобы справиться, вы можете использовать плагины, а не использовать встроенные команды maven. Добавьте следующий плагин в ваш файл pom.xml, а затем выполните ваше приложение намного проще.

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.4.0</version>
  <configuration>
    <mainClass>org.matsim.project.MatsimRun</mainClass>
  </configuration>
</plugin>

В вышеупомянутом плагине предполагается, что ваш класс Main равен org.matsim.project.MatsimRun. Чтобы запустить плагин из командной строки, просто запустите:

mvn exec:java

Надеюсь, это поможет!

0 голосов
/ 10 апреля 2020

Просто измените строку ниже

["mvn", "exec:java" ,'-D"exec.mainClass"="org.matsim.project.MatsimRun"']

с

["mvn", "exec:java" ,"-D\"exec.mainClass\"=\"org.matsim.project.MatsimRun\""]
0 голосов
/ 03 апреля 2020

Попробуйте удалить двойные кавычки, окружающие exec.mainClass, ie:

mvn exec:java -Dexec.mainClass="org.matsim.project.MatsimRun"

вместо:

mvn exec:java -D"exec.mainClass"="org.matsim.project.MatsimRun"
...