CodeGym /Kurse /JAVA 25 SELF /ProcessBuilder – Starten externer Prozesse

ProcessBuilder – Starten externer Prozesse

JAVA 25 SELF
Level 61 , Lektion 0
Verfügbar

1. Was sind Prozesse im Betriebssystem und warum sie aus Java starten

Prozesse: von der JVM zu Bash und zurück

Wenn Sie den Computer einschalten und einen Browser, Messenger oder ein Spiel öffnen – all das sind separate Prozesse. Das Betriebssystem startet für jedes Programm seine eigene „Mini‑Welt“: Es weist Speicher und CPU‑Zeit zu und erlaubt den Zugriff auf Dateien und Netzwerk. So laufen Programme nebeneinander, ohne sich gegenseitig zu stören.

Ein Java‑Programm ist keine Ausnahme. Wenn Sie java MyApp starten, erstellt das System dafür einen eigenen Prozess mit allen benötigten Ressourcen. Darin läuft Ihr Programm: Es rechnet, zeichnet, liest Dateien – alles, was es soll.

Manchmal reicht Java allein jedoch nicht aus. Es kann nötig sein, ein anderes Programm um Hilfe zu bitten – einen Packer zu starten, um Dateien zu verpacken, ffmpeg aufzurufen, um Videos zu verarbeiten, oder einfach herauszufinden, welche Java‑Version auf dem Rechner installiert ist. Das ist das Starten eines externen Prozesses: Java sagt dem System „ruf mir dieses Tool auf“ und erhält anschließend das Ergebnis.

Im Kern ist das ein Weg, ein Programm flexibler zu machen: verschiedene Werkzeuge zu kombinieren, Routineaufgaben zu automatisieren oder Ihre Logik in bereits existierende Systemprozesse einzubetten. Manchmal ist es einfacher, einen externen Befehl einen Teil der Arbeit erledigen zu lassen, statt das Rad im Code neu zu erfinden.

JVM vs. externer Prozess

JVM‑Prozess – Ihr Programm, das in der Java Virtual Machine ausgeführt wird.

Externer Prozess – jedes andere Programm: Taschenrechner, Python‑Skript, Kommandozeile, sogar eine andere Java‑Instanz.

2. Die Klasse ProcessBuilder

In den „alten“ Zeiten startete Java Prozesse über die Methode Runtime.getRuntime().exec(). Das war weder besonders bequem noch sicher – etwa so, als wollte man einen Nagel mit einem Mikroskop einschlagen. Seit Java 5 gibt es daher die Klasse ProcessBuilder, mit der sich externe Prozesse komfortabler und flexibler erstellen, konfigurieren und starten lassen.

ProcessBuilder ist so etwas wie ein „Baukasten“, mit dem Sie alle Parameter des zukünftigen Prozesses im Voraus festlegen können: Befehl, Argumente, Arbeitsordner, Umgebungsvariablen usw.

Syntax: Prozess erstellen

ProcessBuilder pb = new ProcessBuilder("Befehl", "Argument1", "Argument2", ...);
  • Das erste Argument – der Befehlsname (z. B. "ls", "dir", "ping", "java").
  • Die übrigen – die Parameter für den Befehl.

Beispiel: den Befehl ls (Linux/Mac) oder dir (Windows) starten

ProcessBuilder pb;
if (System.getProperty("os.name").toLowerCase().contains("win")) {
    pb = new ProcessBuilder("cmd.exe", "/c", "dir");
} else {
    pb = new ProcessBuilder("ls", "-l");
}

Übrigens sind unter Windows Befehle wie dir, copy usw. keine separaten ausführbaren Dateien, sondern in die Kommandozeile (cmd.exe) „eingebaute“ Befehle. Deshalb müssen sie über cmd.exe /c ... gestartet werden.

Beispiel: einen einfachen Prozess starten

ProcessBuilder pb = new ProcessBuilder("echo", "Hello, Java!");

3. Die Umgebung des Prozesses konfigurieren

Argumente übergeben. Die Argumente des Befehls werden als separate Strings übergeben:

ProcessBuilder pb = new ProcessBuilder("ping", "google.com");

Arbeitsverzeichnis angeben. Standardmäßig wird der Prozess im gleichen Ordner gestartet wie Ihr Programm. Sie können aber auch ein anderes Verzeichnis explizit angeben:

pb.directory(new java.io.File("/tmp"));      // Für Linux/Mac
pb.directory(new java.io.File("C:\\Temp"));  // Für Windows

Umgebungsvariablen ändern. Jeder Prozess hat seinen eigenen Satz an Umgebungsvariablen (environment variables). Diese kann man hinzufügen oder ändern:

pb.environment().put("MY_VAR", "HelloFromJava");

Das kann nützlich sein, wenn der externe Prozess bestimmte Variablen erwartet.

4. Prozess starten

Methode start(). Wenn alles konfiguriert ist, kann der Prozess gestartet werden:

Process process = pb.start();

Die Methode start() liefert ein Objekt Process, mit dem Sie das gestartete Programm steuern können: seine Ausgabe lesen, in seine Eingabe schreiben, es beenden usw.

Ausnahmebehandlung. start() kann eine IOException auslösen, wenn der Befehl nicht gefunden wird, Berechtigungen fehlen oder ein anderer Startfehler auftritt.

Beispiel:

try {
    Process process = pb.start();
    // Mit dem Prozess arbeiten...
} catch (IOException e) {
    System.out.println("Fehler beim Starten des Prozesses: " + e.getMessage());
}

5. Praxis: Einfache Befehle starten

