Java program for changing the directory of command prompt - java

I have written a java program named Automate.java, in which the another java program named newsmail will be executed.
The problem i face here is, Automate.java is in Desktop location(should be in desktop only always due to some requirements) and newsmail is in /home/Admin/GATE521/LN_RB this location.
What must be done before the below code, such that the command prompt automatically goes to the required folder and executes the program.
String command = "java newsmail";
Process child = Runtime.getRuntime().exec(command);

You can use this exec() :
Process child = Runtime.getRuntime().exec(command, null, new File("/home/Admin/GATE521/LN_RB"));
Resources :
javadoc - Runtime.exec()

Use the new ProcessBuilder class, instead of Runtime.exec().
ProcessBuilder pb = new ProcessBuilder("java", "newsmail");
pb.directory("/home/Admin/GATE521/LN_RB");
pb.start();
You can even look at pb.environment() to change environment variables if necessary.

Related

Java Process object fails to execute given command

I am trying to run a piece of Python code via a Java application. The command when put directly into Command Prompt cd'd to the working directory runs exactly as intended. However, my attempts to use the Runtime and ProcessBuilder classes in conjunction with the Process class has yielded no sign of correct function which would be the creation of a CSV file for every call of the code.
I am running this program using Intellij on Windows 10. I have added each directory I am using to my environmental PATH variable as well as attempting full paths in my commands and just file names. The only source of life I can find is that if I include a .waitFor() method a .isAlive() method will return true before the .waitFor() method is called.
I have searched through various similar questions and concluded that using a ProcessBuilder object is the best way to go and that the biggest issue is probably the structure of my command. However, I have made many iterations and have found nothing that changes the caught error to anything useful.
Here is the privacy augmented code that I have been running, I wrote out the command in full in the process builder as that is the last iteration I have attempted.
for (int y = 1; y < iterator; y++) {
try {
String command =
"C:\\Users\\myName\\AppData\\Local\\Programs\\Python\\Python37\\python C:\\Users\\myName\\IdeaProjects\\projectApplication\\script.py ";
String pythonInputPath = " C:\\Users\\myName\\IdeaProjects\\projectApplication\\bin\\output" + y + ".wav ";
ProcessBuilder pb = new ProcessBuilder(command+Arrays.toString(pythonCommandString).replaceAll("\\s","")+pythonInputPath+Integer.toString(y));
Process p = pb.start();
//Process checks
System.out.println(p.isAlive());
p.waitFor();
System.out.println(p.isAlive());
//Destroying process once complete to ensure smooth iterations
p.destroy();
} catch (Exception ex) {
System.out.println("Problems with python script execution: " + ex);
}
}
They python code takes in a WAV file (pythonInputPath) that is a product of earlier part of the application, an Integer[] that usually includes ~20 values (pythonCommandString), and a single iteration integer (y).
The first call to .isAlive() is true and the second is false as expected however the script normally creates a CSV that should be output to a bin file that exists in the working director and that fails to occur when running from Java. From other examples I expected using the Process builder as opposed to the Runtime stream to work, however, there is no difference in my implementation.
Do not concatenate the program with its arguments. Quoting Oracle ProcessBuilder docs
Each process builder manages these process attributes: a command, a
list of strings which signifies the external program file to be
invoked and its arguments, if any
and
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
Just use the constructor you use, but pass each argument as a separate string, otherwise the OS will try to find an application that is named as a whole command line you gave, and obviously there is no such program

Calling ps on Linux from Java

