I am currently working on an English translation. If you like to help to proofread please contact me: ullenboom ät g m a i l dot c o m.

Java Videotraining Werbung

1. Schnittstellen zum Betriebssystem

Java-Entwicklern fällt oft nicht auf, wie viel die Java-Bibliotheken vom Betriebssystem wegabstrahieren. Ein paar Beispiele: Java setzt automatisch beim Pfadangaben den korrekten Pfadseparator (/ oder \) und bei Zeilenumbrüchen automatisch das übliche Zeilenendezeichen des Betriebssystems. Bei der Formatierung für Konsoleneingaben und dem Parsen von Konsoleneingaben greift Java automatisch auf die eingestellte Landessprache des Betriebssystems zurück.

Nicht nur, dass die Java-Bibliothek diese Eigenschaften intern verwendet, sondern sie sind für alle zugänglich. Die Eigenschaften verstecken sich an unterschiedlichen Stellen, etwa

  • in den System-Properties,

  • in Platform MXBeans, wie der OperatingSystemMXBean mit zum Beispiel getSystemCpuLoad(),

  • in java.net.NetworkInterface für Netzwerkkarten und MAC-Adresse,

  • in Toolkit für die Bildschirmauflösung,

  • in GraphicsEnvironment für die installierte Fonts.

Wenn spezielle Informationen fehlen, können Java-Programme externe native Programme aufgerufen, und mit ihnen kommunizieren und zum Beispiel weitere Details zu erfragen. Die Aufgaben in den Kapitel konzentrieren sich auf die System-Properties und wie man externe Programme aufrufen kann.

Voraussetzungen

  • Interaktion mit der Kommandozeile kennen

  • Umgebungsvariablen auswerten können

  • Externen Programme starten können

Verwendete Datentypen in diesem Kapitel:

1.1. Konsole

Java-Programme bestehen nicht nur aus Algorithmen, sondern sie interagieren mit uns und mit dem Betriebssystem. Zwei der ersten Anweisungen waren System.out.println() und new Scanner(System.in).next() — eine Bildschirmausgabe und Konsoleneingabe sind klassische Schnittstellen zwischen Programm und Benutzer.

System.out und System.err sind vom Typ PrintStream, System.in vom Typ InputStream. Die Klasse System hat Methoden um die drei Ströme umzulenken, etwa in Dateien.

1.1.1. Farbige Konsolenausgaben ⭐

Schon in den allerersten Java-Programmen haben wir auf der Konsole Text ausgegeben. Allerdings zeigt die Textausgabe auf System.out und System.err den Text einmal in schwarz, dann in Rot, es gibt also verschiedene Farben.

In dieser Aufgabe wollen wir uns mit der Frage beschäftigen, wie wir selbst farbige Ausgaben schreiben können. Die Lösung dahinter ist, dass Ausgaben mehr als nur Text schreiben. Es gibt besondere Kommandos, die in der Konsole die Farbe ändern, den Cursor bewegen, den Bildschirm löschen, usw. Dafür sind ANSI-Escape-Sequenzen verantwortlich; sie starten mit einem Control Sequence Introducer, dem String

