Как исправить «CreateProcess error = 2, система не может найти указанный файл», даже если указана переменная Path (кроссплатформенная) - PullRequest
1 голос
/ 05 ноября 2019

Я пытаюсь запустить сборку Maven из скрипта Groovy. Кажется, он не может найти Maven.

Я уже проверил переменную пути, и она содержит правильный путь. Если я специально запускаю mvn через C:/…/mvn.cmd, это работает.

Теперь я использую System.getenv(), который исправил отсутствующую переменную Java_home, но это не помогает с mvn. Довольно странные команды, такие как git …, работают даже без указания среды.

Я также знаю, что могу это исправить, просто открыв cmd и выполнив там команды, но я не могу этого сделать, так как он также должен работать намашина Mac или Linux.

File workingDir = new File(*MYWORKINGDIRECTORY*)
def mvnbuild = 'mvn package'.execute(System.getenv().collect { k, v -> "$k=$v" }, workingdir)

mvnbuild.waitForProcessOutput(System.out, System.err)

Это приводит к следующему сообщению об ошибке:

2019-11-05 13:57:12.631 ERROR *MYSCRIPT* FAILED.
Reason:
java.io.IOException: Cannot run program "mvn" (in directory "C:\Users\*MYWORKINGDIRECTORY*"): CreateProcess error=2, The system cannot find the file specified

Если я запускаю какую-то другую команду, например where, она работает просто отлично:

def mvnbuild = 'where mvn'.execute(System.getenv().collect { k, v -> "$k=$v" }, workingdir)

mvnbuild.waitForProcessOutput(System.out, System.err)

производит

C:\*THECORRECTMAVENPATH*\apache-maven-3.6.0\bin\mvn
C:\*THECORRECTMAVENPATH*\apache-maven-3.6.0\bin\mvn.cmd

Несмотря на то, что при попытке запустить npm

PS выдает ту же ошибку, что и выше, PS: я также проверил System.getenv(), этосодержит правильный путь Maven.

1 Ответ

0 голосов
/ 06 ноября 2019

Причина, по которой вы получаете эту ошибку в Windows, заключается в том, что вы не даете ей полное имя, включая расширение. Вам не нужно указывать полный путь, если каталог содержит переменную Path.

Вы можете ввести mvn в интерпретаторе команд Windows (cmd.exe) ибудет работать, потому что немного умен относительно расширений. Но Groovy и Java не проходят через это.

Вместо этого метод Groovy .execute() делегирует Java ProcessBuilder, который в Windows вызывает встроенную функцию с именем CreateProcess в Win32 API. В этой функции, если вы не укажете расширение, он будет предполагать, что это файл .exe. Вот почему работают команды where (на самом деле where.exe) и git (на самом деле git.exe), но не другие исполняемые типы, такие как .bat и .cmd, такие как mvn.cmd.

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

def mvnFileName = System.properties['os.name'].toLowerCase().contains('windows') ? 'mvn.cmd' : 'mvn'
def mvnbuild = "$mvnFileName package".execute() // ...
...