Hallo zusammen. In dieser Übung sprechen über die verteilte Ausführung von Java Programmen
Wenn ihr bisher hauptsächlich mit Java IDEs wie Eclipse oder IntelliJ gearbeitet habt
habt ihr euer Java-Programm bisher wahrscheinlich immer über die dort verfügbaren compile and run Funktionen laufen lassen
Wenn ihr euer Programm nun verteilt laufen lassen wollt, habt ihr normalerweise aber keine IDE am Zielrechner offen und könnt es dann nicht "per Hand" starten habt ihr euer Java-Programm bisher wahrscheinlich immer über die dort verfügbaren compile and run Funktionen laufen lassen
Wenn ihr euer Programm nun verteilt laufen lassen wollt, habt ihr normalerweise aber keine IDE am Zielrechner offen und könnt es dann nicht "per Hand" starten
die Programme müssen also per Kommandozeile komplizierten und ausgeführt werden
Kompilieren kann man Java-Programme mittels des Befehls javac -cp
die wichtigsten Parameter dafür schauen wir uns jetzt kurz an
Wenn ihr zusätzliche Bibliotheken für euer Programm benötigt, könnt ihr diese mittels -cp, kurz für class path, einfügen
Mehrere Bibliotheken oder Ordner werden mittels ":" getrennt. Wie ihr sehen könnt sind auch Wildcards wie "*" möglich
"*" expandiert dabei automatisch zu allen .jar-Dateien im jeweiligen Ordner
Mit -d könnt ihr zusätzlich ein Ausgabeverzeichnis für eure .class-Dateien angeben
klassischerweise werden in Java-Projekten die .class-Dateien im bin-Verzeichnis gespeichert.
.java-Dateien dagegen im src-Verzeichnis. Dann ist euer Projekt schön aufgeräumt
Anschließend müssen nur noch die Quelldateien übergeben werden, die ihr kompilieren wollt
includes werden dabei automatisch aufgelöst. Es langt also die Klassen mit main-Methoden hier anzugeben
Das Ausführen von Java-Programmen geht ziemlich analog zum Kompilieren mittels dem Befehl java
auch hier kann mittels -cp der class path um weitere Bibliotheken und Orte erweitert werden
wichtig ist dabei, dass ihr hier auch euer bin-Verzeichnis hinzufügt, wenn ihr es verwendet
Zudem ist es möglich, Systemparameter mittels -D zu definieren
diese könnt ihr dann in eurem Programm per System.getProperty aufrufen
so könnt ihr euer Programm konfigurieren, ohne diese Konfigurationsoptionen tatsächlich als Parameter des Programms übermitteln zu müssen
Nach allen javaspezifischen Konfigurationen sowie den Systemparametern kommt der eigentliche Einstiegspunkt in euer Programm
also die Klasse, die die main-Methode beinhaltet
Alles danach wird als Parameter in euer Programm übergeben. Darauf kann dann wie gehabt über das args String-Array der main-Methode zugegriffen werden
Hier ein kurzes Beispiel dazu: Wir haben eine HalloWelt-Klasse mit einer main-Methode
Wie ihr im Ordnerverzeichnis sehen könnt, haben wir ein src-Verzeichnis und ein bin-Verzeichnis in dem später unsere .class-Dateien liegen sollen
zudem haben wir noch ein mwcc.jar
Um unser Programm zu kompilieren nehmen wir javac -cp mwcc.jar um unser jar zu includen
-d bin um unser bin-Verzeichnis als Ausgabe zu definieren und unsere Klasse
Gut. Jetzt sehen wir, dass in unserem bin-Verzeichnis eine HalloWelt.class erscheint, das ist unsere Klassendatei in der unser Programm ist
mit java, bei -cp müssen wir jetzt das bin-Verzeichnis mit angeben, und unserem Klassennamen können wir unser Programm jetzt ausführen
Natürlich hat euer Programm am Anfang ziemlich sicher einige Bugs, die es zu debuggen gilt
das ist im verteilten Fall leider noch mal schwieriger als sowieso schon
Die erste und einfachste Möglichkeit ist hier das gute alte printf-Debugging
also einfach mittels System.out.println Debug-Ausgaben im Programm zu erzeugen Die erste und einfachste Möglichkeit ist hier das gute alte printf-Debugging
also einfach mittels System.out.println Debug-Ausgaben im Programm zu erzeugen
hierbei ist natürlich zu beachten, dass die Debug-Ausgabe später auch einer bestimmten Programmzeile zugeordnet werden kann
nichts ist frustrierender als stundenlang an der falschen Stelle rum zu schrauben, bis man merkt, dass man zwei Debug-Ausgaben mit der gleichen Nachricht hat
Wenn ihr viele Debug-Ausgaben habt, weil ihr z.B. einen Fehler sucht der nicht deterministisch auftritt und euer Programm daher sehr lange laufen muss
kann es hilfreich sein, die Ausgabe in eine Datei umzuleiten
Dann kann man dort nach speziellen Ausgaben und Mustern suchen und muss nicht durch zig tausend Zeilen Ausgabe scrollen
Im verteilten Bereich möchte man häufig die Debug-Ausgaben verschiedener Prozesse miteinander in Zusammenhang bringen
hier bietet es sich an, die Debug-Ausgaben mit Zeitstempeln zu versehen
natürlich sind auch Zeitstempel keine hundertprozentige Lösung, da die Uhren verschiedener Rechner voneinander abweichen können
um einen groben Blick über die Reihenfolge von Ereignisse zu erhalten, im Sekunden- oder mehrere hundert Millisekundenbereich
ist es aber allemal ausreichend
Ganz wichtig bei printf-Debugging: IO ist wirklich langsam, beeinflusst also sehr wahrscheinlich maßgeblich eure Programmgeschwindigkeit
das kann leicht euer Programmverhalten verändern und Fehler die z.B. durch Race Conditions oder ungünstiges Timing entstehen komplett verdecken
es kann daher leider leicht passieren, dass ein Fehler plötzlich verschwindet wenn ihr Debug-Ausgaben anmacht, was das Ganze nicht wirklich einfacher macht
Presenters
Zugänglich über
Offener Zugang
Dauer
00:13:20 Min
Aufnahmedatum
2020-10-15
Hochgeladen am
2021-04-08 19:17:04
Sprache
de-DE
Verteilte Ausführung von Java Programmen über die Konsole
Hinweis: Video aus der Veranstaltung Middleware im Wintersemester 2020/21