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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With