Prozesse verwalten mit Java

Java 9 Bootcamp Logo

JEP 102: "Process API updates"

Das JEP 102 beschäftigt sich damit die rudimentäre Process API von Java zu verbessern, sodass es seltener nötig sein wird auf nativen Code auszuweichen um Prozessinformationen zu erhalten, oder steuernd einzugreifen.

Was ist neu in Java 9?

Ein nativer Prozess, den wir in Java mit dem ProcessBuilder.start oder Runtime.exec starten, wird für den Client durch die Klasse java.lang.Process repräsentiert. Diese Klasse hat eine ganze Reihe von Erweiterungen erhalten.

Wenn man auf eigene Faust erkunden möchte, was es in einer Klasse Neues gibt, ist, neben den JEP-Dokumenten die JavaDoc der beste Weg einen Überblick zu erhalten. Praktischerweise sind die neuesten Änderungen (meist) am Ende des Dokuments aufgeführt und mit "Since: 9" gekennzeichnet.

In Process gibt es 7 neue Einträge:

  • public boolean supportsNormalTermination​()

Gibt true zurück, wenn der Aufruf von destroy() den Prozess normal beendet, false wenn der Prozess dadurch sofort terminiert wird.

  • public long pid​()

Gibt die id des nativen Prozesses zurück.

  • public CompletableFuture onExit​()

Gibt ein CompletableFuture zurück, mit dem man auf das Beenden des Prozesses reagieren kann, zum Beispiel durch das registrieren eines Callbacks.

  • public ProcessHandle toHandle​()

Mit Java 9 wurden die Interfaces ProcessHandle und ProcessHandle.Info eingeführt. ein ProcessHandle identifiziert einen nativen Prozess, und erlaubt desen Kontrolle. Mit ProcessInfo werden zusätzliche Informationen über einen Prozess bereitgestellt. Die Methode toHandle ermöglicht es den zugehörigen ProcessHandle zum Prozess zu erhalten. Intern wird dazu die Methode ProcessHandle.of(pid) verwendet.

  • public ProcessHandle.Info info​()

ProcessHandle.Info liefert Informationen über den Prozess, wie den zugehörigen User, den Aufrufpfad, die Startzeit und die Aufrufargumente. Die verfügbarkeit der Informationen variiert je nach Betriebssystem.

  • public Stream children​()

Delegiert an die Methode children() des zugehörigen ProcessHandle um die Kindprozesse eines Prozesses zurück zu liefern. Da Prozesse asynchron erzeugt und terminiert werden, gibt es keine Garantie, das diese Prozesse alive sind.

  • public Stream descendants​()

Diese Methode liefert neben den direkten Kindprozessen rekursiv auch deren Abkömmlinge.

Was kann der ProcessHandle?

Die meisten neuen Methoden in Process, haben direkt (als Rückgabewert) oder indirekt (durch delegierende Aufrufe) mit ProcessHandle zu tun. Man findet daher in ProcessHandle die meisten Methoden wieder, die schon von Process bekannt sind (destroy, destroyForcibly, info, isAlive, onExit...). Während ein Process aber durch Aufrufen von ProcessBuilder.start oder Runtime.exec erzeugt wird, erhalte ich einen Handle auch für andere Prozesse. Dafür gibt es folgende Methoden:

  • static Optional of​(long pid)

Wenn die native Prozess-id bekannt ist, kann man für den Prozess ein Processhandle bekommen.

  • static ProcessHandle current​()

Gibt den Java Prozess zurück, in dem wir uns befinden.

  • Optional parent​()

Gibt den Elternprozess eines Prozesses zurück, wenn verfügbar.

  • Die Methoden children und descendants kennen wir bereits aus Process. Hier werden sie implementiert.

  • static Stream allProcesses​()

Gibt alle für den gegenwärtigen Prozess sichtbaren Prozesse zurück.

Ob ich den entsprechenden Zugriff erhalte, oder eine SecurityException hängt in den meisten Fällen natürlich davon ab, ob ein SecurityManager installiert ist.

Fazit

Mit ProcessHandle und ProcessHandle.Info sind längst überfällige Features hinzugekommen, die den Zugriff auf Prozesse erleichtern. Viele der Funktionen waren zwar auch zuvor möglich, erforderten aber nativen, plattformspezifischen Code. Mit den neuen Funktionen ist das weitgehend überflüssig geworden.

Besuchen Sie unsere Workshops zum Thema Java 9 um mehr über dieses und weitere neue Features von Java 9 zu erfahren: