in a project I need to execute a java application from another java application. So far so good. Now I am stuck at the point, where the former needs to fetch the latters logs from the console.
The execution of the second is handled by the following snipped of code:
ArrayList<String> commands = new ArrayList<>();
commands.add("javaw");
commands.addAll(data.returnPropertiesAsPrefixedStringList());
commands.add("-cp");
commands.add(data.getClasspathJar().toString());
commands.add("[PathToMainClass]");
//data.getArgs for example contains the path to the second java (jnlp) file
commands.addAll(data.getArgs());
ProcessBuilder java = new ProcessBuilder().inheritIO().command(commands);
Process start = java.start();
How can I now fetch the logs "start" writes to the console? As I did not quite know what I had to search for, I did not manage to find fitting answers.
Edit:
I have tried getting the logs like that, but it did not work. The Logs weren't recognised at all.
Process start = java.start();
BufferedReader input = new BufferedReader(new InputStreamReader(start.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
System.out.println("It Did Work: " + line);
}
Thank you in advance for your help.
-IHaveNoClue
Process has a getInputStream() operation, so you could use an inputstream reader to access this data. Also maybe this discussion will help you: printing-runtime-exec-outputstream-to-console
Related
Hello guys im writing a web app in java with servlet, but i need for a job to use python, so im using Process.getRuntime().exec() for call the script.
My web app is a survey and between client compile it we take a photo of him.
I need python for deepface, for detection his emotion, and write all the results in a pdf file (what he choose, photos and detection of emotion result).
For 7 question in the survey the script works fine, when i put 8 question he never stop his job (the script working when isn't called from java i tested it).
Can you help me for understand how i can find the error? This process has got a limit of resources or something like that?
Process p = Runtime.getRuntime().exec("python "+rootPath+"\\DeepFaceLearning\\TestFace.py "+nomeFile);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
String temp ="";
while((temp = stdInput.readLine()) != null) {
System.out.println(temp);
}
For python the script is very long, but i think the problem is java beacuse he works fine when i run the script from command line with 40 questions.
I need to add 21 question in total.
Script python:
take a file read it and save the questions,reason e photos in a variables
analyze all photos
wirte all this information on a pdf
save pdf in db
Edit: java enter into script but don't complete all the job.
If the your python is working for 7 the same way as for 8 question, you could try to read the inputstream in other Thread.
Like:
...
new Thread(new Runnable(){
#Override
public void run(){
BufferedReader stdInput = new BufferedReader(newInputStreamReader(p.getInputStream()));
String temp ="";
while((temp = stdInput.readLine()) != null) {
System.out.println(temp);
}}).start();
I'm currently working on a project for school and I'm trying to use sSMTP to send emails from java to a user using a text file. Executing from the command line ssmtp email#gmail.com < msg.txt works just fine and sends me the email with the information contained in msg.txt. However, when I try to do it in java using ProcessBuilder it doesn't send an email.
`ProcessBuilder builder = new ProcessBuilder;
builder.command("ssmtp", "email#gmail.com", "<", "msg.txt");
Process p = builder.start();`
I believe that it doesn't like where I try to pipe in msg.txt. If anyone knows a better way to do this that would be great. I haven't been able to find anything yet and am not sure how to do it myself
Instead of trying to rely on the shell's redirect functionality (which as you see doesn't work), you can just read msg.txt and write it to the process' OutputStream. It'll be the same thing, but in code (and it'll be a better solution too).
Something along the lines of
Process p = new ProcessBuilder("ssmtp").start();
PrintStream out = new PrintStream(p.getOutputStream());
String line = null;
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("msg.txt")));
while((line = in.readLine()) != null)
out.println(line);
out.close();
in.close();
However if you want to use shell redirection which I wouldn't recommend for anything serious, you need to execute the program which actually does the redirection, i.e. bash. The following should do the trick:
new ProcessBuilder("bash", "ssmtp", "email#gmail.com", "<", "msg.txt").start();
As dave_thompson_085 commented, it's even easier to do programmatic redirection. Things sure are easy these days!
new ProcessBuilder("ssmtp", "email#gmail.com").redirectInput(new File("msg.txt")).start();
I'm trying to start some .jar inside an .jar using this code: (I'm trying with craftbukkit server right know)
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("java -jar craft.jar");
BufferedReader out = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedWriter in = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
this.running = true;
while(this.running){
String line;
if((line = out.readLine()) != null){
System.out.println(line);
}
}
The problem is, it work for a moment, but after a while it stops outputting or just print '>' as show in the image below. How can I fix this? **Plus, Which is the correct way to send commands to the bukkit server?
Thanks!
When using a Process in Java, it is crucial to read stdout and stderr in two independend threads (your while loop). Otherwise the child process can lock up waiting for the filled buffer to be drained.
With Java 7 you can actually redirect stderr to stdout, and possibly redirect the resulting stream to the parents stdout. With older versions you need to attach the seperate threads.
Besides: you should not use the "single string" variant of exec, but specify the args as arrays. This is safer (less vulnerable to parsing problems).
(But I am not sure if this is your actual problem. Maybe you should dump the error stream and see if it helps)
I do it like that:
#Override
public void run(){
// ...
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); //of course proc is an instance of Process, and it's set up
while(true){
String line = stdInput.readLine();
if(line == null) break; //this is essential, when process terminates, line gets null
System.out.println(">"+line);
}
// ...
}
Give it a try.
(Technically it's similiar how you did, but it works for me so i share it)
I'm trying to integrate with a legacy system. The legacy system uses dialog windows to report errors. It have no return codes at all except for the dialog windows. I start the legacy system with Runtime.exec().
Is there a way to detect if the executed program has spawned dialog windows or any other graphical interface? This solution is done in Windows and the executed program is an exe.
If the legacy system report errors in console, is possible get your erros.
Simply take the inputstream of error and do your reading.
Like this:
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
// any error message?
InputStream error = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(error);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null)
System.out.println(" ERROR >" + line);
I recommend to read: Runtime.exec() quirks
Hope this help.
You can use this JNA snippet to poll for windows started by your process.
AFAIK, you can only get the standard and error output streams from a process using the Java Process API.
So the solution i did, is to use the snippet code that #Gerrett Hall linked to. That snippet code check the active window before i run the command and save the name.
Then after a vile if the command have not returned check if the active window have changed. if it have, kill the process(Alt. send a return key global).
To get the info from the dialog i could use Ctrl + C to copy the content of the dialog and reading the paste buffer to copy the message in to the log. Have not figured out that part yet.
And yes this is a ugly hack but so is the legacy system to.
I'm making an update function for my project, it's working great, until i want it to restart, basically I download the new file and replace it with the old one, and then i want to run it again, now for some reason it doesn't wna run, and i don't get any error...
Here is the complete update class:
http://dl.dropbox.com/u/38414202/Update.txt
Here is the method i'm using to run my .jar file:
String currDir = new File("(CoN).jar").getAbsolutePath();
Process runManager = Runtime.getRuntime().exec("java -jar " + currDir);
It's not clear to me, why do you need to run the jar with a call to exec() . Given that you need to run the code in the .jar file from a Java program, you could simply run the main() method as defined in the jar's manifest, and capture its output - wherever that is.
Using exec() is OK when you need to call a program from the underlying operating system, but there are easier ways to do this if both the caller and the callee are Java programs.
Now, if your jar is gonna change dynamically and you need to update your program according to a new jar, there are mechanisms for reloading its contents, for instance take a look ath this other post.
The JavaDocs for the Process class specifically point out that if you don't capture the output stream of the Process and promptly read it that the process could halt. If this is the case, then you wouldn't see the process that you started run.
I think you have to capture the stream like this :
BufferedReader stdInput = new BufferedReader(new InputStreamReader(runManager.getInputStream()),8*1024);
BufferedReader stdError = new BufferedReader(new InputStreamReader(runManager.getErrorStream()));
// read the output from the command
String s = null;
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
The exec function doesn't automatically lookup into the PATH to start a process, so you have to pass the complete path for the java binary.
You can do that by using the java.home system property, see this answer: ProcessBuilder - Start another process / JVM - HowTo?
No one here seemed to help me, so I went to ask my friend and I had it almost right. It abiously required the string to be an array.
solution:
String[] cmd = {"java", "-jar", currDir};
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e1) {
e1.printStackTrace();
}