Cómo Compilar y Ejecutar un Programa Java desde otro Programa Java

¿Alguna vez has pensado si es posible compilar y ejecutar un programa Java desde otro programa Java? Podemos usar Runtime.exec(String cmd) para enviar comandos al sistema operativo subyacente. Utilizaremos el mismo enfoque para compilar y ejecutar un programa Java desde otro programa Java.

Compilar y Ejecutar un Programa Java desde otro Programa Java

Vamos a escribir un programa Java simple que será compilado y ejecutado desde otro programa Java.

package com.journaldev.files;

public class Test {

    public static void main(String[] args) {
        System.out.println("Start");
        for(String str : args){
            System.out.println(str);
        }

    }

}

Aquí está el otro programa donde estoy compilando y ejecutando la clase Test.

package com.journaldev.files;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class CompileRunJavaProgram {

    public static void main(String[] args) {
        try {
            runProcess("pwd");
            System.out.println("**********");
            runProcess("javac -cp src src/com/journaldev/files/Test.java");
            System.out.println("**********");
            runProcess("java -cp src com/journaldev/files/Test Hi Pankaj");
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }

    private static void printLines(String cmd, InputStream ins) throws Exception {
        String line = null;
        BufferedReader in = new BufferedReader(
            new InputStreamReader(ins));
        while ((line = in.readLine()) != null) {
            System.out.println(cmd + " " + line);
        }
      }

      private static void runProcess(String command) throws Exception {
        Process pro = Runtime.getRuntime().exec(command);
        printLines(command + " stdout:", pro.getInputStream());
        printLines(command + " stderr:", pro.getErrorStream());
        pro.waitFor();
        System.out.println(command + " exitValue() " + pro.exitValue());
      }

}

Observa la diferencia en los comandos javac y java. Necesitamos hacer esto porque el directorio de trabajo de Eclipse es el directorio raíz del proyecto, pero el directorio de origen de mis clases es src. Cuando ejecuto el programa anterior desde Eclipse, aquí está la salida producida.

pwd stdout: /Users/pankaj/Documents/eclipse-workspace/JavaExceptions
pwd exitValue() 0
**********
Path Serapartor = /
javac -cp src src/com/journaldev/files/Test.java exitValue() 0
**********
java -cp src com/journaldev/files/Test Hi Pankaj stdout: Start
java -cp src com/journaldev/files/Test Hi Pankaj stdout: Hi
java -cp src com/journaldev/files/Test Hi Pankaj stdout: Pankaj
java -cp src com/journaldev/files/Test Hi Pankaj exitValue() 0

Aquí está la salida cuando ejecuto el mismo programa desde la línea de comandos; el directorio de trabajo es el directorio raíz del proyecto.

pankaj:~ pankaj$ cd /Users/pankaj/Documents/eclipse-workspace/JavaExceptions
pankaj:JavaExceptions pankaj$ javac -cp src src/com/journaldev/files/Test.java
pankaj:JavaExceptions pankaj$ javac -cp src src/com/journaldev/files/CompileRunJavaProgram.java 
pankaj:JavaExceptions pankaj$ java -cp src com/journaldev/files/CompileRunJavaProgram
pwd stdout: /Users/pankaj/Documents/eclipse-workspace/JavaExceptions
pwd exitValue() 0
**********
javac -cp src src/com/journaldev/files/Test.java exitValue() 0
**********
java -cp src com/journaldev/files/Test Hi Pankaj stdout: Start
java -cp src com/journaldev/files/Test Hi Pankaj stdout: Hi
java -cp src com/journaldev/files/Test Hi Pankaj stdout: Pankaj
java -cp src com/journaldev/files/Test Hi Pankaj exitValue() 0
pankaj:JavaExceptions pankaj$ 

El programa anterior funcionará bien en sistemas Unix, pero no funcionará en sistemas Windows porque el separador de archivos de Windows es diferente del de Unix. Para asegurarnos de que sea independiente de la plataforma, podemos pasar comandos como argumento a la función principal. La función principal se verá así:

public static void main(String[] args) {
    try {
        if(args.length < 2) throw new Exception("Mandatory Arguments missing");
        runProcess(args[0]);
        runProcess(args[1]);
    } catch (Exception e) {
        e.printStackTrace();
    }
    
}

También podemos usar File.separator para crear los comandos de manera independiente de la plataforma. También podemos obtener esta propiedad del método System.getProperty("file.separator") de System getProperty. El programa anterior puede cambiarse como sigue para obtener un código independiente del sistema.

String separator = File.separator;
System.out.println("File Serapartor = "+separator);

separator = System.getProperty("file.separator");
System.out.println("File Serapartor = "+separator);

runProcess("javac -cp src src"+separator+"com"+separator+"journaldev"+separator+"files"+separator+"Test.java");
System.out.println("**********");
runProcess("java -cp src com"+separator+"journaldev"+separator+"files"+separator+"Test Hi Pankaj");

Obtendrás la misma salida que antes. Eso es todo para usar el método exec de Runtime para compilar y ejecutar un programa Java desde otro programa Java. Los métodos printLines() y runProcess() se toman de esta publicación.

Source:
https://www.digitalocean.com/community/tutorials/compile-run-java-program-another-java-program