Java-Technologie

Die Arbeitsweise von Java

Als Programm-Grundlage dient der Quelltext, das in Klartext (text/plain) der jeweiligen Programmiersprache verfasste Programm. Daraus können auf unterschiedliche Weise ausführbare Programme ('binaries' in Maschinensprache) erzeugt werden. Hier werden die häufigsten Methoden (Compiler, Interpreter, Java) gegenübergestellt.
Java Java Starker Kaffee
Programme Einige Möglichkeiten, ausführbare Programme zu erstellen
Ausführbare Programme werden mit Compiler und Linker erstellt
Script-Programme sind durch Interpreter sofort ausführbar
Compilierter Byte-Code für einen Virtuellen Computer
Dynamische Bibliotheken sind wiederverwendbare compilierte Programmteile
Dienste (Server-Programme) sind Programme ohne Oberfläche

Programme

Quelltext

Alle Programmiersprachen verwenden als Grundlage Quelltext. Dieser lesbare Text (text/plain) enthält die Anweisungen, entsprechend den Regeln (Syntax) der jeweiligen Programmiersprache.
Quelltext (Source, src) kann man mit jedem Text-Programm (Editor) lesen und ändern.
Der Quelltext enthält die geistige Leistung, es ist daher im Interesse kommerzieller Entwicklung, ihn besonders zu schützen, und möglichst nicht zu verbreiten.
Gute Programmiersprachen erlauben es, den Quelltext unverändert auf beliebigen Betriebssystemen zu verwenden.
Ein Text enthält keine Anweisungen in Maschinensprache und kann daher von keinem Betriebssystem ausgeführt werden. Es gibt verschiedene Methoden, um Quelltext in Maschinen-Code zu übersetzen.

Ausführbare Programme

können vom betreffenden Betriebssystem selbständig ausgeführt werden. Sie enthalten die Anweisungen für den Prozessor in binärer Form (Binaries), d.h. im Maschinen-Code des jeweiligen Prozessors. Darüber hinaus verwenden die meisten Programme Funktionen des Betriebssystems, sie unterscheiden sich daher meist nach Prozessor und Betriebssystem.
Ein ausführbares Programm muss für jeden Prozessor und für jedes Betriebssystem spezifisch hergestellt werden.
Ein binär codiertes Programm ist nicht portabel und kann von Menschen nicht 'gelesen' werden.
Binär codierte Programme werden mit maximaler Geschwindigkeit ausgeführt.

Je nach Programmiersprache werden verschiedene Verfahren verwendet, um den Quelltext in ein ausführbares Programm umzuwandeln. Dabei muss man (je nach Programmiersprache unterschiedlich) ein Kompromiss zwischen einfacher Bedienung und Geschwindigkeit eingehen.
Der beste Kompromiss hat sich in Laufe der kurzen IT-Geschichte geändert:
In der IT-Urzeit arbeiteten die Prozessoren relativ langsam. Daher wurden Programmiersprachen bevorzugt, die mit einem Compiler und einmaliger Übersetzung ausführbare Programm-Dateien (Binaries) erzeugten.
Heutige Prozessoren sind so schnell, dass die Zeit zur Übersetzung von Quelltext vernachlässigbar wird. Daher werden Programmiersprachen bevorzugt, die den Maschinencode mit einem Interpreter bei jeder einzelnen Ausführung neu erzeugen.

Betriebssystem

Ein PC- System enthält zahlreiche Programme, welche zwischen Hardware und Software vermitteln und als Grundlage für alle anderen ausführbaren Programme dienen.
Heutige Betriebssysteme sind einige GB groß und daher auf einem Massenspeicher (Festplatte, in Sonderfällen auf CD/DVD, USB-Stick oder im Netzwerk) gelagert.
Das System wird von einem BIOS-Programm vom Massenspeicher gelesen, in den Arbeitsspeicher kopiert und dann gestartet, d.h. die Kontrolle wird vom BIOS an das System übergeben.

Ein Betriebssystem stellt den Sockel dar, auf dem alle anderen Programme aufbauen. Das System besteht aus vielen Einzelteilen, die in verschiedenen Programmiersprachen erstellt sind. Meist wird dafür die Compiler-Programmiersprache C++ eingesetzt. Kritische Teile sind sogar direkt in Maschinensprache (Assembler) erstellt.

