Come compilare ed eseguire un programma Java da un altro programma Java

Hai mai pensato se sia possibile compilare ed eseguire un programma Java da un altro programma Java? Possiamo usare Runtime.exec(String cmd) per emettere comandi al sistema operativo sottostante. Utilizzeremo lo stesso approccio per compilare ed eseguire un programma Java da un altro programma Java.

Compilare ed Eseguire un Programma Java da un Altro Programma Java

Scriviamo un semplice programma Java che verrà compilato ed eseguito da un altro programma 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);
        }

    }

}

Ecco l’altro programma in cui sto compilando ed eseguendo la classe 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());
      }

}

Nota la differenza nei comandi javac e java. Dobbiamo farlo perché la directory di lavoro di Eclipse è la directory radice del progetto ma la mia directory di origine delle classi è src. Quando eseguo il programma sopra da Eclipse, ecco l’output prodotto.

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

Ecco l’output quando eseguo lo stesso programma dalla riga di comando, la directory di lavoro è la directory radice del progetto.

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$ 

Il programma sopra funzionerà correttamente nei sistemi Unix ma non funzionerà nei sistemi Windows perché il separatore di file di Windows è diverso dai separatori di file Unix. Per assicurarci che sia indipendente dalla piattaforma, possiamo passare i comandi come argomento alla funzione principale. La funzione principale sarà così:

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();
    }
    
}

Possiamo anche utilizzare File.separator per creare i comandi in modo indipendente dalla piattaforma. Possiamo ottenere questa proprietà anche dal metodo System getProperty System.getProperty("file.separator"). Il programma sopra può essere modificato come segue per ottenere un codice indipendente dal 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");

Otterrai lo stesso output come sopra. Questo è tutto per l’utilizzo del metodo exec di Runtime per compilare ed eseguire un programma Java da un altro programma Java. I metodi printLines() e runProcess() sono tratti da questo post.

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