capture error from runtime process java - java

I'm running a Java program from another Java application using Runtime.getRuntime().exec like this
Process p1 = Runtime.getRuntime().exec("javac test.java");
Process p2 = Runtime.getRuntime().exec("java test");
The content of the test.java
import java.io.*;
class test
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
System.out.println(s);
}
}
I want to handle Input, Output and Error stream of the process p2.
I did capture of the output of the test.java, however, I do not know how to handle output and error.
Here is my code:
try {
String s = "";
InputStream istr = p2.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(istr));
BufferedReader bre = new BufferedReader
(new InputStreamReader(p2.getErrorStream()));
while ((s = br.readLine()) != null) {
System.out.println(s);
}
br.close();
while ((s = bre.readLine()) != null) {
System.out.println(s);
}
bre.close();
p2.waitFor();
} catch (IOException ex) {
ex.printStackTrace();
} catch (Exception err) {
err.printStackTrace();
}
The code above works fine for capturing the output of the test.java. But it does not display error of the test.java.
Could you please give me a sample code for fixing this problem and handling output stream or share idea? Thanks in advance

The solution I've always used is to create a separate thread to read one of the streams
So, in your case it should be something like
String s = "";
InputStream istr = p2.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(istr));
BufferedReader bre = new BufferedReader
(new InputStreamReader(p2.getErrorStream()));
new Thread(new Runnable() {
#Override
public void run() {
while ((s = br.readLine()) != null) {
System.out.println(s);
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
while ((s = bre.readLine()) != null) {
System.out.println(s);
}
}
}).start();
// when you are finished close streams

Related

How can I read colors from process's input stream?

I am working on a Server launcher. This launcher runs Minecraft servers.
I want to get colors from the server's process's input like windows command prompt. How can I do that?
My server thread:
serverThread = new RunnableThread("ServerThread-" + serverName) {
#Override
public void onRun() {
if (!getProcess().isAlive()) {
ServerStatusChangeEvent.change(LocalServer.this, StatusType.STOPPED);
closePort();
if(queryTimerTask != null) queryTimerTask.cancel(false);
cancel();
}
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(getProcess().getInputStream(), Charset.forName("UTF-8")));
String line;
while ((line = reader.readLine()) != null) {
String l = line;
Platform.runLater(() -> parseLine(l));
}
reader.close();
} catch (final Exception e) {
//empty catch block
}
}
};
Thanks for the answers and sorry for my bad english!

Use Java application to run commands on windows cmd