AnwenderInnen-Software setzt auf dem Betriebssystem auf: Solche Programme (Text, Kalkulation, Grafik, Datenbank, Internet ...) werden vom System in den Arbeitsspeicher geladen, dann wird ihnen die Kontrolle übergeben. Fast alle Programme stützen sich bei der Ausführung auf Teile des Betriebssystems, z.B. bei Zugriff auf Hardware (Drucker, Monitor ...) auf die im System geladenen Treiber.
Compiler-Programme
Der Quelltext (z.B.*.cpp) wird mit Hilfe eines Compiler-Programms einmalig in ein ausführbares Programm (Binary) übersetzt. Dieser Vorgang ist relativ aufwändig. Die erzeugten Programme laufen mit maximaler Geschwindigkeit und brauchen dazu kein anderes Hilfsprogramm. Sie sind nicht portabel: Der Quelltext muss für jedes System neu compiliert werden.
Typische Beispiele: C, C++, Fortran, Pascal, ...
C++ Compiler
Script-Programme
Der Quelltext dieser Programme wird bei jeder einzelnen Ausführung von einem Interpreter-Programm (z.B. von php.exe) in Maschinensprache übersetzt und sofort ausgeführt. Das ist besonders einfach und flexibel, kostet jedoch mehr Prozessor-Leistung.
Interpreter-Programme sind System-unabhängig, sie laufen bei sauberer Programmierung ohne Änderung auf jedem Betriebssystem.
Typische Beispiele: Javascript, Perl, PHP, Python, ...
PHP-Interpreter
Java
Der Quelltext *.java )wird einmalig von einem Compiler (javac.exe) in portablen Byte-Code (*.class) übersetzt. Dieser wird vom 'Virtuellen Java-PC' (Java VM) ausgeführt.
Diese Architektur ist ein Kompromiss: Der Byte-Code ist portabel, wird jedoch wesentlich rascher ausgeführt als Interpreter-Programme.
Java ByteCode

Compiler-Programme

Compiler-Programmiersprachen erzeugen Programme in einem 2-stufigen Verfahren:
Am Anfang steht der Quelltext, das sind die Anweisungen in lesbarem Text (text/plain), entsprechend den Regeln (Syntax) der jeweiligen Programmiersprache, z.B. *.cpp
In der ersten Stufe wird der Quelltext von einem Compiler-Programm gelesen und in binäre Maschinensprache übersetzt. Meist werden mehrere Programmteile verwendet, jeder davon ergibt eine *.obj Datei in Maschinencode.
In der zweiten Stufe werden alle obj-Module zusammen mit den verwendeten Bibliotheken (libraries) von einem Linker-Programm zu einem ausführbaren Programm *.exe zusammengestellt.
Standard-Bibliotheken werden von jeder Programmiersprache mitgeliefert, viele andere libraries können aus dem Internet geladen oder gekauft werden.
Die ausführbaren Programme Compiler und Linker und die Bibliotheken sind die Haupt-Bestandteile der jeweiligen Programmiersprache.
Compiler-Programme
Compiler-Technik: Ein Quelltext (hier *.cpp) wird compiliert (= in Maschinensprache *.obj übersetzt), mit Bibliotheken verbunden (Linker), daraus wird ein "Ausführbares Programm" *.exe
Für jedes Betriebssystem (bzw. Version) muss man aus dem Quelltext ein eigenes Programm erzeugen.
Beispiel: Die Programmiersprache C (moderne Version C++) ist die meist verwendete Compiler-Sprache. Ein C++ Compiler ist in jedem modernen Betriebssystemen (Linux) enthalten. (Nur) auf Windows werden ausführbare Programme (binaries) an ihrer Endung *.exe erkannt, in allen anderen Systemen können ihre Namen fast beliebig lauten.
Vorteile:
Compilierte Programme laufen besonders schnell. Alle gängigen Betriebssysteme und AnwenderInnen-Programme sind daher zum größten Teil in C++ erstellt. Noch etwas schneller laufen nur Programme in Maschinensprache (Assembler), deren Entwicklung jedoch sehr aufwändig ist.

Geschützter Quelltext: Die Umkehrung des Compiler-Vorgangs ist außerordentlich aufwändig. Daher ist ein Nachbau des Programm-Quelltextes fast unmöglich. Wer von der Software-Entwicklung leben will, braucht diesen Schutz. Allerdings sind die fertigen binären Programme frei kopierbar. - Das versucht man durch zusätzliche Maßnahmen zu verhindern.
Nachteile:
Die erzeugten Programme laufen jeweils nur auf einem bestimmten Betriebssystem, oft nur auf bestimmten Versionen. Deshalb werden vom gleichen Programm meist verschiedene Versionen für Linux, MacOS, Windows, usw. angeboten. AnwenderInnen müssen sich laufend neue Versionen (updates) besorgen und diese installieren.
Patches sind Programme, welche Teile von installierten Programmen verändern (ausbessern).
Die erzeugten ausführbaren Programme (binaries) sind für Menschen nicht lesbar.
Änderungen erfordern eine komplette Entwicklungs-Umgebung (Compiler, Linker, Bibliotheken, ..) sowie die Verfügung über den Quelltext. Sie können daher meist nur von den EntwicklerInnen vorgenommen werden.

Interpreter-(Script)-Programme

Die unmittelbare Übersetzung vom Quelltext zur Ausführung erfolgt durch Interpreter-Programme. Der Quelltext solcher Programme wird oft als 'Script' bezeichnet.
Der Interpreter 'liest' das Script und führt die Anweisungen sofort aus. Das vereinfacht die Entwicklung radikal, hat aber einen wesentlichen Nachteil: Die Übersetzung (Interpretation) wird bei jeder Wiederholung erneut ausgeführt.
Moderne Prozessoren kompensieren diesen Nachteil durch ihre hohe Leistung. Deshalb nimmt die Bedeutung von Interpreter-Programmiersprachen laufend zu.

Bekanntestes Beispiel: Jeder Browser erhält HTML-Quelltext, 'interpretiert' das HTML-Programm und zeigt das Ergebnis als Webseite an.

Beispiele: → HTML-Webseiten mit oder ohne → Javascript, → Perl, → PHP, → Konsolen-(Kommandozeilen)-Scripts, ...
Interpreter-Programme Script-Interpreter-Technik: Script-Programme in Klartext (*.php) können - einmal erstellt - auf jeder beliebigen Plattform eingesetzt werden. Allerdings wird ein Script-Programm bei jeder einzelnen Anwendung (Wiederholung) vom jeweiligen Interpreter-Programm (z.B. php.exe) erneut in Maschinensprache übersetzt.
Vorteile:
Script-Programme werden universell erstellt, d.h. unabhängig von der jeweiligen Plattform (Betriebssystem und Version).
Die Entwicklung ist besonders rasch und bequem (kostengünstig !), da Script-Programme nach jeder Änderung sofort ausgeführt (interpretiert) werden können.
Viele Programme können mit Text rasch und einfach umgehen. Daher ist es einfach, Programm-Generatoren zu herzustellen: Programme, welche andere (Script)-Programme erstellen. Besonders der letzte Punkt hat rasch steigende Bedeutung, z.B. für Dynamische Webseiten.
Quelltext ist für Menschen lesbar. Scripts eignen sich daher besonders gut für OpenSource-Programme: Diese Programme mit 'Offenem Quelltext' werden kostenlos (und daher auch ohne Garantie) verteilt. Sie sind zu tausenden und für jeden Bedarf im Internet verfügbar.
Nachteile:
Script-Programme werden bei (fast) jeder Verwendung neu in Maschinencode übersetzt (interpretiert) und sind daher langsamer als compilierte Programme.
Sie benötigen zur Ausführung ein klassisches 'ausführbares Programm' - Das Interpreter-Programm. Dieser Interpreter ist selbst ein compiliertes Programm, von dem es für jedes Betriebssystem eine eigene Version geben muss..
Moderne Betriebssysteme (z.B. Linux) bieten selbstverständlich Interpreter für alle gängigen Script-Programme.
Die meisten Interpreter (z.B. für → Perl, → PHP, ..) sind auch für Windows-Systeme kostenlos verfügbar, man muss sie jedoch selbst aus dem Internet laden, installieren und konfigurieren.
Der Quelltext kann nicht geschützt werden. Daher ist die Verwendung dieser Programmiersprachen für kommerzielle Entwicklung weniger interessant. Eine Ausnahme sind kunden-spezifische Programme, die nicht geschützt werden müssen.
Kompensation der Nachteile:
Heutige PC sind (zumindest verglichen mit ihren 'Vorfahren') extrem schnell. Daher verliert der Nachteil der etwas langsameren Ausführung laufend an Bedeutung.
Die Herstellung einer dynamischen Webseite mit einem PHP Script-Programm erfordert typisch Zeiten von einigen Millisekunden und ist daher im normalen Gebrauch nicht als Verzögerung merkbar.

