I am working on a simple java program. It simply compiles and executes another java program. I am using Runtime.exec() function to compile and run. There is no problem with compilation. but when it runs, if the second program needs an input to read from keyboard, I can't give it from the master process. I used getOutputStream() function. but it couldn't help. I will provide my code.
public class sam {
public static void main(String[] args) throws Exception {
try {
Process p = Runtime.getRuntime().exec("javac sam2.java");
Process p2 = Runtime.getRuntime().exec("java sam2");
BufferedReader in = new BufferedReader(
new InputStreamReader(p2.getInputStream()));
OutputStream out = p.getOutputStream();
String line = null;
line = in.readLine();
System.out.println(line);
input=input+"\n";
out.write(input.getBytes());
p.wait(10000);
out.flush();
}catch (IOException e) {
e.printStackTrace();
}
}
}
This is my master program(sam.java).
The following is the code of sam2.java
public class sam2 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str;
System.out.println("Enter the number..\n");
str = br.readLine();
System.out.println(Integer.parseInt(str));
}
}
There is no problem, if my second program has only printing statements. But the problem arises when I have to read something from the other.
Open a command prompt and navigate to the compile-packages-in-java directory. Then type in the command to compile the Person source and hit Enter . Notice that you provided the path of the Java file. This path corresponds to the package name.
Java contains the functionality of initiating an external process – an executable file or an existing application on the system, such as Google Chrome or the Media Player- by simple Java code.
It is a bit strange but you can run the second program without forking it. Just calling the main method in it. So forget the runtime section and do this:
sam2.main(new String[0]);
Of course this way you must compile sam2 at compile time
Each process needs to be allowed to run and finish. You can use Process#waitFor
for this purpose. Equally, you need to consume any output from the process at the same time. waitFor
will block so you will need use a Thread
to read the input (and if you need to, write output to the process)
Depending on the location of the java/class file, you may also need to specify a starting folder from which the execution of the process can start.
Most of this significantly easier using ProcessBuilder
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class CompileAndRun {
public static void main(String[] args) {
new CompileAndRun();
}
public CompileAndRun() {
try {
int result = compile("compileandrun/HelloWorld.java");
System.out.println("javac returned " + result);
result = run("compileandrun.HelloWorld");
} catch (IOException | InterruptedException ex) {
ex.printStackTrace();
}
}
public int run(String clazz) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("java", clazz);
pb.redirectError();
pb.directory(new File("src"));
Process p = pb.start();
InputStreamConsumer consumer = new InputStreamConsumer(p.getInputStream());
consumer.start();
int result = p.waitFor();
consumer.join();
System.out.println(consumer.getOutput());
return result;
}
public int compile(String file) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("javac", file);
pb.redirectError();
pb.directory(new File("src"));
Process p = pb.start();
InputStreamConsumer consumer = new InputStreamConsumer(p.getInputStream());
consumer.start();
int result = p.waitFor();
consumer.join();
System.out.println(consumer.getOutput());
return result;
}
public class InputStreamConsumer extends Thread {
private InputStream is;
private IOException exp;
private StringBuilder output;
public InputStreamConsumer(InputStream is) {
this.is = is;
}
@Override
public void run() {
int in = -1;
output = new StringBuilder(64);
try {
while ((in = is.read()) != -1) {
output.append((char) in);
}
} catch (IOException ex) {
ex.printStackTrace();
exp = ex;
}
}
public StringBuilder getOutput() {
return output;
}
public IOException getException() {
return exp;
}
}
}
Now obviously, you should check the return results of the processes, and may be produce a better mechanism for interacting with the processes, but that's the basic idea...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With