Beispiel 1: Dateiliste in einem Ordner ausgeben

import java.io.*;

public class ProcessDemo {
    public static void main(String[] args) {
        // Befehl abhängig vom Betriebssystem wählen
        ProcessBuilder pb;
        if (System.getProperty("os.name").toLowerCase().contains("win")) {
            pb = new ProcessBuilder("cmd.exe", "/c", "dir");
        } else {
            pb = new ProcessBuilder("ls", "-l");
        }

        try {
            Process process = pb.start();

            // Ausgabe des Prozesses lesen (stdout)
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream())
            );
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            // Auf das Ende des Prozesses warten
            int exitCode = process.waitFor();
            System.out.println("Prozess wurde mit Code beendet: " + exitCode);

        } catch (IOException | InterruptedException e) {
            System.out.println("Fehler: " + e.getMessage());
        }
    }
}

Was passiert hier?

  • Wir ermitteln das Betriebssystem, um den richtigen Befehl zu wählen.
  • Wir erstellen einen ProcessBuilder mit dem benötigten Befehl.
  • Wir starten den Prozess über start().
  • Wir lesen Zeilen aus dem stdout des Prozesses und geben sie auf dem Bildschirm aus.
  • Wir warten auf das Ende des Prozesses (waitFor()).
  • Wir geben den Rückgabecode aus (0 – Erfolg, anderes – Fehler).

Beispiel 2: Start von java -version

ProcessBuilder pb = new ProcessBuilder("java", "-version");
try {
    Process process = pb.start();

    // java -version schreibt nach stderr, deshalb lesen wir getErrorStream()
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(process.getErrorStream())
    );
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
    process.waitFor();
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

Wichtiger Punkt: Manche Befehle (z. B. java -version) schreiben nicht in die Standardausgabe (stdout), sondern in den Fehlerstrom (stderr). Daher muss man manchmal process.getErrorStream() lesen.

6. Plattformübergreifend: Unterschiede zwischen Windows und Linux/Mac

  • Befehle und ihre Parameter können sich unterscheiden.
  • Dateipfade werden unterschiedlich geschrieben (C:\Temp vs. /tmp).
  • Einige Befehle (z. B. ls, cat) gibt es nur in Unix‑ähnlichen Systemen, unter Windows gibt es Entsprechungen (dir, type).
  • Unter Windows werden eingebaute Befehle nur über cmd.exe /c Befehl gestartet.

Beispiel: OS prüfen:

String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
    // Windows
} else if (os.contains("mac")) {
    // macOS
} else if (os.contains("nix") || os.contains("nux")) {
    // Linux
}

Tipp: Testen Sie Ihre Programme immer auf den Zielbetriebssystemen, wenn Sie auf Plattformunabhängigkeit setzen.

7. Tabelle: Zentrale Methoden und Möglichkeiten von ProcessBuilder

Methode/Feld Zweck Beispiel
new ProcessBuilder(String...)
Prozess mit Befehl und Argumenten erstellen
new ProcessBuilder("ls", "-l")
.directory(File)
Arbeitsverzeichnis festlegen
.directory(new File("/tmp"))
.environment()
Umgebungsvariablen abrufen/ändern
.environment().put("VAR", "value")
.start()
Prozess starten
Process p = pb.start()
Process.getInputStream()
stdout des Prozesses abrufen
InputStream
Process.getErrorStream()
stderr des Prozesses abrufen
InputStream
Process.getOutputStream()
stdin des Prozesses abrufen
OutputStream
Process.waitFor()
Auf Prozessende warten
int code = p.waitFor()
Process.exitValue()
Rückgabecode des Prozesses abrufen
int code = p.exitValue()

8. Typische Fehler beim Starten externer Prozesse

Fehler Nr. 1: Befehl nicht gefunden. Wenn Sie sich im Befehlsnamen vertun oder er im System fehlt, erhalten Sie eine IOException: Cannot run program .... Zum Beispiel der Versuch, ls unter Windows zu starten.

Fehler Nr. 2: Falsche Übergabe von Argumenten. Packen Sie nicht den gesamten Befehl in einen einzigen String! Richtig: new ProcessBuilder("ping", "google.com"). Falsch: new ProcessBuilder("ping google.com").

Fehler Nr. 3: Unterschiede der Betriebssysteme nicht berücksichtigt. Ein Befehl, der unter Linux hervorragend funktioniert, kann unter Windows nicht existieren – und umgekehrt. Prüfen Sie immer das OS und passen Sie den Befehl an.

Fehler Nr. 4: Prozessausgabe nicht verarbeitet. Wenn Sie die Ausgabe eines Prozesses nicht lesen, kann er wegen eines vollen Puffers „hängen“ bleiben. Selbst wenn Sie die Ausgabe nicht verwenden wollen – lesen Sie sie und ignorieren Sie sie ggf.

Fehler Nr. 5: Streams nicht geschlossen. Schließen Sie die Streams des Prozesses nach der Verwendung, um Ressourcenlecks zu vermeiden.

Fehler Nr. 6: Ausnahmen nicht behandelt. Das Starten externer Prozesse ist fehleranfällig. Verwenden Sie immer try-catch und informieren Sie den Benutzer über Fehler.

1
Aufgabe
JAVA 25 SELF, Level 61, Lektion 0
Gesperrt
Systeminspektor 🖥️
Systeminspektor 🖥️
1
Aufgabe
JAVA 25 SELF, Level 61, Lektion 0
Gesperrt
Digitaler Spurensucher 📁
Digitaler Spurensucher 📁
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION