This question already has answers here:
How to use "cd" command using Java runtime?
(8 answers)
Closed 4 years ago.
I am trying to run a .class file in java. Here's what I've tried:
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("cd target/classes/; java -cp ./ SoundHandler Correct; cd ../../");
I did some googling and the best I could come up with was to tack this on to the end:
pr.getInputStream();
pr.getErrorStream();
pr.getOutputStream();
This did not help. I want to run a .class file in java. Thanks!
You are giving three commands to the runtime to execute - but only one parameter. It is trying to execute it as one command - however such a command does not exist.
If the command consists of multiple elements (command and arguments), they should be passed as a String array, so the runtime can differentiate them. If you are using shell commands, (like cd), then the command should be passed to the shell as a parameter.
Try something like this:
//if you are using unix-like OS. For Windows change sh -c to cmd /k
String[] cmd = new String[] {"sh", "-c", "cd target/classes/ && java -cp ./ SoundHandler Correct"};
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(cmd)
For debugging the process, you can read the command's output on the following way:
InputStream is = pr.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null){
System.out.println("MSG: " + line);
}
A bit of update after some chat conversation: the main idea was working, but classpath needed some investigation.
Related
I am supposed to make an IDE for my project. Here I have to execute a java program(suppose Hello world ) via a Shell command from a specific java program. I know how to execute a shell command via java program (using Runtime.getRuntime()),but how do I invoke run a java program using this shell command.
Start with ProcessBuilder, it will allow you to separate each command argument as a separate parameter, removing the need to "quote" arguments that have spaces (like paths), it will allow you to specify the starting location of the command (working directory) and the redirection support makes it easier to extract information from the output of the command (although you might like to keep it separate)...
List<String> cmds = new ArrayList<String>(5); // You can use arrays as well
cmds.add("java");
cmds.add("-jar");
cmds.add("filename.jar");
ProcessBuilder pb = new ProcessBuilder(cmds);
pb.redirectErrorStream(true);
pb.directory(new File("...")); // Working directory...
Process p = pb.start();
// Normal processing of the Process...
You can even specify the environment variables passed to the process...
Take a look at the Java Docs for more details
This will work.
Setup the commands and then create runtime and execute command there.
String command[] = new String[4];
command[0] = "cmd";
command[1] = "/k start cmd /k";
command[2] = "java";
command[3] = path;
Process p = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); //This will allow you to supply with input
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); //This will provide you access to the errors.
pw = new PrintWriter(p.getOutputStream());
pw.println("next commands");
The PrintWriter object will allow you to execute more commands.
I want to run a script with ssh from java. The script takes a number as parameter. I launch this code :
String myKey="/home/my_key.pem";
Runtime runtime = Runtime.getRuntime();
String commande = "ssh -i "
+myKey+" ubuntu#ec2-56-75-88-183.eu-west-1.compute.amazonaws.com './runScript.bash 8000'";
Process p = runtime.exec(commande);
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
p.waitFor();
I obtain this error :
bash: ./runScript.bash 8000: No such file or directory
The name of file is correct. chmod given to runScript.bash is 777.
When i run the command line directly from bash it works. But from IDE, it does not.
How can i do to run this commande line correctly please ?
The error makes it clear:
bash: ./runScript.bash 8000: No such file or directory
This indicates that the shell is trying to invoke a script called ./runScript.bash 8000 -- with the space and the 8000 in the filename of the script.
It's rare for me to be telling anyone to use fewer quotes, but, well, this is actually a case where that would fix things.
Better would be to avoid double evaluation altogether:
Runtime.exec(new String[] {
"ssh",
"-i", myKey,
"ubuntu#ec2-56-75-88-183.eu-west-1.compute.amazonaws.com",
"./runScript 8000"
})
I am using cygwin to get unix environment on windows.
I have some shell script that run on cygwin to perform syncing works and other things. I want to executes these script through java code.
Also during executing of scripts on cygwin , certain information is displayed on terminal by using simple echo command.. I want to show all that information in my application.
How can I do this??
Use the Runtime class to run Cygwin. This is very brittle, and dependent upon your setup, but on my machine I would do:
Runtime r = Runtime.getRuntime();
Process p = r.exec("C:\\dev\\cygwin\\bin\\mintty.exe --exec /cygpath/to/foo.sh");
Then wait for the Process to complete, and get a handle to it's InputStream objects to see what was sent to stdout and stderror.
The first part of the command is to run cygwin, and the second is to execute some script, or command (using -e or --exec). I would test this command on the DOS prompt to see if it works first before cutting any code. Also, take a look at the options available by doing:
C:\dev\cygwin\bin\mintty.exe --help
Also from within the DOS prompt.
EDIT: The following works for me to print version information
public class RuntimeFun {
public static void main(String[] args) throws Exception {
Runtime r = Runtime.getRuntime();
Process p = r.exec("C:\\dev\\cygwin\\bin\\mintty.exe --version");
p.waitFor();
BufferedReader buf = new BufferedReader(
new InputStreamReader(
p.getInputStream()));
String line = buf.readLine();
while (line != null) {
System.out.println(line);
line = buf.readLine();
}
}
}
Unfortunately, can't seem to get it working with --exec, so you're going to have to do some more research there.
You can use something like this
String cmd = "ls -al";
Runtime run = Runtime.getRuntime();
Process pr = run.exec(cmd);
pr.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
while ((line=buf.readLine())!=null) {
System.out.println(line);
}
p.s. this doesn't handle errors
Is it possible to open the command prompt (and I guess any other terminal for other systems), and execute commands in the newly opened window?
Currently what I have is this:
Runtime rt = Runtime.getRuntime();
rt.exec(new String[]{"cmd.exe","/c","start"});
I've tried adding the next command after the "start", I've tried running another rt.exec containing my command, but I can't find a way to make it work.
If it matters, I'm trying to run a command similar to this:
java -flag -flag -cp terminal-based-program.jar
EDIT Unfortunately I have had some strange findings. I've been able to successfully launch the command prompt and pass a command using this:
rt.exec("cmd.exe /c start command");
However, it only seems to work with one command. Because, if I try to use the command separator like this, "cmd.exe /c start command&command2", the second command is passed through the background (the way it would if I just used rt.exec("command2");). Now the problem here is, I realized that I need to change the directory the command prompt is running in, because if I just use the full path to the jar file, the jar file incorrectly reads the data from the command prompt's active directory, not the jar's directory which contains its resources.
I know that people recommend staying away from rt.exec(String), but this works, and I don't know how to change it into the array version.
rt.exec("cmd.exe /c cd \""+new_dir+"\" & start cmd.exe /k \"java -flag -flag -cp terminal-based-program.jar\"");
If you are running two commands at once just to change the directory the command prompt runs in, there is an overload for the Runtime.exec method that lets you specify the current working directory. Like,
Runtime rt = Runtime.getRuntime();
rt.exec("cmd.exe /c start command", null, new File(newDir));
This will open command prompt in the directory at newDir. I think your solution works as well, but this keeps your command string or array a little cleaner.
There is an overload for having the command as a string and having the command as a String array.
You may find it even easier, though, to use the ProcessBuilder, which has a directory method to set your current working directory.
Hope this helps.
public static void main(String[] args) {
try {
String ss = null;
Process p = Runtime.getRuntime().exec("cmd.exe /c start dir ");
BufferedWriter writeer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
writeer.write("dir");
writeer.flush();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
System.out.println("Here is the standard output of the command:\n");
while ((ss = stdInput.readLine()) != null) {
System.out.println(ss);
}
System.out.println("Here is the standard error of the command (if any):\n");
while ((ss = stdError.readLine()) != null) {
System.out.println(ss);
}
} catch (IOException e) {
System.out.println("FROM CATCH" + e.toString());
}
}
The following works for me on Snow Leopard:
Runtime rt = Runtime.getRuntime();
String[] testArgs = {"touch", "TEST"};
rt.exec(testArgs);
Thing is, if you want to read the output of that command, you need to read the input stream of the process. For instance,
Process pr = rt.exec(arguments);
BufferedReader r = new BufferedReader(new InputStreamReader(pr.getInputStream()));
Allows you to read the line-by-line output of the command pretty easily.
The problem might also be that MS-DOS does not interpret your order of arguments to mean "start a new command prompt". Your array should probably be:
{"start", "cmd.exe", "\c"}
To open commands in the new command prompt, you'd have to use the Process reference. But I'm not sure why you'd want to do that when you can just use exec, as the person before me commented.
You just need to append your command after start in the string that you are passing.
String command = "cmd.exe /c start "+"*your command*";
Process child = Runtime.getRuntime().exec(command);
String[] command = {"cmd.exe" , "/c", "start" , "cmd.exe" , "/k" , "\" dir && ipconfig
\"" };
ProcessBuilder probuilder = new ProcessBuilder( command );
probuilder.directory(new File("D:\\Folder1"));
Process process = probuilder.start();
You can use any on process for dynamic path on command prompt
Process p = Runtime.getRuntime().exec("cmd.exe /c start dir ");
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd \"E:\\rakhee\\Obligation Extractions\" && dir");
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd \"E:\\oxyzen-workspace\\BrightleafDesktop\\Obligation Extractions\" && dir");
Please, place your command in a parameter like the mentioned below.
Runtime.getRuntime().exec("cmd.exe /c start cmd /k \" parameter \"");
You have to set all \" (quotes) carefully. The parameter \k is used to leave the command prompt open after the execution.
1) to combine 2 commands use (for example pause and ipconfig)
Runtime.getRuntime()
.exec("cmd /c start cmd.exe /k \"pause && ipconfig\"", null, selectedFile.getParentFile());
2) to show the content of a file use (MORE is a command line viewer on Windows)
File selectedFile = new File(pathToFile):
Runtime.getRuntime()
.exec("cmd /c start cmd.exe /k \"MORE \"" + selectedFile.getName() + "\"\"", null, selectedFile.getParentFile());
One nesting quote \" is for the command and the file name, the second quote \" is for the filename itself, for spaces etc. in the name particularly.
I am trying to execute a program from the Java code. Here is my code:
public static void main(String argv[]) {
try {
String line;
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable -o filename.txt"});
BufferedReader input = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
} catch (Exception err) {
err.printStackTrace();
}
}
My OS is Mac OS X 10.6.
Now, the executable I am trying to run is supposed to spit the output to filename.txt. If I take this command and run it on the terminal, it works fine and the filename.txt gets populated also. But, from my java program the file is not created.
if instead I use executable > filename.txt then the filename.txt is created but is empty. Not sure what's wrong here. The executable I am trying to run is Xtide (if that helps).
I would really appreciate any help I can get.
Thanks,
You cannot redirect output to file and read the output in java. It's one or the other. What you want is this:
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable -o filename.txt"});
p.waitFor();
BufferedReader input = new BufferedReader(
new InputStreamReader(new FileInputStream("filename.txt")));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
The main changes are:
p.waitFor(), since process execution is asynchronous, so you have to wait for it to complete.
The data is read from the file rather than from the output of the process (since this will be empty.)
The answer from mdma works (and I voted it up), but you might also want to consider the version where you do read the output stream directly from executable:
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable"});
p.waitFor();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())_;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
Correct me if I am wrong, but the symptoms are as follows:
exec("/usr/bash", "-c", "executable > filename.txt") creates an empty file.
exec("/usr/bash", "-c", "executable -o filename.txt") does not create a file.
One or both of the above gives an exit code of 255 when you look at it.
When you run the command from the command line as executable -o filename.txt or executable > filename.txt it works as expected.
In the light of the above, I think that the most likely cause is that /bin/bash is not finding the executable when you launch it from Java. The fact that the first example does create an empty file means that /bin/bash is doing something. But if you try to run
$ unknown-command > somefile.txt
from a bash shell prompt you will get an error message saying that the command cannot be found and an empty "something.txt" file. (You would not see the error message in your Java app because it is being written to stderr, and you are not capturing it.) The reason that the empty "something.txt" file is created is that it is opened by the shell before it attempts to fork and exec the "executable".
If this is the problem, then the simple solution is to use the absolute pathname for the executable.
Also, if you are not doing any command line redirection or other shell magic, there is no need to run the executable in a new bash instance. Rather, just do this:
Process p = Runtime.getRuntime().exec("executable", "-o", filename.txt");
then wait for the process to complete and check the exit code before trying to read the file contents.