Bei Verwendung von Script-Programmen auf Server-PC ist der Quelltext für AnwenderInnen unzugänglich, da sie nur das vom Programm hergestellte Produkt (z.B. eine Dynamische Webseite) erhalten, nicht jedoch den Quelltext.
Interpreter-Programme für Server sind zwar vor normalen AnwenderInnen geschützt, nicht jedoch vor einem Server-Administrator, welcher auch auf die Quelltext-Dateien Zugriff hat.

Java

Bei Java führt der Weg vom Quelltext zum ausführbaren Programm über eine Zwischenstufe, den Byte-Code.
Byte-Code ist binärer Code, der zur Ausführung auf einem speziellen Software-System vorgesehen ist, der Java Virtual Machine (VM). Java VM ist selbst ein ausführbares Programm, welches auf dem jeweiligen Betriebssystem aufsetzt.
Java VM dient als Interpreter für Byte-Code, d.h. der Byte-Code wird damit in Maschinensprache umgewandelt. Allerdings arbeitet Java VM wesentlich schneller als die Interpreter von Script-Programmiersprachen (s.o.).
Zur Herstellung von Byte-Code aus dem Quelltext dient ein Java-Compiler.
Das Java-System ist daher eine Mischung aus Compiler- und -Interpreter-Systemen.
Java-VM
Die Java-Technik: Ein Quelltext *.java wird vom Compiler javac.exe einmalig in portablen Byte-Code *.class übersetzt. Der Byte-Code kann auf jedem System vom jeweiligen Interpreter java.exe ausgeführt werden.
Vorteile:
Byte-Code ist unabhängig vom Betriebssystem. Solche Dateien *.class sind daher ausgezeichnet portabel.
Programme in Byte-Code werden daher nur einmal compiliert und können dann auf jeder Plattform laufen. Man verwendet für alle Systeme nur eine einzige Version, was auch die Verteilung bedeutend erleichtert.
Die Interpretation von Byte-Code ist wesentlich schneller als die von Script-Programmen. Java ist daher für hohen Rechen-Aufwand (3D-Grafik, Animation) optimal geeignet.
Java-Programme kann man als Applets in Webseiten einbetten. Diese Programme laufen unverändert auf jedem System. Applets dürfen aus Sicherheits-Gründen nicht auf Dateien des lokalen (Client)-PC zugreifen. Ihre Verwendung ist daher sicher.
Auf Servern kann man Java-Programme ("Servlets") als schnelle Generatoren zur Herstellung von Dynamischen Webseiten einsetzen.
Java-Quelltext kann man schützen, daher ist Java für kommerzielle Entwicklung interessant.
Nachteile:
Zum Compilieren von Java-Quelltext *.java zu Byte-Code wird ein Java-Compiler benötigt. Dieses 'Ausführbare Programm' (Runtime engine, JRE) gibt es von Sun / Oracle kostenfrei für alle gängigen Betriebssysteme.
Moderne Betriebssysteme (Linux) enthalten selbstverständlich den JRE oder installieren ihn rasch und einfach. Auch den 'Solution Developer Kit' JDK kann man in jedem gängigen Linux System auf Knopfdruck installieren.
Applets kann man nicht vor dem unerwünschten Kopieren schützen. Sie sind daher für kommerzielle Entwicklung weniger interessant.
Vor der Ausführung eines Java-Programms muss das relativ große JVM-Programm geladen werden. Das macht sich als unangenehme Wartezeit bemerkbar, z.B. bei Einbettung von Java-Applets in Webseiten. Das Programm selbst wird allerdings sehr rasch ausgeführt.

Dynamische Bibliotheken (DLLs)

