I have following java code
public static void main(String a[]) {
String location = "C:\\Users\\test\\output\\testProject";
File dir = new File("C:\\Users\\test\\cmds");
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", "Start /wait","packageProject.bat",location);
pb.directory(dir);
Process p = null;
try {
p = pb.start();
p.waitFor();
}
catch (IOException e) {
e.printStackTrace();
}
catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("Folder created");
}
Batch file is
cd "C:\Users\test\output\test-master"
mvn clean install -DskipTests
exit
It is packaging file but not command prompt is not closing once process is complete.
Please suggest.
You should remove wrapper CMD.EXE and start, just call the batch file directly as:
String bat = new File(dir, "packageProject.bat").getAbsolutePath();
ProcessBuilder pb = new ProcessBuilder(bat , location);
pb.directory(dir);
Process p = pb.start();
p.waitFor();
If this process generates a lot of output you may run into a second problem if you don't consume error and output streams. You can do this in background threads, or simply send stdout/err to files by adding these calls before pb.start():
pb.redirectOutput(new File(location, "std.out"));
pb.redirectError(new File(location, "std.err"));
Related
I would like to run a hidden script file that resides in the current location using process builder. with the following code
// System.out.println("line"+reader.readLine());
ProcessBuilder builder = new ProcessBuilder(shfile.getAbsolutePath());
builder.redirectErrorStream(true);
Process process = builder.start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = null;
System.out.println("out"); //===printing this
while (null != (output = br.readLine()))
{
System.out.println("in"); //not printing this
System.out.println(">>"+output);
}
int rs = process.waitFor();
but it hangs in the br.readline()..
but when I run the same script file using the following command in terminal
sh .script.sh
it executes and gives me the expected results
I looked into all the loops in the forum everyone asks to handle input stream and error stream in threads or do a redirect error stream. I have added a redirect error stream but still it hangs.
when i press ctrl+c it prints the initial lines of the output and exits.
Content of my script file
#!/bin/sh
cd /home/ats/cloudripper/lke_factory_asb_v2/lk_assets_factory_release/
sh ./LKE_run_Diablo.sh 0a0e0c3dc893
So how to handle this situation.
Process builder have special API to redirect child process input, output and error streams. See documentation
If you need both child and parent process to use same console you should use INHERIT mode redirection. An example:
public class ChildProcessOutputProxy {
public static void main(String[] args) {
ProcessBuilder builder = new ProcessBuilder("whoami");
builder.redirectOutput(Redirect.INHERIT);
builder.redirectErrorStream(true);
try {
var child = builder.start();
child.waitFor();
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
In Java, I've tried to run:
Process p = Runtime.getRuntime().exec("C:\\Windows\\System32\\chgport.exe");
as well as
Process p = Runtime.getRuntime().exec("chgport.exe");
but getting the following Exception:
java.io.IOException: Cannot run program "C:\Windows\System32\chgport.exe": CreateProcess error=2, The system cannot find the file specified
I am using the NetBeans IDE and it is running with admin credentials.
I tried your code and its working fine, Try it like so:
String[] command = {"chgport"};
ProcessBuilder pb = new ProcessBuilder(command);
pb.directory(new File("C:/Windows/System32/"));
pb.redirectErrorStream(true);
Process p = pb.start();
I tried both methods from Eclipse and both are working fine
Is it possible that you are not running your IDE with Administrator rights?
Can you try close the IDE and right click run as administrator?
try {
Process p = Runtime.getRuntime().exec("C:\\Windows\\System32\\mspaint.exe");
p.waitFor();
String[] command = {"mspaint"};
ProcessBuilder pb = new ProcessBuilder(command);
pb.directory(new File("C:/Windows/System32/"));
pb.redirectErrorStream(true);
Process p2 = pb.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You could run it with CMD /C, which "carries out the command specified by string and then terminates".
Process p = Runtime.getRuntime().exec("CMD /C chgport.exe");
How can I get the process id of the shell script started with ProcessBuilder?
String cmd[] = { "sh", "-c", "ls -l" };
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectOutput(new File(request.getParameter("output_file_name")));
Process p = pb.start();
try {
p.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
p.destroy();
See: How can a Java program get its own process ID?
Java 9 now has support for this. Otherwise call a script out of your application to save the PID which you will read somewhere
This is one way to run cmd.exe using java:
String command="cmd /c start cmd.exe";
Process p = Runtime.getRuntime().exec(command);
How to enforce command to run cmd.exe from the root directory C:\ ?
As suggested by others, consider using ProcessBuilder.
Code:
ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/C", "start");
processBuilder.directory(new File("C:\\"));
try {
processBuilder.start();
} catch (IOException e) {
e.printStackTrace();
}
On clicking a button in a jsp page, I want to run a batch file. I wrote this code to execute a batch file inside a method, but it's not working. Plz help me out.
public String scheduler() {
String result=SUCCESS;
try {
Process p = Runtime.getRuntime().exec("cmd /c start.bat", null, new File("C:\\Program Files\\MySQL\\MySQL Server 5.0\\bin\\start"));
System.out.println("manual scheduler for application.."+p);
} catch(Exception e) {
}
}
Add this code,
batFile.setExecutable(true);
//Running bat file
Process exec = Runtime.getRuntime().exec(PATH_OF_PARENT_FOLDER_OF_BAT_SCRIPT_FILE+File.separator+batFile.getName());
byte []buf = new byte[300];
InputStream errorStream = exec.getErrorStream();
errorStream.read(buf);
logger.debug(new String(buf));
int waitFor = exec.waitFor();
if(waitFor==0) {
System.out.println("BAT script executed properly");
}
According to this, the following code should work (just remove the cmd /c):
public String scheduler() {
String result=SUCCESS;
try {
File f = new File("C:\\Program Files\\MySQL\\MySQL Server 5.0\\bin\\start")
Process p = Runtime.getRuntime().exec("start.bat", null, f);
System.out.println("manual scheduler for application.."+p);
} catch(Exception e) {
}
}
It's not clear here whether you just want to run a bat file or you want to wait for it to run.
// the location where bat file is located is required eg. K:/MyPath/MyBat.bat in my case
// If bat file is in classpath then you can provide direct bat file name MyBat.bat
**Runtime rt = Runtime.getRuntime() ;
Process batRunningProcess= rt.exec("cmd /c K:/MyPath/MyBat.bat");**
// This is to wait for process to complete
//if process is completed then value will be 0
**final int exitVal = lawTab_Indexer.waitFor();**
// This line is not required if you just want to run a bat file and dont want to wait for it to get completed.