In Java, I start one new Process using Runtime.exec(), and this process in turn spawns several child processes.
I want to be able to kill all the processes, and have previously been trying process.destroy() and process.destroyForcibly() - but the docs say that destroyForcibly() just calls destroy() in the default implementation and destroy() may not kill all subprocesses (I've tried and it clearly doesn't kill the child processes).
I'm now trying a different approach, looking up the PID of the parent process using the method suggested here and then calling ps repeatedly to traverse the PIDs of child processes, then killing them all using kill. (It only needs to run on Linux).
I've managed the first bit - looking up the PID, and am trying the following command to call ps to get the child PIDs:
String command = "/bin/ps --ppid " + pid;
Process process = new ProcessBuilder(command).start();
process.waitFor();
Unfortunately the 2nd line above is throwing an IOException, with the following message: java.io.IOException: Cannot run program "/bin/ps --ppid 21886": error=2, No such file or directory
The command runs fine if I paste it straight into the terminal on Ubuntu 16.04.
Any ideas would be very much appreciated.
Thanks
Calling the command you wish to run this way is always destined to fail.
Since Process does not effectively run a shell session, the command is basically handed over to the underlying OS to run. This means that it'll fail, since the path to t he program to be executed (in this case ps), is not the full one hence the error you're getting.
Also, testing whether your command works using a terminal is not correct. Using a terminal contains the notion of performing an action with an active logged in user with a correct path etc etc. All the above are not the case though when running a command through Process as these are not taken into consideration.
Furthermore, you also need to account for cases where the actual java application could be running under a different user, with a different set of permissions, paths etc.
In order for your to fix this, you can simply do either of the following:
1) Invoke your ps command using the full path to it (still not sure if it would work)
2) Change the way your create the Process object into something like: p = new ProcessBuilder("bash", "-c", command).start();
The second, will effectively run a bash session, passing in the ps command as an argument thus obtaining the desired result.
http://commons.apache.org/proper/commons-exec/tutorial.html
```
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();
CommandLine cmdLine = CommandLine.parse(line);
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(cmdLine);
```

Run external app by userinput

So I'm creating a Java program and I want to make it so that you can ask it to open a program.
But, here's the catch, I want the program it opens to be taken from the user input, right now I'm trying to change this
try{Process p = Runtime.getRuntime().exec("notepad.exe");}
catch(Exception e1){}
Into something that opens a program that you asked it to open.
Here's an example of what I want:
User: Can you open chrome?
Program: Of course, here you go!
chrome opens
Could anyone tell me how I would be able to do this?
You can do it in two ways:
1.By Using Runtime:
Runtime.getRuntime().exec(...)
So, for example, on Windows,
Runtime.getRuntime().exec("C:\application.exe -arg1 -arg2");
2.By Using ProcessBuilder:
ProcessBuilder b = new ProcessBuilder("C:\application.exe", "-arg1", "-arg2");
or alternatively
List<String> params = java.util.Arrays.asList("C:\application.exe", "-arg1", "-arg2");
ProcessBuilder b = new ProcessBuilder(params);
or
ProcessBuilder b = new ProcessBuilder("C:\application.exe -arg1 -arg2");
The difference between the two is :
Runtime.getRuntime().exec(...)
takes a single string and passes it directly to a shell or cmd.exe process. The ProcessBuilder constructors, on the other hand, take a varargs array of strings or a List of strings, where each string in the array or list is assumed to be an individual argument.
So,Runtime.getRuntime.exec() will pass the line C:\application.exe -arg1 -arg2 to cmd.exe, which runs a application.exe program with the two given arguments. However, ProcessBuilder method will fail, unless there happens to be a program whose name is application.exe -arg1 -arg2 in C:.
You can try it with like. Pass whole path of where you install chrome.
try{
Process p = Runtime.getRuntime().exec("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe");
}
catch(Exception e1){
}
When using exec, it is essentially the same as if you were using the command line on windows. Open Command Prompt, type open, and see if it gives details as to how it opens files. If not, find the opener. Usually when dealing with command line operations, there are multiple parameters that are required for opening files/applications. An example of this would be for opening the "TextEdit.app" application on a mac.
Process p = Runtime.getRuntime().exec("open -a TextEdit.app");
Terminal(for mac) would open the app using the -a flag, meaning "application." You could open a file doing:
Process p = Runtime.getRuntime().exec("open filename.file_ext -a TextEdit.app");
The second one will tell the computer to find the application named <app_name>.app and open the file filename.file_ext
I know this is not going to work for a windows machine, but it's only to show how to use the command line operations for opening files and applications. It should be similar for windows though.
Hope this helps

How to run Different commands from Java Code?

