Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ProcessBuilder cannot run program found in PATH

Tags:

java

process

I'm trying to run npm through ProcessBuilder.start(). However, in Windows at least, whenever I try to start the process without stating the full path of the executable, the invocation fails with "CreateProcess error=2".

EDIT: the directory of npm is in the PATH environment variable.

Sample code:

public class Main {
    public static void main(String[] args) {
        // Won't work
        invokeCommand(new String[] {"npm", "--version"});

        // Will work
        invokeCommand(new String[] {"C:\\Program Files\\nodejs\\npm.cmd", "--version"});
    }

    private static void invokeCommand(String[] args) {
        System.out.println("INVOKING: " + String.join(" ", args));

        ProcessBuilder pb = new ProcessBuilder(args);

        try {
            Process p = pb.start();
            p.waitFor();

            dumpStdout(p);
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        System.out.println();
    }

    private static void dumpStdout(Process p) throws IOException {
        String line;
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

        while ((line = reader.readLine()) != null) {
            System.out.println("STDOUT: " + line);
        }

        reader.close();
    }
}

Why is it so? Is it because npm is a batch command? That's very inconvenient, not to say inconsistent with other programs like java or node that will run just fine without their full paths. Thank you.

like image 796
Humberto Avatar asked Feb 03 '26 15:02

Humberto


1 Answers

Java does scan the Path for executables, but does not reference the PATHEXT variable. So change your launcher with the file extension of the executable - which is why it works with appending ".cmd".

It would work with the extension {"npm.cmd", "--version"}, or without the extension if you use a terminal such as {"cmd.exe", "/c", yourcommand} as CMD scans the file extensions in the environment variable PATHEXT. Typically set to:

 PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
like image 120
DuncG Avatar answered Feb 06 '26 05:02

DuncG



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!