import java.io.*;
public class ColorTest {
public static void main(String [] args){
try{
//Process p = Runtime.getRuntime().exec("cmd /c color 0a");
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readline()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I am not understanding why the command won't execute. The line that is commented is the one I need help with.

Executing 'adb logcat' command using Runtime class

I was trying to get the logcat content into a JTextPane. I used following code hoping it will return the content as String but it freeze and also, doesn't produce an error.
Process exec = null;
try {
exec = Runtime.getRuntime().exec("adb logcat -d");
InputStream errorStream = exec.getErrorStream();
BufferedReader ebr = new BufferedReader(new InputStreamReader(errorStream));
String errorLine;
while ((errorLine = ebr.readLine()) != null) {
System.out.println("[ERROR] :- " + errorLine);
}
if (exec.waitFor() == 0) {
InputStream infoStream = exec.getInputStream();
InputStreamReader isr = new InputStreamReader(infoStream);
BufferedReader ibr = new BufferedReader(isr);
String infoLine;
while ((infoLine = ibr.readLine()) != null) {
System.out.println("[INFO] :- " + infoLine);
}
}
} catch (IOException | InterruptedException ex) {
ex.printStackTrace();
} finally {
if (exec != null) {
exec.destroy();
}
}
I referred to some tutorials but, they were not filling my problem. Is this wrong? Are there any other methods to get the logcat content as a String programmatically? Sorry if this is a dumb question.
The issue you're seeing is that you're trying to process command streams and wait for the executing process, all in the same thread. It's blocking because the process reading the streams is waiting on the process and you're losing the stream input.
What you'll want to do is implement the function that reads/processes the command output (input stream) in another thread and kick off that thread when you start the process.
Second, you'll probably want to use ProcessBuilder rather than Runtime.exec.
Something like this can be adapted to do what you want:
public class Test {
public static void main(String[] args) throws Exception {
String startDir = System.getProperty("user.dir"); // start in current dir (change if needed)
ProcessBuilder pb = new ProcessBuilder("adb","logcat","-d");
pb.directory(new File(startDir)); // start directory
pb.redirectErrorStream(true); // redirect the error stream to stdout
Process p = pb.start(); // start the process
// start a new thread to handle the stream input
new Thread(new ProcessTestRunnable(p)).start();
p.waitFor(); // wait if needed
}
// mimics stream gobbler, but allows user to process the result
static class ProcessTestRunnable implements Runnable {
Process p;
BufferedReader br;
ProcessTestRunnable(Process p) {
this.p = p;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(p.getInputStream());
br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
// do something with the output here...
}
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
}

Java - How to send a value to child process using outputstream?

I relaunch the child process every time than i need to obtain a random number, but i think that it can be done using outPutStream but i don't know how. I saw the others post but i don't found nothing relevant for my problem. I don't want to use sockets.
Main Process.
public class ejercicio7 {
public static void main(String [] args){
boolean cerrado = false;
try {
while(!cerrado){
String entrada = JOptionPane.showInputDialog(null, "Introduce una entrada");
Process proceso = Runtime.getRuntime().exec("java -jar C:\\Users\\Cristian\\Desktop\\java\\numeros.jar \"" + entrada+"\"");
BufferedReader br = new BufferedReader(new InputStreamReader(proceso.getInputStream()));
String texto;
while((texto = br.readLine()) !=null){
if(Boolean.parseBoolean(texto)){
cerrado = true;
}else{
System.out.println(texto);
}
}
br.close();
proceso.destroy();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Child Process.
public static void main(String[] args) {
if(args.length <=0 && args[0].length() == 0){
System.out.println("No se ha introducido una entrada");
}else{
if(!args[0].equalsIgnoreCase("fin")){
System.out.println(Math.round(Math.random() * 10));
}else{
System.out.println("true");
}
}
}
}
Make your child process handling input stream:
public static void main(String[] args) throws Exception {
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
while (!"fin".equals(line = reader.readLine())) {
System.out.println(line);
}
System.out.println("buy");
}
Then in main process you can send messages to child process:
Process proceso = Runtime.getRuntime().exec("java -jar C:\\Users\\Cristian\\Desktop\\java\\numeros.jar");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(proceso.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(proceso.getInputStream()));
String texto;
out.write(entrada + "\n");
out.flush();
while((texto = in.readLine()) !=null){
...

StreamGobbler - Thread to accept input into it? Java

Using an self-edited StreamGobbler to run a php script,
I am trying to input commands into the script while it is running...
StreamGobbler.java
private class StreamGobbler extends Thread {
InputStream is;
OutputStream os;
String line;
PMRunnerPro main;
public StreamGobbler(InputStream is, OutputStream os, PMRunnerPro main) {
this.is = is;
this.os = os;
this.main = main;
}
#Override
public void run() {
try {
BufferedReader reader = new BufferedReader (new InputStreamReader(is));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));
line = reader.readLine();
while (line != null && ! line.trim().equals("--EOF--")) {
if (main.sSendNeeded) {
System.out.println("Sent");
writer.write(main.sCommand + "\n");
main.sSendNeeded = false;
main.sCommand = "";
}
main.outputBox.setText(main.outputBox.getText() + (line + "\n"));
line = reader.readLine();
}
writer.flush();
} catch(IOException ex) {
main.sRunning = false;
}
System.out.println("Over");
main.sRunning = false;
}
}
The command is sent to the script only when there is an output from the script.
I want the Thread to continuously check if there is any command to send to the script and then do so if there is any.
If I understood your intentions correctly...
Since you using blocking I/O, you need two threads for what you want:
1st thread will read script output, as you do now. Once output available, it will be shown in textarea;
2nd thread will read input from queue and forward it to script.
Here's code draft (notice that you may want to add synchronization between input and output workers, so input worker won't be able to send new command to script until previous command produces output from script, but that's up to you):
class InputWorker implements Runnable {
#Override
public void run() {
try {
BufferedReader reader = new BufferedReader (new InputStreamReader(is));
String line = reader.readLine();
while (line != null && ! line.trim().equals("--EOF--")) {
// show script output
}
} catch(IOException ex) {
//
}
}
}
class OutputWorker implements Runnable {
final BlockingQueue<String> commandQueue = new ArrayBlockingQueue<String>();
public void sendCommand(String command) {
commandQueue.add(command);
}
#Override
public void run() {
try {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));
while (true) {
String command = commandQueue.take();
if ("EXIT".equals(command)) { return; }
writer.write(command);
writer.flush();
}
} catch(IOException ex) {
//
} catch (InterruptedException e) {
//
}
}
}

Categories

Resources