ProcessBuilder не может найти файл данной команды - PullRequest
0 голосов
/ 24 января 2020

Я создаю инструмент CLI, который запускает следующую команду Maven

mvn archetype:generate -B -DarchetypeGroupId=me.pablo -DarchetypeArtifactId=fleeti-archetype -DarchetypeVersion=1.0 -Dversion=1.0 -DgroupId=me.pablo -Dpackage=me.pablo -Dname=Test -DartifactId=test

она должна выполняться в следующем каталоге

C:\Users\35356\Desktop\Test

Теперь я создал свою собственную служебный класс для запуска команд, которые мне нужны, используя ProcessBuilder :

package me.pablo.processes;

import me.pablo.FleetiMessage;
import me.pablo.FleetiMessageType;
import me.pablo.commands.Command;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.Arrays;

public class FleetiProcess
{
    private List<Command> commands;
    private List<Process> allProcesses;

    public FleetiProcess(final List<Command> commands) {
        this.commands = commands;
        this.allProcesses = new ArrayList<>();
    }

    public void execute() {
       runProcess();
    }

    public void executeAsync(final int delayInSeconds) {
        Executors.newSingleThreadScheduledExecutor().schedule(this::runProcess, delayInSeconds, TimeUnit.SECONDS);
    }

    public void execute(final int delayInSeconds) {
        Executors.newSingleThreadScheduledExecutor().schedule(this::stopFleetiProcess, delayInSeconds, TimeUnit.SECONDS);
        runProcess();
    }

    public void stopFleetiProcess() {
        allProcesses.forEach(Process::destroyForcibly);
    }

    private void runProcess() {
        commands.forEach(command -> {
            // Debug messages
            System.out.println("Raw command is \n" + command.getRawCommand());
            System.out.println("Split command is \n" + Arrays.toString(command.getRawCommand().split(" ")));
            System.out.println("Target file exist: \n" + new File(command.getPath()).exists());

            final ProcessBuilder commandBuilder = new ProcessBuilder();
            commandBuilder.command(command.getRawCommand().split(" "));
            commandBuilder.directory(new File(command.getPath()));
            try {
                final Process commandProcess = commandBuilder.start();
                final StreamGobbler streamGobbler = new StreamGobbler(commandProcess.getInputStream(), System.out::println);
                Executors.newSingleThreadExecutor().submit(streamGobbler);
                allProcesses.add(commandProcess);

                int exitVal = commandProcess.waitFor();
                if (exitVal == 0) {
                    FleetiMessage.printMessage(
                            new FleetiMessage(FleetiMessageType.SUCCESS, "Successfully ran process for " + command.getRawCommand()));
                } else {
                    FleetiMessage.printMessage(
                            new FleetiMessage(FleetiMessageType.ERROR, "Could not run process for command " + command.getRawCommand()));
                }
            } catch (final IOException | InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

    private static class StreamGobbler implements Runnable {
        private InputStream inputStream;
        private Consumer<String> consumer;

        StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
            this.inputStream = inputStream;
            this.consumer = consumer;
        }

        @Override
        public void run() {
            new BufferedReader(new InputStreamReader(inputStream)).lines()
                    .forEach(consumer);
        }
    }
}

Каждый раз, когда я запускаю этот код, я сталкиваюсь с одной и той же ошибкой:

java .io.IOException: не удается запустить программу "mvn" (в каталоге "C: \ Users \ 35356 \ Desktop \ Test"): ошибка CreateProcess = 2, система не может найти указанный файл

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

Однако я точно знаю, что файл существует. Это полный вывод консоли:

Raw command is
mvn archetype:generate -B -DarchetypeGroupId=me.pablo -DarchetypeArtifactId=fleeti-archetype -DarchetypeVersion=1.0 -Dversion=1.0 -DgroupId=me.pablo -Dpackage=me.pablo -Dname=Test -DartifactId=test
Split command is
[mvn, archetype:generate, -B, -DarchetypeGroupId=me.pablo, -DarchetypeArtifactId=fleeti-archetype, -DarchetypeVersion=1.0, -Dversion=1.0, -DgroupId=me.pablo, -Dpackage=me.pablo, -Dname=Test, -DartifactId=test]
Target file exist:
true
java.io.IOException: Cannot run program "mvn" (in directory "C:\Users\35356\Desktop\Test"): CreateProcess error=2, The system cannot find the file specified
        at java.base/java.lang.ProcessBuilder.start(Unknown Source)
        at java.base/java.lang.ProcessBuilder.start(Unknown Source)
        at me.pablo.processes.FleetiProcess.lambda$runProcess$0(FleetiProcess.java:53)
        at java.base/java.lang.Iterable.forEach(Unknown Source)
        at me.pablo.processes.FleetiProcess.runProcess(FleetiProcess.java:43)
        at me.pablo.processes.FleetiProcess.execute(FleetiProcess.java:26)
        at me.pablo.commands.FleetiCreateAppCommand.run(FleetiCreateAppCommand.java:89)
        at picocli.CommandLine.executeUserObject(CommandLine.java:1729)
        at picocli.CommandLine.access$900(CommandLine.java:145)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2101)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2068)
        at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:1935)
        at picocli.CommandLine.execute(CommandLine.java:1864)
        at me.pablo.FleetiCLI.main(FleetiCLI.java:19)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
        at java.base/java.lang.ProcessImpl.create(Native Method)
        at java.base/java.lang.ProcessImpl.<init>(Unknown Source)
        at java.base/java.lang.ProcessImpl.start(Unknown Source)
        ... 14 more 

Я запустил этот код в MacOS и работал отлично. Эта проблема возникает только при работе на Windows. Кто-нибудь знает в чем может быть проблема?

...