Java simple process builder issue - java

I just conducted simple test code for Java Process Builder.
There are 4 examples and everything is working smoothly excluding last one.
Here is my codes
public class bashProcessor {
public static void main(String args[]) {
try {
ProcessBuilder pb;
pb = new ProcessBuilder("/bin/bash", "-c", "touch Jin_1.sh");
pb.start();
pb = new ProcessBuilder("/bin/bash", "-c", "mkdir Jin_2");
pb.start();
pb = new ProcessBuilder("/bin/bash", "-c", "bash /home/Jin/test.sh");
pb.start();
//below is not working
pb = new ProcessBuilder("/bin/bash", "-c",
"bash /home/solr-tomcat/bin/shutdown.sh warm4 solr-instances");
pb.start();
System.out.println("pb job is done now");
Thread.sleep(3000);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
When I type last example(bash /home/solr...) by hand-typing. It works without any error. I need your kind help. if you have any idea
please let me know it would be great help.

As pointed out by #ug_ try to remove bash from command and then execute your code. Following code works fine with multiple command.
cmd.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class cmd {
public static void main(String[] args) {
try {
String[] command = new String[3];
command[0] = "/bin/bash";
command[1] = "-c";
command[2] = "javac -verbose HelloWorld.java";
Process p = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String Error;
while ((Error = stdError.readLine()) != null) {
System.out.println(Error);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

Related

Execute Java Program From Java Code using Process

I am trying to execute a java code by using Process class.
Here is my code.
Class file which is trying to execute is.
class Demo{
public static void main(String[] args) {
System.out.println("Hello World");
}
}
class Pro {
public static void main(String[] args) {
try {
ProcessBuilder builder = new ProcessBuilder("java Demo");
builder.redirectErrorStream(true);
Process process = builder.start();
InputStream is = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Both classes are in different file and in the same folder.
O/P
java.io.IOException: Cannot run program "java Demo": 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 GFG.main(GFG.java:13)
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)
... 3 more
Try like this:
private static final String LOCATION = "D:\\test.java";
public static void main(String args[]) throws InterruptedException,IOException{
ProcessBuilder processBuilder = new ProcessBuilder(command);
List<String> command = new ArrayList<String>();
command.add("javac"); //or command.add("javac -jar")
command.add(LOCATION);
ProcessBuilder builder = new ProcessBuilder(command);
Map<String, String> environ = builder.environment();
final Process process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("Program terminated!");
}
}
Hope this helps,
Addendum (how to wait for process):
private String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
calling:
public static void main(String[] args) {
ExecuteShellComand obj = new ExecuteShellComand();
String domainName = "https://wwww.google.com";
//in mac oxs
String command = "ping -c 3 " + domainName;
//in windows
//String command = "ping -n 3 " + domainName;
String output = obj.executeCommand(command);
System.out.println(output);
}
This is an example to ping some page, 3 times and wait for response.

java process builder adding path to environment not working

I am using intellij both on my imac and mac book. when i run the following code on my mac book, everything works.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class Main {
public ProcessBuilder pb;
public Main(){
try {
pb = new ProcessBuilder();
pb.directory(new File("~/IdeaProjects/test"));
Map<String, String> env;
env = pb.environment();
env.put("PATH", "/usr/local/fsl/bin/");
} catch (Exception e) {
e.printStackTrace();
}
}
public void getMeanImage(String base, String file){
List<String> cmd = new LinkedList<>();
cmd.add("fslmaths");
cmd.add(base + file);
cmd.add("-Tmean");
cmd.add(base + file + "_mean");
pb.command(cmd);
try {
String s = "";
Process p = pb.start();
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String [ ] args) {
Main m = new Main();
m.getMeanImage("", "scan.nii.gz");
}
}
On the imac I run into problems. I copied the PATH value used by printenv.
env.put("PATH", "/usr/local/fsl/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin");
I get the exception:
java.io.IOException: Cannot run program "fslmaths" (in directory "~/IdeaProjects/test"): error=2, No such file or directory
Why can't the process builder find the program fslmaths in /usr/local/fsl/bin on the imac?
which fslmaths
/usr/local/fsl/bin/fslmaths
thanks in advance,
Martin
I found the solution. In the 'Run/Debug Configurations' of intellij under 'Environment Variables' the checkbox 'Include parent environment variables' was not enabled.

Java Kill processes started with ProcessBuilder

I'm running my processes like this:
builder = new ProcessBuilder("/bin/bash", "-c", "./MessageGenerator | ./SimpleEchoServer");
process = builder.start();
Then process.destroy() or forciblyDestroy() doesn't work. Is it because I'm using a pipe? How can I kill these processes?
you should also split up the pipe command. I've written a little example:
package com.company;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder processBuilder;
String line;
processBuilder = new ProcessBuilder("/bin/bash", "-c", "ls -l", "|", "grep java");
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println ("Stdout: " + line);
}
Thread.sleep(10000);
process.destroy();
}
}

running ffmpeg command in java Process hangs in waitFor()

I'm running ffmpeg command to generate video for given images (img001.jpg, img002.jpg ...) it's creating slide.mp4, but it waits infinitely:
public class Ffmpeg {
public static void main(String[] args) throws IOException, InterruptedException {
String path = "E:\\pics\\Santhosh\\FadeOut\\testing";
String cmd = "ffmpeg -r 1/5 -i img%03d.jpg -c:v libx264 -r 30 -y -pix_fmt yuv420p slide.mp4";
runScript (path, cmd);
}
private static boolean runScript(String path, String cmd) throws IOException, InterruptedException {
List<String> commands = new ArrayList<String>();
commands.add("cmd");
commands.add("/c");
commands.add(cmd);
ProcessBuilder pb = new ProcessBuilder(commands);
pb.directory(new File(path));
pb.redirectErrorStream(true);
Process process = pb.start();
flushInputStreamReader(process);
int exitCode = process.waitFor();
return exitCode == 0;
}
}
private static void flushInputStreamReader (Process process) throws IOException, InterruptedException {
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line=null;
StringBuilder s = new StringBuilder();
while((line=input.readLine()) != null) {
s.append(line);
}
}
Any suggestions?
After writing the function flushInputStreamReader, its working
Aside from reading the ErrorStream, there's a better way to handle this.
Add -loglevel quiet to the command, so that the ErrorStream won't overflow and blocking the process at the first place.
Here the working code for the live project:
public void executeHLS() throws IOException, InterruptedException {
String original_video_file = "C:\\xampp\\htdocs\\hls\\test.mp4";
String conversion = "cmd.exe /c F:\\java\\ffmpeg\\ffmpeg\\bin\\ffmpeg -i "+original_video_file+" -hls_time 10 -hls_playlist_type vod -hls_segment_filename \"C:\\xampp\\htdocs\\hls\\video_segments_%0d.ts\" C:\\xampp\\htdocs\\hls\\hls_master_for_test.m3u8";
//String conversion = "cmd.exe /c "+"dir";
String[] cmds={conversion};
for(int i=0;i<cmds.length;i++) {
try {
System.out.println(cmds[i]);
if(runScript(conversion)) {
System.out.println("Operation Successfull!!!!");
}else {
System.out.println("Operation Failed ####");
}
} catch (IOException e) {
e.printStackTrace();
}
//System.exit(0);
}
}
private static boolean runScript(String cmd) throws IOException, InterruptedException {
ArrayList<String> commands = new ArrayList<String>();
commands.add("cmd");
commands.add("/c");
commands.add(cmd);
ProcessBuilder pb = new ProcessBuilder(commands);
//pb.directory(new File(path));
pb.redirectErrorStream(true);
Process process = pb.start();
flushInputStreamReader(process);
int exitCode = process.waitFor();
return exitCode == 0;
}
private static void flushInputStreamReader (Process process) throws IOException, InterruptedException {
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line=null;
StringBuilder s = new StringBuilder();
while((line=input.readLine()) != null) {
s.append(line);
}
}

how to run a java executable jar in another java program

I know this question has been asked before but those answers didn't provide me an answer.
I want to execute a exec jar file in my java program and get the output from executing jar into a string. Here below are the codes I have used so far without success.
cmdlink = "java -jar iwtest-mac.jar"+" "+cmd;
System.out.println(cmdlink);
Process process = Runtime.getRuntime().exec(cmdlink);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((reader.readLine()) != null) {
st = reader.readLine();
}
process.waitFor();
and another code I have tried is as follows:
String cmdlink = "iwtest-mac.jar "+cmd;
ProcessBuilder pb = new ProcessBuilder("java", "-jar", cmdlink); //cmd here is a string that contains inline arguments for jar.
pb.redirectErrorStream(true);
pb.directory(new File("C:\\Users\\Dharma"));
System.out.println("Directory: " + pb.directory().getAbsolutePath());
Process p = pb.start();
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
for (String line = br.readLine(); line != null; line = br.readLine()) {
System.out.println( line );
p.waitFor();
Both of the above are not working for me. Any suggestions are appreciated.
This works For Me..
public class JarRunner {
public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "C:\\JCcc.jar");
pb.directory(new File("C:\\"));
try {
Process p = pb.start();
LogStreamReader lsr = new LogStreamReader(p.getInputStream());
Thread thread = new Thread(lsr, "LogStreamReader");
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class LogStreamReader implements Runnable {
private BufferedReader reader;
public LogStreamReader(InputStream is) {
this.reader = new BufferedReader(new InputStreamReader(is));
}
public void run() {
try {
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is what the Docs says-
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
You can pass any number of arguments in constructor.
Read more about process builder here.

Categories