You need to read the output (and error) streams from the Process using getInputStream() and getErrorStream(). You’ll need a separate thread for this if you want to wait for the process to complete.
String[] cmd = {"java", "-cp", "C:/Users/..../workspace/Testing/bin", s, str};
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
final InputStream pOut = p.getInputStream();
Thread outputDrainer = new Thread()
{
public void run()
{
try
{
int c;
do
{
c = pOut.read();
if (c >= 0)
System.out.print((char)c);
}
while (c >= 0);
}
catch (IOException e)
{
e.printStackTrace();
}
}
};
outputDrainer.start();
p.waitFor();
If you are using Java 7 and want all output of the process to be redirected to the console, the code is considerably simpler:
String[] cmd = {"java", "-cp", "C:/Users/..../workspace/Testing/bin", s, str};
Process p = new ProcessBuilder(cmd).redirectError(Redirect.INHERIT)
.redirectOutput(Redirect.INHERIT)
.start();
p.waitFor();
The redirectError() and redirectOutput() methods with Redirect.INHERIT cause output to just be sent to the parent Java process.
You need to read the output (and error) streams from the Process using getInputStream() and getErrorStream(). You’ll need a separate thread for this if you want to wait for the process to complete.
String[] cmd = {"java", "-cp", "C:/Users/..../workspace/Testing/bin", s, str};
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
final InputStream pOut = p.getInputStream();
Thread outputDrainer = new Thread()
{
public void run()
{
try
{
int c;
do
{
c = pOut.read();
if (c >= 0)
System.out.print((char)c);
}
while (c >= 0);
}
catch (IOException e)
{
e.printStackTrace();
}
}
};
outputDrainer.start();
p.waitFor();
If you are using Java 7 and want all output of the process to be redirected to the console, the code is considerably simpler:
String[] cmd = {"java", "-cp", "C:/Users/..../workspace/Testing/bin", s, str};
Process p = new ProcessBuilder(cmd).redirectError(Redirect.INHERIT)
.redirectOutput(Redirect.INHERIT)
.start();
p.waitFor();
The redirectError() and redirectOutput() methods with Redirect.INHERIT cause output to just be sent to the parent Java process.
You are executing javac, the language compiler. I believe you want to invoke the java runtime on the class file with your main method. Replace javac with java, and specify your main class.
Here is the way to go:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
// Read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
Read the Javadoc for more details here. ProcessBuilder would be a good choice to use.
A quicker way is this:
public static String execCmd(String cmd) throws java.io.IOException {
java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
Which is basically a condensed version of this:
public static String execCmd(String cmd) throws java.io.IOException {
Process proc = Runtime.getRuntime().exec(cmd);
java.io.InputStream is = proc.getInputStream();
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
String val = "";
if (s.hasNext()) {
val = s.next();
}
else {
val = "";
}
return val;
}
I know this question is old but I am posting this answer because I think this may be quicker.
Edit (For Java 7 and above)
Need to close Streams and Scanners. Using AutoCloseable for neat code:
public static String execCmd(String cmd) {
String result = null;
try (InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
Scanner s = new Scanner(inputStream).useDelimiter("\\A")) {
result = s.hasNext() ? s.next() : null;
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
java - Eclipse gives different output than cmd using runtime exec - Stack Overflow
python - Runtime.getRuntime().exec() won't work in Java Eclipse - Stack Overflow
java - Capturing stdout when calling Runtime.exec - Stack Overflow
How to capture output of java files using Runtime.exec
Videos
You have different system environment in executing from command string and executing from Eclipse.
Variables of environment are valuable : PATH, JAVA_HOME or JRE_HOME and your current worikng directory.
I use ProcessBuilder in cases, when I must be sure in environment, that is provided for external process like yours "java CPU/memory".
I think that first of all your external process have wrong working directory. In ProcessBuilder you can point on it with:
ProcessBuilder pb = new ProcessBuilder("java", "CPU/MEMORY");
pb.directory(new File("/home/myhome/myjavaprojects"));
Process p = pb.start();
Don't ignore the ErrorStream. If you read it (in its own thread), you'll see what you're doing wrong.
For example:
import java.io.*;
public class Foo001 {
public static void main(String[] args) {
System.out.println("hellow");
try {
int x;
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("java CPU/memory");
final BufferedReader in = new BufferedReader(new InputStreamReader(
proc.getInputStream()));
final BufferedReader err = new BufferedReader(new InputStreamReader(
proc.getErrorStream()));
new Thread(new ReadLiner(in, "in")).start();
new Thread(new ReadLiner(err, "err")).start();
// proc.waitFor(); // not sure that this is needed
} catch (Throwable t) {
t.printStackTrace();
}
}
}
class ReadLiner implements Runnable {
private BufferedReader br;
private String text;
public ReadLiner(BufferedReader br, String text) {
this.br = br;
this.text = text;
}
@Override
public void run() {
String line = null;
try {
while ((line = br.readLine()) != null) {
System.out.println(text + ": " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
You need to capture both the std out and std err in the process. You can then write std out to a file/mail or similar.
See this article for more info, and in particular note the StreamGobbler mechanism that captures stdout/err in separate threads. This is essential to prevent blocking and is the source of numerous errors if you don't do it properly!
Use ProcessBuilder. After calling start() you'll get a Process object from which you can get the stderr and stdout streams.
UPDATE: ProcessBuilder gives you more control; You don't have to use it but I find it easier in the long run. Especially the ability to redirect stderr to stdout which means you only have to suck down one stream.
The standard output of Runtime.exec is not automatically sent to the standard output of the caller.
Something like this aught to do - get access to the standard output of the forked process, read it and then write it out. Note that the output from the forked process is availble to the parent using the getInputStream() method of the Process instance.
Copypublic static void main(String[] args) throws Exception {
System.setOut(new PrintStream(new FileOutputStream("test.txt")));
System.out.println("HelloWorld1");
try {
String line;
Process p = Runtime.getRuntime().exec( "echo HelloWorld2" );
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()) );
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
catch (Exception e) {
// ...
}
}
Since JDK 1.5 there is java.lang.ProcessBuilder which handles std and err streams as well. It's sort of the replacement for java.lang.Runtime and you should be using it.