In der Praxis zeigte sich, dass bestimmte Programm-Teile von vielen verschiedenen ausführbaren Programmen verwendet werden. Diese Teile kann man auslagern und in Form eigener Dateien für alle Programme eines PC zur Verfügung stellen.
DLLs werden meistens in der Programmiersprache C++ erstellt.
Dynamische Bibliotheken (Dynamic Libraries, DLLs) werden zweistufig hergestellt, so wie im Kapitel ↑ Compiler-Programme vorgestellt. DLLs sind jedoch selbst nicht ausführbar.
Auf Windows werden zahlreiche Bibliotheken *.dll verwendet. Sie werden von ausführbaren Programmen bei Bedarf angefordert ('geladen').
Vorteile:
Die wiederverwendbaren Programmteile können von vielen Programmen verwendet werden. Diese Teile können in allen ausführbaren Programmen eingespart werden, es muss nicht jedesmal 'das Rad neu erfunden' werden.
DLLs laufen rasch, da sie in Maschinencode vorliegen.
Updates sind einfacher, da oft nicht das ganze Programm ausgetauscht werden muss, sondern nur einzelne DLLs.
Nachteile:
Bei erstmaliger Verwendung durch ein Programm muss die DLL-Bibliothek erst geladen werden. Diese Verzögerung ist für AnwenderInnen deutlich merkbar.
Im Laufe einer Sitzung (session) häufen sich im Arbeitsspeicher die geladenen DLLs und vermindern laufend die Leistung.
Wie bei allen compilierten Programmen können Änderungen nur durch die EntwicklerInnen erfolgen.
Dynamische Bibliotheken laufen jeweils nur auf einem bestimmten Betriebssystem.
Programme müssen sich auf verwendete DLLs verlassen. Sie funktionieren nicht, wenn eine benötigte DLL fehlt, veraltet ist, oder einfach nicht gefunden wird.
Die Schnittstelle zwischen DLL und jenen Programmen, die DLLs verwenden, ist auf technischer Ebene standardisiert.
Leider gibt es keinen Standard in einer höheren Organisations-Form.
Daher können die meisten Programme nur bestimmte DLLs verwenden, die von den EntwicklerInnen dazu vorgesehen wurden. Die Ergänzung von Programmen mit beliebigen DLL-Bausteinen ist leider nicht möglich.

Dienst (Service, Hintergrund-, Server-Programm)

Normale AnwenderInnen-Programme bieten heute ein oder mehrere 'interaktive' Fenster zur Bedienung.
Bestimmte Programme sollen automatisch laufen, d.h. im 'Hintergrund' auf einem normalen Arbeits-PC oder auf einem eigenen Server-PC.
In diesen Fällen sind interaktive Fenster nicht nur unnötig, sondern störend. So wird z.B. die Systemzeit jedes PC durch ein Hintergrund-Programm weitergezählt, von dem man sich eine vollautomatische Funktion ohne ständige Meldungen erwartet.
In lokalen Netzwerken (LANs) werden mehrere gemeinsam genutzte Dienst-Programme auf einem eigens dafür reservierten PC ausgeführt - Dieser wird als → Server-PC bezeichnet.
Am Server ist niemand da ist, um Meldungen zu lesen oder eine Eingabe auszuführen. Server-PC verfügen meist über keine Ein- oder Ausgabe-Geräte (Monitor, Tastatur, Maus, ..), diese werden nur bei Bedarf (z.B. Service) angesteckt.
Server-Programme kann man in jeder Programmiersprache herstellen, d.h. mit Compiler, Interpreter oder als Java-Bytecode. Sie werden wie jedes andere Programm gestartet, laufen dann jedoch 'im Hintergrund', d.h. ohne sichtbares Fenster. Die Konfiguration (Details zur Programm-Steuerung) ist in einer Konfigurations-Datei festgelegt, die einmalig beim Start des Server-Programms gelesen wird. Auf Linux sind zur Konfiguration einfache Text-Dateien üblich, auf Windows meist die binär codierte Registry-Datenbank.
Server-Programme 'lauschen' (listen) normalerweise inaktiv (an einem bestimmten → Port) auf Aufträge:
Sie bleiben so lange untätig, bis sie einen Auftrag von einem 'Client' erhalten.
Ein Webserver z.B. lauscht auf die Anforderung einer Webseite. Nur in diesem Fall wird er aktiv, sucht die gewünschte Datei und sendet sie an den anfragenden Browser zurück.
Andere Möglichkeiten zur Aktivierung eines wartenden Server-Programms sind bestimmte Ereignisse (events, z.B. Systemstart) oder Zeit-Steuerung (z.B. täglich um 12:00 oder alle 30 Minuten ..).
Auch Server-Programme haben Möglichkeiten zur Weitergabe von Daten:
Die laufende Aktivität und besondere Ereignisse werden in Text-Dateien (Log-Dateien) dokumentiert.
In wichtigen Fällen wird meist ein Mail an den Webmaster gesendet.