I want to run different commands which can be executed on my command prompt or terminal through Java.
I did search few place but did not get appropriate reply.
I want to run a compiler which is set in the environment as VISAGE_HOME as well as run GRADLE so as to do all my build tasks.
I want to invoke all these commands from within Java Program.
Since it is a swing application I would like to invoke these commands on click of button or some other events.
My Problem is that I am not able to program this :( .
Neither do I know an API which would do this. I went through some sample codes but most of them have same kind of example codes of executing the shell commands or command prompt commands. None showed me to do the above stuff.
Have a look at ProcessBuilder. The Process object it returns has a waitFor method so you can wait for the process to finish. Then you can start your next process.
For example
Process p = new ProcessBuilder("runYourCommand").start();
InputStream in = process.getInputStream();
InputStreamReader inr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(inr);
String inputLine;
while ((inputLine = br.readLine()) != null) {
System.out.println(inputLine);
}
p.waitFor();
Another interesting method on ProcessBuilder is environment(). This will return the environment variables that you can access. From the API docs
Map<String, String> env = pb.environment();
env.put("VAR1", "myValue");
Something like this:
String cmd = "gedit";
Runtime run = Runtime.getRuntime();
Process pr = run.exec(cmd);
Firstly, ProcessBuilder is your friend...
You could have a look at;
Getting started with Java’s ProcessBuilder (Linux focus)
Using ProcessBuilder to Make System Calls
Run processbuilder and get in and output
ProcessBuilder and how redirecting input and output from operating system's processes
Executing Operating System Commands from Java
Secondly, You will need to use System.getenv to find the value of the specified environment variable and substitute it yourself.
nb: Thanks to Guillaume Polet for pointing out that the Process will automatically include the path environment variable to find commands.
Also, remember, DO NOT EXECUTE ANY BLOCKING PROCESS ON THE EDT.
Executing external commands are inherently blocking actions, while not explicitly, taking into account needing to consume the output of the process or wanting to know about the processes termination, these would require you to perform some kind of blocking action. Don't do this on the EDT. It will cause you program to appear as if it's hung.
You can use the Runtime.exec methods to run commands from within Java. The system enviroment variables are normally not visible from within the jvm. You could use a launcher, that submits these system enviroment properties as jvm properties to your java application.
According to http://javarevisited.blogspot.de/2011/02/how-to-execute-native-shell-commands.html implementing the following into your code after including "java.lang.Runtime" should perfectly work:
try {
Process process = Runtime.getRuntime().exec("Command to be executed");
} catch (Exception e) {
e.printStackTrace(System.err);
}

Java cannot execute system command (Ubuntu)

It's not the first time I have tried to execute a system command from Java; but this time it turns out to be very hard. I have a script that executes just fine from the terminal. It reads input from a file (input.txt), it processes it and exports the result in another file (ouput.txt). The whole thing lasts no more than 1sec. But, when I try to execute it from Java, it gets stuck and never finishes. This is my code:
Process p = new ProcessBuilder("./runCalculator.sh").start();
p.waitFor();
I have also tried with Runtime.getRuntime().exec("./runCalculator.sh") but all the same. I've read both the InputStream and the ErrorStream of the process. The error stream returns nothing but a message like "Starting Calculation..."
Any ideas?
You need to use the following code:
ProcessBuilder pb = new ProcessBuilder();
pb.command("bash", "-c", "./runCalculator.sh");
Process process = pb.start();
int retValue = process.waitFor();
You likely need to invoke the unix command interpreter/processor for this to work. Please see: When Runtime.exec() won't.
Try this:
Process p = new ProcessBuilder("sh ./runCalculator.sh").start();
Another, simplier solution is that you can open program by entering the name of the program (this assumes that program is installed) instead of creating script and calling it.
Note that the name of the program isn't always what you see in Gnome's menu, for example Gnome's calculator is "gnome-calculator". Regarding this facts, you can run calculator by the folowing line:
Process p = Runtime.getRuntime().exec("gnome-calculator");
In that case you don't have a need for any sh scripts (in your case runCalculator.sh).

Categories

Resources