I have a java program in which i have this code,
JOptionPane.showConfirmDialog(null, "TEST");
String pathToJar = ClassRewriter.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()+"ClassRewriter.class";
System.out.println(pathToJar);
ProcessBuilder pb = new ProcessBuilder("javaw "+pathToJar);
Process process = pb.start();
I have a java program in a class called classrewriter, and i am trying to start that program from within its main method but it doesnt seem to work.
public int runCommand(String command) throws Exception
{
Process s= Runtime.getRuntime().exec(command);
return s.exitValue();
}
So you write:
runCommand("java -jar "+pathToJar);
But it isn't recommend, because it isn't supported on all OSes (for example linux or mac).
Related
Imagine that I'm starting my Java Compilation from a Command Prompt Window (say W0), where I have compiled the following piece of code.
public static void main(String... args) {
new ProcessBuilder("cmd", "/c", "start cmd.exe").inheritIO().start().waitFor();
System.out.println("Done!");
}
This will open one more Command Prompt Window (say W1), but yet the string "Done!" is printed in the previous window W0.
I have made the following attempt to get rid out of this.
public static void main(String... args) {
ProcessBuilder processBuilder0 = new ProcessBuilder("cmd", "/c", "start", "cmd.exe");
ProcessBuilder processBuilder1 = processBuilder0.inheritIO();
Process process = processBuilder1.start();
process.waitFor();
OutputStream os = process.getOutputStream();
System.setOut(new PrintStream(os));
System.out.println("Done!");
}
But now the string "Done!", is not getting printed in both W0 and W1, as the standard OutputStream has been changed to some 'UNKNOWN' stream.
System.setOut(new PrintStream(os));
I can set the OutputStream to some other user files, but the real problem is that I'm unable to transfer the control to another Command Prompt.
Kindly, help me to solve this problem.
How do you have java run commands on Mac? I see some examples of complex commands that is hard to follow. If I wanted to run a simple echo command from java, how would I do that? Not using osascript yet. Just want to see how you would send an echo from java to terminal.
public static void main(String[] args) throws IOException {
ProcessBuilder x = new ProcessBuilder("echo"," hi");
x.start();
}
This is the code I tried, but it does not work.
I think this question can help people who are trying to learn the basics of ProcessBuilder.
I am on Windows so the below code uses Windows echo. I hope you know the Mac echo command so that you can replace my command with yours.
import java.io.IOException;
import java.lang.ProcessBuilder;
public class PrcBldT2 {
public static void main(String[] args) {
// This command is for Windows operating system.
// For MacOS, try: new ProcessBuilder("echo", "hi")
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "echo", "hi");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
try {
Process p = pb.start();
int result = p.waitFor();
System.out.println("Exit status = " + result);
}
catch (IOException | InterruptedException x) {
x.printStackTrace();
}
}
}
Note that each word in the command is a separate string. The echo command output will be redirected to System.out.
The command "cat ~/desktop/b.mpg ~/desktop/b2.mpg > ~desktop/intermediate_all.mpg" does not seem to work via Java Runtime alone (as seen in the example below);
public class Test {
public static void main(final String[] args) {
String[] cmd = {"cat ~/desktop/b.mpg ~/desktop/b2.mpg > ~desktop/intermediate_all.mpg"};
try { Runtime.getRuntime().exec(cmd); }
catch (IOException e) { e.printStackTrace();}
}
}
However, when put into a .sh file like in this second example it works just fine....
public class Test {
public static void main(final String[] args) {
try { Runtime.getRuntime().exec("/users/nn/desktop/configure.sh"); }
catch (IOException e) { e.printStackTrace();}
}
}
Can anybody please tell me what the fundamental process is being lost when moving from a bash script to straight Java Runtime? FYI, I am using OSX, have already tried using absolute filepaths, and know about Process Builder (which has the same effect) is preferred to using Java Runtim--as has been stated a thousand times on this forum already, so lets avoid beating the dead horse on that one.
Thanks
The command being executed is cat with arguments. The command and its arguments must be separate elements of the array.
Also, you can't redirect using Runtime.exec() - you must use ProcessBuilder:
Try this:
ProcessBuilder pb = new ProcessBuilder("cat", "~/desktop/b.mpg", "~/desktop/b2.mpg");
pb.redirectOutput(new File("~/desktop/intermediate_all.mpg"));
Process p = pb.start();
It is likely that the shell location ~ will not be understood, so you may have to use the full absolute path for the files
Try this:
Runtime.getRuntime().exec(new String[] {
"/bin/bash", "-c",
"cat ~/desktop/b.mpg ~/desktop/b2.mpg > ~/desktop/intermediate_all.mpg" })
Because in the second case, you are effectively running "bash", "-c", "cat etc >file" where Bash takes care of parsing the redirection for you. Redirection is a feature of the shell, not of cat; if you run the raw process without a shell, the features of the shell are not available to you.
in your java code
~/desktop/b.mpg ~/desktop/b2.mpg > ~desktop/intermediate_all.mpg ,
you have to give full path after > ~/desktop/intermediate_all.mpg
I have a perl script that i'm trying to execute through shell. The normal UNIX shell invocation is do is: /home/projects/bumble/script.pl --input /home/input/input.txt > /home/output/output.txt.
To do this in Java I wrote a function:
public void runCommand(String command, File directory) {
final ProcessBuilder pb = new ProcessBuilder(command);
pb.directory(directory);
final Process process = pb.start();
if(process.waitFor() != 0) {
throw new RuntimeException("ERROR");
}
}
I call this:
String command = "/home/projects/bumble/script.pl --input /home/input/input.txt > /home/output/output.txt";
File directory = new File("/home/projects/bumble");
runCommand(command,directory);
The exception I get is:
java.io.IOException: ... Cannot run program error=2, No such file or directory
I notice here: java.io.IOException: Cannot run program error=2, No such file or directory, implies that running programs given a full input with > into a completely different directory would fail. If I just run the command /home/projects/bumble/script.pl --input /home/input/input.txt, also fails with the same error. I run it directly through shell, it does work. Is there something I am missing or doing incorrectly?
Runtime.exec() traps: http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html?page=3
2 problems with the code:
Command should be broken down into a String[] such as:
String[] command = {"perl", "/home/projects/bumble/script.pl", "--input", "/home/input/input.txt"}
Output needs to be handled seperately without the redirect ">". To do this, ProcessBuilder has Redirect. http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.Redirect.html
Programmatically the function is:
public static void runCommand(final String[] command, final File directory, final File output) throws IOException, InteruptException {
final ProcessBuilder pb = new ProcessBuiler(command);
pb.redirectErrorStream(true); //optional; easier for this case to only handle one stream
pb.redirectOutput(Redirect.to(output));
final Process p = pb.start();
if(p.waitFor != 0) {
//throw an exception / return error message
}
}
I have a java application that downloads and runs another program. The problem I'm running into is that when it runs the program there is no visual; however, the process shows up in the Windows Task Manager.
Here's the relevant execution code:
String[] cmd = {System.getProperty("java.io.tmpdir") + PACKAGE_PATH + onePackage};
log.info("Package downloaded to: " + cmd[0]);
new ProcessBuilder(cmd[0]).start();
I've also used a Runtime.exec() and that produced the same results.
Here's a Commons Exec version that produces the same result:
String line = "cmd.exe start /c " + "\"" + cmd[0] + "\"";
CommandLine cmdLine = CommandLine.parse(line);
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(cmdLine);
One last bit of detail, it works fine on my Win7 desktop from Eclipse, but not on Windows Server 2008 R2.
You can do it with the following code:
import java.io.IOException;
public class TestClass {
public static void main(String[] args) throws IOException {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("cmd.exe /c mspaint.exe");
}
}
This will result in a mspaint.exe getting started up in the foreground compared to the background. However since you do it through cmd.exe that process ends immediately after mspaint.exe starts up resulting in the java program to finish its execution regardless of the status of the mspaint.exe which may be ok for your situation.
If you need to wait for it to finish, I would recommend looking at Commons Exec