小能豆

Running a java program from another java program

javascript

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.


阅读 76

收藏
2023-11-22

共1个答案

小能豆

The issue you are facing is because you are trying to interact with the standard input/output streams of the second Java program (sam2.java) in a way that is not suitable for your use case.

When you use Runtime.getRuntime().exec("java sam2"), it starts a new process for sam2.java, and you try to get its output stream and write to it. However, the second program is waiting for input from the console, and you are trying to provide that input through the output stream, which is not the correct approach.

Instead, you should use the ProcessBuilder class, which allows you to redirect the standard input, output, and error streams of the child process. Here’s an example of how you can modify your sam.java program:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;

public class sam {
    public static void main(String[] args) {
        try {
            // Compile sam2.java
            Process compileProcess = new ProcessBuilder("javac", "sam2.java").start();
            int compileExitCode = compileProcess.waitFor();

            if (compileExitCode == 0) {
                // Run sam2.java
                Process runProcess = new ProcessBuilder("java", "sam2").start();

                // Get the input stream of the child process
                OutputStream childInputStream = runProcess.getOutputStream();

                // Provide input to the child process
                String input = "123\n"; // You can change this input as needed
                childInputStream.write(input.getBytes());
                childInputStream.flush();

                // Wait for the child process to complete
                int runExitCode = runProcess.waitFor();

                // Print the output of the child process
                BufferedReader in = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    System.out.println(line);
                }

                // Print the exit code of the child process
                System.out.println("Exit Code: " + runExitCode);
            } else {
                System.out.println("Compilation failed");
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

This modified code uses ProcessBuilder to start the child processes and redirect their input and output streams. The input for the child process is provided through the output stream, and the output of the child process is read from its input stream. Note that you should handle exceptions appropriately in a production code, and this example simplifies error handling for illustration purposes.

2023-11-22