\u001B[

und enden mit dem String

m

\u001B ist im ASCII-Alphabet das ESC-Zeichen, dezimal 27.

In Java lassen sich Escape-Sequenzen problemlos in den System.out oder System.err schreiben und es gibt einige Bibliotheken wie zum Beispiel https://github.com/fusesource/jansi, die das über Konstanten und Methoden vereinfachen. Problematisch ist lediglich, dass die unterschiedlichen Konsolen nicht zwangsläufig alle Escape-Sequenzen verstehen. In der Standardeinstellung versteht z. B. die CMD.EXE von Windows nichts. Die Unterstützung von einigen Farben ist jedoch bei anderen Konsolen verbreitet:

  • Schwarz: \u001B[30m

  • Rot: \u001B[31m

  • Grün: \u001B[32m

  • Gelb: \u001B[33m

  • Blau: \u001B[34m

  • Magenta: \u001B[35m

  • Zyan: \u001B[36m

  • Weiß: \u001B[37m

  • Zurücksetzen: \u001B[0m

Zur Dekoration eignen sich:

  • fett: \u001B[1m

  • unterstreichen: \u001B[4m

  • invertiert: \u001B[7m

Aufgabe:

  • Lege eine neue Klasse AnsiColorHexDumper an, und setze folgende Konstanten in die Klasse:

    public static final String ANSI_RED    = "\u001B[31m";
    public static final String ANSI_GREEN  = "\u001B[32m";
    public static final String ANSI_BLUE   = "\u001B[34m";
    public static final String ANSI_PURPLE = "\u001B[35m";
    public static final String ANSI_CYAN   = "\u001B[36m";
    public static final String ANSI_RESET  = "\u001B[0m";
  • Schreibe eine neue Methode printColorfulHexDump(Path), die die übergebene Datei einliest und als Hexdump auf der Konsole ausgibt. Unter einem Hexdump versteht man die Ausgabe einer Datei in Hexadezimalschreibweise, also Folgen wie 50 4B 03 04 14 00 06 00 08 00, die in Spalten geschrieben werden.

  • Erweitere das Programm, sodass Farben das Vorkommen von bestimmen Bytes in der Datei deutlich macht. So können zum Beispiel ASCII-Buchstaben in einer Farbe erscheinen, Ziffern aber wieder in einer anderen.

1.2. Properties

Der Begriff Properties ist in Java mehrfach belegt. Er steht für die JavaBean-Properties und für Schlüssel-Werte-Paare, die zur Konfiguration genutzt werden können. Wenn wir diesem Kapitel über ›Properties‹ sprechen, sollen immer Schlüssel-Werte-Paare gemeint sein, insbesondere die Paare, die ein Properties-Objekt verwaltet.

1.2.1. Windows oder Unix oder macos? ⭐

Die System-Properties enthalten eine Reihe von Informationen, die zum Teil auch über Methoden zugänglich sind. Die Javadoc führt unter https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#getProperties-- die Variablen auf.

Aufgabe:

  • Lege einen neuen Aufzählungstyp OS mit Konstanten WINDOWS, MACOS, UNIX, UNKNOWN an.

  • Ergänze eine statische Methoden current(), die mit System.getProperty("os.name") den Namen des Betriebsystems ausliest und das entsprechende Aufzählungselement als Ergebnis liefert.

1.2.2. Kommandozeilenproperties und Properties aus Dateien vereinheitlichen ⭐

Properties lassen sich von der Kommandozeile setzen und können so von außen in ein Java-Programm eingeführt werden. Das soll diese Aufgabe trainieren.

Webserver laufen auf unterschiedlichen Ports, im Entwicklungsmodus in der Regel auf 8080.

Aufgabe:

  • Schreibe ein Programm, das aus unterschiedlichen Quellen die Port-Angaben annehmen kann:

    • Auf der Kommandozeile kann der Port mit --port=8000 angegeben werden.

    • Falls --port nicht existiert, soll eine Umgebungsvariable port ausgewertet werden, die auch auf der Kommandozeile mit -Dport=8020 gesetzt werden kann.

    • Falls die Umgebungsvariable nicht existiert, soll in einer Datei application.properties eine Zuweisung wie port=8888 ausgewertet werden.

    • Falls überhaupt keine Angabe gemacht wurde, ist der Port standardmäßig mit 8080 belegt.

  • Zum Schluss soll der Port ausgegeben werden.

Beispiel für drei Aufrufvarianten:

$ java com.tutego.exercise.os.PortConfiguration
$ java com.tutego.exercise.os.PortConfiguration --port=8000
$ java -Dport=8020 com.tutego.exercise.os.PortConfiguration

1.3. Externe Prozesse ausführen

Als plattformunabhängige Programmiersprache kann Java nicht alles bieten, und so gibt es verschiedene Möglichkeiten, Anfragen an die Host-Umgebung, an das Betriebssystem zu stellen. Eine einfache Möglichkeit ist das Aufrufen externer Programme, was in der nächste Aufgabe gefragt ist.

1.3.1. Über Windows Management Instrumentation den Batteriestatus auslesen ⭐⭐

Bonny Brain spielt auf Ihrem Notebook ein Strategiespiel. Die nächste Runde dauert 30 Minuten, und da Ihr Notebook nur über die Batterie läuft, möchte sie nicht das Spiel abbrechen müssen, wenn die Batterie bald leer ist. Mit folgenden Aufrufen lässt sich unter Windows auf der Kommandozeile die prozentuale verbleibende Laufzeit und die verbleibende Anzahl Minuten geschätzt nach der der aktuellen Last ermitteln:

> wmic path win32_battery get EstimatedChargeRemaining
EstimatedChargeRemaining
10

> wmic path win32_battery get EstimatedRunTime
EstimatedRunTime
37

Ist der Computer kein Laptop mit Batterie ist die Ausgabe ›Keine Instanzen verfügbar.‹ Wenn das Laptop geladen wird, ist das Ergebnis bei EstimatedRunTime 71582788 (hexadezimal 4444444). Details dazu gibt Microsoft unter https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery.

Aufgabe:

  • Starte in einem Java-Programm über den ProcessBuilder das Windows-Programm wmic als externen Prozess und lese das Ergebnis von EstimatedChargeRemaining und EstimatedRunTime aus.

  • Berücksichtige im Programm und in der Ausgabe, dass ein Laptop am Strom betrieben werden kann oder ein Desktop-Computer keine Batterie besitzt.

Das Betriebssystem von Microsoft bietet eine API mit dem Namen Windows Management Instrumentation (WMI), mit der Einstellungen eines Computers ausgelesen und zum Teil verändert werden können. WMI ist vergleichbar mit JMX auf der Java-Seite. Weil oft Shellskripte zwecks Automatisierung auf diese Belegung zugreifen möchten, hat Microsoft eine Kommandozeilenschnittstelle Windows Management Instrumentation Command-line (WMIC) geschaffen.

Ein WMI-Provider liefert Informationen über CPU-Auslastung, Motherboard, Netzwerk, Batteriestatus und vieles mehr. Folgender Aufruf gibt eine kleine Übersicht:

> wmic /?