Anhang A

Anhang A behandelt die erweiterten Tools des JDK und einige Freeware- bzw. Shareware-IDEs für Java.

A.1 Ergänzungen zu den JDK-Tools

In Kapitel 3 haben wir die wichtigsten drei Tools des JDK besprochen:

Das JDK besteht aber zusätzlich aus einer ganzen Reihe von weiteren Tools. Diese sollen hier durchgesprochen werden.

Neben den bereits behandelten Tools des JDK zählen noch einige weitere Programme zu den Basis-Tools. Dazu kommen die Tools für die erweiternden Funktionalitäten. Die Tools für die erweiternden Funktionalitäten von Java lassen sich in verschiedene Gruppen unterteilen, die wir auch getrennt behandeln. Allerdings nur knapp. Eine Ausnahme sind die Sicherheitsprogramme, auf deren Arbeitsweise und Hintergründe wir etwas intensiver eingehen wollen. Eine ausführliche Besprechung aller Programme sprengt jedoch den Rahmen dieses Buchs. Sie werden auch für die meisten Leser von untergeordneter Bedeutung sein. Eine vollständige Abhandlung finden Sie in der offiziellen Dokumentation des JDK.

A.1.1 Erweiterte Basisprogramme

Zu den erweiterten Basisprogrammen werden offiziell Folgende gezählt:

Der Java-Disassembler

Im Gegensatz zu vollständig kompiliertem Maschinencode ist es bei Java-Bytecode möglich, den Quellcode wieder weitgehend zu reproduzieren. Natürlich werden nicht alle Details reproduzierbar sein, aber alle wichtigen Bestandteile des Quellcodes sind wiederherstellbar. Diesen Vorgang der Rückübersetzung von Bytecode in Quellcode nennt man Disassemblierung. Unter Java übernimmt diesen Prozess ein eigenes JDK-Tool, der Java-Disassembler javap.

Nach der Disassemblierung des Codes werden diverse Informationen über den Quelltext ausgegeben. In der Standardeinstellung des Java-Disassemblers werden Informationen über Deklarationen von Definitionen, Methoden, Konstruktoren und statischen Initialisierern ausgegeben, sofern diese nicht private oder protected sind. Mit diversen Optionen kann man diesen Vorgang erweitern und genauer spezifizieren.

Wenn man beispielsweise das klassische Java-HelloWorld-Programm kompiliert und dann per javap disassembliert, erhält man aus dem ursprünglichen Source

class HelloWorld {
    public static void main (String args[]) {
        System.out.println("Hello World!");
    }  }

folgende Source-Datei zurückgeneriert:

Compiled from HelloWorld.java
class HelloWorld extends java.lang.Object {
    public static void main(java.lang.String []);
    HelloWorld();
}

Es wird auffallen, dass bereits ohne besondere Optionen ausführliche Angaben über die Superklasse (extends java.lang.Object) sowie die Methoden-argumente (java.lang.String []) explizit aufgeführt werden.

Die Syntax für den Java-Disassembler:

javap [Optionen] [Klassenname(n)]

Wie aus der Syntax bereits herleitbar ist, können in einem Schritt mehrere Klassen disassembliert werden. Die Klassen werden alle, durch jeweils ein Leerzeichen getrennt, hintereinander aufgelistet.

Wichtig ist auch hier wieder, dass die Angabe der Erweiterung .class unbedingt unterbleiben muss.

Option Beschreibung
-help Anzeige von Hilfe
-c Diese Option weist den Disassembler an, sämtliche Instruktionen der JVM (public, jedoch auch private und protected) -auszugeben, also die Quelldatei zu disassemblieren und den vollständigen Bytecode, der vom Compiler erzeugt wird, anzuzeigen. Aus dem oben angeführten HelloWorld wird die disassemblierte Version: Compiled from HelloWorld.java
class HelloWorld extends java.lang.Object {
public static void main(java.lang.String []);
HelloWorld();
Method void main(java.lang.String [])
0 getstatic #7 <Field java.lang.System.out Ljava/io/PrintStream;>
3 ldc #1 <String "Hello World!">
5 invokevirtual #8 <Method java.io.PrintStream.println(Ljava/lang/String;)V>
8 return
Method HelloWorld()
0 aload_0
1 invokenonvirtual #6 <Method java.lang.Object.<init>()V>
4 return
}
-classpath
[Verzeichnis]
Diese Angabe korrespondiert wie bereits beim Compiler und Interpreter mit der gleichnamigen Umgebungsvariable und teilt in diesem Fall dem Disassembler mit, in welchen Verzeichnissen nach den einzelnen Klassen zu suchen ist. Die Verzeichnisse werden in der Unix-Syntax durch Doppelpunkte getrennt, Windows benutzt das Semikolon. Auch ist für Pfadangaben zu beachten, dass die Komponenten eines Pfades unter Unix mittels des Slash und unter Windows mittels des Backslash voneinander getrennt werden. Die angegebenen Pfade werden in der Reihenfolge ihres Auftretens durchsucht.
-bootclasspath path Spezifiziert den Pfad, von wo die bootstrap classes zu laden sind (Default ist jre\lib\rt.jar und jre\lib\i18n.jar).
-extdirs dirs Überschreibt den Pfad, wo Erweiterungen für das JDK gesucht werden (default jre\lib\ext).
-verbose Diese Option veranlasst den Disassembler, diverse Statusinformationen (z.B. Stack, Variablen, Argumente usw.) über den Quellcode anzuzeigen, während er gerade disassembliert wird.
-l Gibt zusätzlich noch Zeilennummern und lokale Variablen aus. Aus dem Beispiel oben wird Compiled from ErstesJavaProgramm.java
class HelloJava extends java.lang.Object {
public static void main(java.lang.String[]);
HelloJava();
}
Line numbers for method void main(java.lang.String[])
line 3: 0
line 2: 8
Line numbers for method HelloJava()
line 1: 0
-b Stellt die Rückwärtskompatibilität zu früheren Versionen sicher.
-public Zeigt nur die öffentlichen Klassen und Bestandteile an.
-protected Zeigt die geschützten und die öffentlichen Klassen und Methoden an.
-private Zeigt alle Klassen und Methoden an.
-s Zeigt interne Typ-Signaturen an.
-package Zeigt die Pakete, die geschützten und die öffentlichen Klassen und Methoden an (Default).
-J Flag Gibt ein Flag direkt an das Runtime-System weiter. Beispiele: javap -J-version
javap -J-Djava.security.manager -J-Djava.security.policy=MeinePolicy MeinKlassenName

Tabelle A.1:   Die Javap-Optionen

Javap gibt die Ausgabe der Dissamblierung standardmäßig auf den Bildschirm aus. Um den Source in eine neue Datei auszugeben (etwa zur späteren Weiterverwendung), können Sie unter der DOS/Windows-Eingabeaufforderung die Technik des Umleitens nutzen. Mit dem Umleitungszeichen > leiten Sie die Ausgabe des Befehls in eine beliebige Datei um. Die Datei mit dem rechtsseitig angegebenen Namen wird erstellt, die dann den zurückübersetzten Quelltext enthält. Dieser kann dann beliebig weiter bearbeitet und unter Umständen sogar neu kompiliert werden (Achtung: Es fehlen je nach verwendeter Option Klassen oder einiger ihrer Bestandteile).

javah - das Tool zur Erstellung von C-Header- und Stub-Dateien

Der javah-Generator erstellt C-Header (Erweiterung .h) und C-Quelldateien (Erweiterung .c) für die angegebenen Klassen. Diese so generierten Dateien enthalten alle notwendigen Informationen zur Implementierung von nativen Methoden, beispielsweise #include- und #define-Anweisungen, typedef-Konstrukte u.ä. Normalerweise generiert javah nur ein Headerfile für die angegebenen Klassen. Innerhalb dieses Headerfiles wird eine C-Struct deklariert, die alle notwendigen Felder enthält, die mit den Instanzfeldern der ursprünglichen Java-Klassen korrespondieren. Innerhalb dieser Header-Datei wird ebenfalls bereits eine Funktion für jede native Methode definiert, die in der zugehörigen Quelldatei implementiert werden muss.

Ein Aufruf von javah im klassischen HelloWorld-Programm in Java

class HelloWorld {
    public static void main (String args[]) {
        System.out.println("Hello World!");
    }  }

wird die folgende Header-Datei erzeugen:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <native.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
typedef struct ClassHelloWorld {
    char PAD;  /* ANSI C requires structures to have a least one member */
} ClassHelloWorld;
HandleTo(HelloWorld);
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

Auch so genannte Stub-Dateien, d.h. C-Dateien, die neben der Header-Datei zusätzliche, notwendige Rumpffunktionen für die Einbindung von nativen Methoden in der Java-Umgebung enthalten, können von javah generiert werden. Bei Angabe der Option -stubs zur Erzeugung von Stub-Dateien generiert bei unserem klassischen Java-HelloWorld-Programm eine .c-Datei, die wie folgt aussieht:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <StubPreamble.h>
/* Stubs for class HelloWorld */

Bei komplexeren Java-Programmen wird in demselben Maße das javah-Resultat entsprechend anspruchsvoller und nimmt Programmierern viel Arbeit ab.

javah generiert standardmäßig eine C-Datei in dem aktuellen Verzeichnis, deren Name identisch zu dem im Aufruf spezifizierten Klassenname ist. Wenn dieser Klassenname ein Paket enthält, so enthalten die C-Dateien sämtliche Komponenten des Paketnamens. Allerdings werden diese nicht durch Punkte, sondern durch Unterstriche getrennt.

Die Syntax von javah:

javah [Optionen] [Klassenname ]

Klassenname ist der Name der Java-Klassendatei ohne die Dateinamenserweiterung.

Option Beschreibung
-help Hilfe
-version Die Version des JDK
-classpath -[Verzeichnis] Identisch mit den anderen Tools
-bootclasspath path Identisch mit den anderen Tools
-verbose Identisch mit den anderen Tools
-d [Verzeichnis] Mit dieser Option wird javah gezeigt, in welchem Verzeichnis sich die Header oder Stub-Dateien nach der Generierung befinden sollen. Normalerweise wird das aktuelle Verzeichnis verwendet. Diese Option und die Angabe der Option -o schließen sich aus.
-stubs Diese Option veranlasst javah, Stub-Dateien statt der Standard-Header-Dateien zu erzeugen.
-o [Dateiname] Mit dieser Option wird javah veranlasst, die Stubs- oder Header-Dateien in die mit Dateiname spezifizierte Datei (eine Datei, in der alle .h- oder .c-Dateien kombiniert werden) einzufügen. Bei der Datei kann es sich um eine normale Textdatei, um eine Header-Datei ([Dateiname].h) oder eine Stub-Datei ( [Dateiname].c) handeln.
-jni javah wird angewiesen, im erzeugten Header-File JNI-style native method function prototypes zu generieren.
-old Gibt an, dass Header-Dateien nach dem alten JDK1.0-Konzept erstellt werden sollen.
-force Erzwingt die Erstellung einer Ausgabedatei.

Tabelle A.2:   Die javah-Optionen

Das Dokumentations-Tool javadoc

Eines der am meisten unterschätzten Tools im JDK ist javadoc. Das JDK verfügt damit über ein feines, eigenes Dokumentations-Tool, das auf der Basis von speziellen Kommentar-Tags innerhalb einer Java-Quelldatei (es gibt drei Formen von Kommentaren in Java, hierfür wird die folgende Form benötigt: /** Kommentartext */ ) eine HTML-Datei als API-Dokumentation der angegebenen Datei oder des Paketes erzeugt.

Vereinfacht gesagt, schreibt javadoc die innerhalb der Datei in den javadoc-Kommentaren eingeschlossenen Texte kurzerhand in eine HTML-Datei. Darin können sich beliebige Informationen befinden. Es bleibt im Prinzip dem Programmierer überlassen, was er mit diesen Kommentaren über seinen Quelltext dokumentieren möchte. Außerdem kann man die Kommentare mit Steueranweisungen zur Erzeugung von Hyperlinks und speziellen Tags erweitern.

Allerdings benötigt man dafür kein eigenes Tool, auch mit einem Editor ist dies halbwegs machbar. Es werden zusätzlich noch automatische Informa-tionen über die Klassen, Interfaces, Vererbungshierarchien, Methoden, Variablen und Hyperlinks, die mit dem Java-Programm in Verbindung stehen können, aufgeführt. Die erzeugte Dokumentation enthält sämtliche als public und protected deklarierte Elemente. Javadoc wurde ursprünglich von den SUN-Entwicklern erstellt, um die Java-API-Dokumentation zu erzeugen.

Die Leistungsfähigkeit dieses Tools wird besonders deutlich, wenn man Anspruch und Wirklichkeit bezüglich der Dokumentation in Software-Projekten gegenüberstellt. In der professionellen Software-Entwicklung sollte Planung bzw. Konzeption eines Projekts mit ca. 30 % oder mehr einkalkuliert werden (es kommt stark auf die Rahmenbedingungen an, aber die Größenordnungen stimmen ungefähr). Die Realisierierung schlägt dann vielleicht mit 50 % zu Buche und der Rest (also ca. 20 %) sollte für die Dokumentation zur Verfügung stehen. Die Praxis sieht dann meist so aus, dass nach 30 % der Zeit mit der Realisierung zwar begonnen wird, die Planung und Konzeption aber noch nicht abgeschlossen ist und ständig Veränderungen in der Realisierungsphase bewirkt. Diese Phase benötigt dann 90 % der Zeit1 und wo bleibt dann noch Kapazität für die Dokumentation? Oft wird sie als nicht so wichtig betrachtet. Je mehr Schitte der Dokumentation dann mit einem Tool erfolgen können, das automatisch die wichtigsten Details herausarbeitet, desto besser. In dieser Hinsicht ist javadoc vielleicht sogar das einzige Tool des JDK, das man in der Praxis nicht durch ergänzende oder alternative Tools ersetzt.

Die zu dokumentierende Datei muss mindestens eine public oder protected deklarierte Klasse enthalten.

Die Syntax von Javadoc:

javadoc [Optionen] [Dateiname] [Paketname] [@files]

Dateiname ist die .java-Datei bzw. der Paketname. Die Datei kann sowohl ohne die Dateinamenserweiterung, als auch mit Erweiterung angegeben werden kann (leider wieder keine konsistente Syntaxlogik bzgl. der anderen JDK-Programme). Wenn ein Paketname angegeben worden ist, dann dokumentiert javadoc alle Java-Quelldateien innerhalb des aktuellen Verzeichnisses und anschließend das dazugehörige Paketverzeichnis (als Paketname zu verstehen und nicht etwa als ein physikalisches Verzeichnis). Für jede Klasse wird ein eigenes HTML-Dokument erzeugt und für die Klassen innerhalb des Paketes wird ein HTML-Index generiert. Standardmäßig werden also minimal vier HTML-Dateien (eine Index-Datei, [Name der Datei].html, packages.html und tree.html) generiert.

Abbildung A.1:  Aus einer Java-Datei werden per javadoc alle anderen Dateien generiert.

Abbildung A.2:  Die Dokumentation erfolgt im Stil der Java-Online-Dokumentation.

In der ersten Version von javadoc gab es noch die unangenehme Eigenart, bei Aufruf ohne Parameter einfach anzufangen zu dokumentieren. Was? Das wußte javadoc ebenfalls nicht und so folgte zwangsläufig irgendwann eine Fehlermeldung. Durchaus vergleichbar mit einem Taxifahrer, der einfach losfährt, nachdem der Gast eingestiegen ist. Aber ohne nach dem Weg zu fragen. Erst ein paar Straßen weiter kommt dann die Rückfrage, wo es eigentlich hin gehen soll. Seit dem JDK 1.1.x ist das glücklicherweise vorbei und es wird eine Kurzbeschreibung mit allen Parametern auf dem Bildschirm ausgegeben.

Die javadoc-Optionen

Mittlerweile sind die Optionen des Dokumentations-Tools so umfangreich geworden, dass wir hier nur eine Zusammenfassung der wichtigsten Optionen angeben wollen. Diejenigen Optionen, die mit den bisher beschriebenen Optionen der anderen Tools übereinstimmern, haben auch die dort beschriebene Funktion. Das Dokumentations-Tool des JDK versteht u.a. folgende Optionen, die teilweise selbsterklärend sind und oft auch weggelassen werden können (für Details sei auf die Online-Dokumentation verwiesen):

-1.1, -author, -bootclasspath, -bottom, -classpath, -d, -docencoding,        -doclet, -
docletpath, -doctitle, -encoding, -extdirs, -footer, -group,       -header, -help, -helpfile, 
-J, -link, -linkoffline, -locale, -nodeprecated,  -nodeprecatedlist, -nohelp, -noindex, -
nonavbar, -notree, -overview,         -package, -private, -protected, -public, -sourcepath, -
splitindex,           -stylesheetfile, -title, -use, -verbose, -version, -windowtitle

Das Dokumentations-Tool des JDK wurde für die Version 1.2 erheblich überarbeitet. Hier folgt eine Liste mit den wichtigsten Veränderungen:

  • -use - Hinzufügen einer Cross-Referenzdokumentation (Beschreibung, dass das API andere APIs verwendet)
  • -link und -linkoffline - Generierung von Links auf existierende Dokumentationen, die mit javadoc-generiert wurden
  • -windowtitle - Angabe des Titels, der in das HTML <title>-Tag geschrieben wird
  • -doctitle - Titel der Seite (bisher die Option -title)
  • -group - Unterteilung von Paketen in Gruppen.

Die Funktion eines Dokumentations-Tools muss sich naturgemäß von den übrigen Tools ein wenig unterscheiden. Insbesondere werden Querverweise (»siehe auch ...«) eine wichtige Rolle bei der Dokumentation spielen. Diese können jedoch nicht als Aufrufparameter übergeben werden, sondern müssen wie oben beschrieben Bestandteile des Quelltextes sein. Sie werden dort innerhalb der Kommentar-Tags mit einem speziellen Zeichen eingeleitet (die so genannten javadoc-Tags). Die Tags beginnen nach dem eigentlichen Kommentarbeginn alle mit dem Zeichen @.

Die javadoc-Tags

Tag Beschreibung
@link Setzt einen in-line-Link an diesem Punkt.
@version Mit diesem Tag kann die Version des Programms spezifiziert werden.
@throws Wie @exception.
@since Spezifiziert, wann das Release erstellt wurde.
@serialField Dokumentiert eine ObjectStreamField-Komponente eines serialPersistentFields-Mitglieds einer Serializable-Klasse.
@serialData Beschreibt die Daten, die von der writeObject()- und der Externalizable.writeExternal()-Methode geschrieben werden.
@serial Dokumentation eines serialisierbaren Defaultfeldes.
@see Dieses Tag erzeugt einen Verweis in der HTML-Datei.
@return Mit diesem Tag kann der Wert beschrieben werden, der von einer Methode zurückgegeben wird.
@param Dieses Tag dient zu Dokumentation der Parameter.
@exception Dieses Tag erzeugt ein Link auf Ausnahmen, die von der Klasse erzeugt werden.
@deprecated Der Tag markiert ein Klasse, ein Interface, ein Feld oder eine Methode als nicht zu verwenden in weiteren Anwendungen. So gekennzeichneter Code wird dennoch weiter kompiliert und laufen, aber der Compiler - natürlich nur der einer neueren Generation - wird eine Warnung generieren, dass Sie Ihren Code bzgl. dieses Ausdrucks updaten sollten.
@author Dieses Tag fügt den Namen des Autors in die HTML-Datei ein.

Tabelle A.3:   Die javadoc-Tags

Beispiel für einen Quelltext mit javadoc-Kommentar und javadoc-Tags:

/**
* Um was es geht.
* @version  3.42
* @author  Ralph Steyer
*/
class HelloWorld {
/* Kommentarform 2 - wird von javadoc nicht brücksichtigt*/
    public static void main (String args[]) {
        System.out.println("Hello World!");
    }  }

Beachten Sie, dass der javadoc-Kommentar außerhalb der Klassendefinition steht. Dies ist wichtig, denn der Generator ignoriert den Kommentar bei einer Verschachtelung mit einer Klassendefinition.

jdb - der Java-Debugger >

Als Nächstes soll der Java-Debugger jdb, das Debugging-Werkzeug des JDK, behandelt werden. Es handelt sich nicht um einen integrierten Debugger, wie er mittlerweile in den meisten Entwicklungsumgebungen üblich ist. Den Debugger können Sie nur über Befehlszeileneingaben steuern. Er verfügt nur über eine ähnliche Syntax wie die bekannten Unix-Debugger dbx oder gdb. Allerdings ist er in der Lage, neben den lokalen Dateien auch Dateien auf entfernten Systemen (Anwendungen und Applets) auf Fehler zu überprüfen. In diesem Fall müssen Sie die notwendigen -host und die -password-Optionen verwenden.

Mit dem jdb können Sie beliebig Haltepunkte setzen und die Werte der Variablen ausgeben lassen. Steppen durch den Source - sprich das Programm in Einzelschritten auszuführen - wird ebenfalls unterstützt. Der Code in der Umgebung eines Haltepunktes kann jederzeit aufgelistet werden. Sie können jedes Mal, wenn das Programm angehalten oder unterbrochen wird, den Stack mit den Aufrufen untersuchen. Weiter unterstützt jdb die Bewegung durch die Threads in Ihrem Code. Exceptions sind ein weiterer Problemfall, wo Sie jdb unterstützt, indem er die Ausnahmen (auf Wunsch) auffängt, selbst wenn sie im Programm nicht aufgefangen werden. Erst einmal abgefangen, können Sie dann die Variablen und den Stack untersuchen.

Im JDK 1.3 wurde der Debugger erheblich überarbeitet, sodass er in vielen Details nicht mehr mit seinem Vorgänger des JDK 1.2 übereinstimmt. Dafür kam im JDK 1.3 das Debugging-Tool oldjdb hinzu, was im Wesentliche dem Vorgänger des aktuellen jdb entspricht2. Dieses ist - wie alle mit old beginnenden Tools - für die Arbeit mit Quellcode vorhanden, der bestimmte Kriterien älterer Java-Versionen nutzt, die mit dem neuen Standard nicht vereinbar sind. Der neue Debugger jdb wurde gegenüber seinem Vorgänger bezüglich seiner erlaubten Optionen erheblich erweitert.

Man muss trotz der unbestrittenen Leistungsfähigkeit von jdb festhalten, dass seine Bedienung wohl die meisten Wünsche im JDK offen lässt. Sie ist relativ umständlich. Außerdem setzt die Verwendung von jdb recht viel Hintergrundwissen voraus. Auch wer sich mit dem Debuggen schon auskennt, wird mit einem integrierten Debugger leichter zum Erfolg kommen.
Vorbereitung einer Debugger-Sitzung

Bevor Sie den Debugger verwenden, müssen Sie Ihre Klassen erst einmal entsprechend kompilieren, damit für den Debugger genügend Informationen zur Verfügung stehen. Dazu müssen Sie den Java-Compiler mit der Option -g ausführen.

Die Syntax für die vorbereitende Kompilierung:

javac -g [Name der Datei].java

Das Ergebnis dieser Kompilierung sollte ein nicht optimierter Bytecode sein, den jdb für den Zugriff auf die Symboltabellen für lokale Variablen benötigt. jdb hängt sich auf Grund dieser Information quasi in den Bytecode hinein. Eine jdb-Debugging-Sitzung lässt sich auf zwei (drei, wenn man Interpreter- und Appletviewer-Sitzung unterscheidet) verschiedene Arten starten. Sie können jdb veranlassen den Java-Interpreter mit den zu bearbeitenden Klassen im Debugging-Modus zu starten oder Sie können jdb starten und dazu auffordern, sich an einen laufenden Java-Interpreter (bzw. einen laufenden Appletviewer) anzuhängen. jdb versteht dieselben Optionen wie der Java-Interpreter. Sie können den Debugger also einfach anstelle des Interpreters aufrufen und sämtliche Optionen des Interpreters verwenden. Natürlich besitzt er aber auf Grund seiner weitergehenden Funktionen zusätzliche eigene Optionen.

Auch hier gilt wieder, dass der Compiler zwingend die Erweiterung .java voraussetzt. jdb jedoch benötigt in der Folge die Erweiterung .class nicht zwingend. Es ist jedoch in diesem Fall auch kein Fehler, was wieder eine der vielen Inkosistenzen im JDK ist.
Direkter Aufruf des Debuggers

Eine Debugger-Sitzung kann man auf vielfältige Weise durchführen. Die üblichste Methode ist der direkte Aufruf des Debuggers mit der zu untersuchenden Klasse, die eine main()-Methode enthalten muss.

Die eigentliche Syntax für den direkten Aufruf des Debugger ist nicht sonderlich umfangreich:

jdb [Optionen] [KlassenName]
oldjdb [Optionen] [KlassenName]

Die Optionen des Debuggers sind im JDK 1.3 gegenüber den Vorgängerversionen erheblich verändert und erweitert worden.

Option Beschreibung
-host [Hostname] Diese Option informiert jdb bzw. oldjdb, auf welchem Rechner sich das entfernte Java-Programm befindet. Hostname steht dabei für den DNS-Namen des Remote-Computer.
-password [password] Diese Option gibt das Passwort für die Java-Datei auf einem entfernten System, das vom Java-Interpreter mit der -Xdebug Option angegeben wurde, an jdb bzw. oldjdb weiter. Bei einer Arbeit auf einem entfernten Rechner ist ein solches Passwort oft zwingend. Außerdem muss das Passwort verwendet werden, wenn man den Debugger als Zweitprozess nach Start des Interpreters verwenden möchte.
-help Hilfe (jdb bzw. oldjdb)
-version Debuggerversion (jdb bzw. oldjdb)
-dbgtrace Ausgabe von Informationen über jdb bzw. oldjdb
-sourcepath <Verzeichnisse getrennt durch ";"> Verzeichnisse, die durchsucht werden sollen (nur jdb)
-attach <Addresse> Anhängen an eine laufende VM an der spezifizierten Adresse mit dem Standard-Connector (nur jdb)
-listen <Addresse> Warten auf eine laufende VM an der spezifizierten Adresse mit dem Standard-Connector (nur jdb)
-listenany Warten auf eine laufende VM an einer beliebigen Adresse mit dem Standard-Connector (nur jdb)
-launch Direkter Start statt auf das run-Kommando zu warten (nur jdb)
-connect <Connector-Name>:<name1>=<value1>,... Verbindung zu der Ziel-VM über den angegebenen Connector mit dem aufgelisteten Argumenten aufbauen (nur jdb).
-thotspot Die Applikation mit der im JDK 1.3 neu eingeführten Hotspot(tm) Performance Engine laufen lassen (nur jdb).
-tclassic Die Applikation mit der klassischen VM laufen lassen (nur jdb).

Tabelle A.4:   Die Optionen von jdb und oldjdb im JDK 1.3

Wenn Sie jdb direkt im Befehlszeilenmodus unter DOS (oder Xterm) mit der Angabe einer Klasse gestartet haben, wird die Ausgabe im entsprechenden Fenster etwa so aussehen:

Initializing jdb...

Bis jetzt wurde der Code noch nicht ausgeführt. Deshalb sehen Sie im Ausgabefenster nicht viel mehr als diese Zeile. Wenn Sie jdb auf diese Weise benutzen, startet er den Java-Interpreter mit den jeweils in der Befehlszeile festgelegten Parametern, lädt die spezifizierte Klasse und hält an, bevor die erste ausführbare Anweisung der Klasse ausgeführt wird. Wie es weiter geht, werden wir gleich sehen. Vorher aber besprechen wir noch die weiteren Aufrufmöglichkeiten für den Debugger.

Start des Debuggers als Folgeprozess des Interpreters

Neben dem direkten Aufruf des jdb können Sie das Programm gleichermaßen mit dem Java-Interpreter starten und anschließend jdb als getrennten Prozess aufrufen, der Ihrem laufenden Programm dann hinzugefügt wird. Dieser Weg ist zwar nicht so üblich, wir wollen ihn dennoch skizzieren. Dazu müssen Sie den Interpreter mit der Option -Xdebug und Angabe der entsprechenden Klasse starten. Vor der Ausführung der angegebenen Klasse gibt java ein Passwort aus. Dieses Passwort muss dann als Befehlszeilen-Parameter für jdb benutzt werden und jdb wird sich dann mit diesem Passwort in den Prozess einklinken. Wenn Sie jdb und das Java-Programm auf zwei verschiedenen Rechnern laufen lassen wollen, müssen Sie zusätzlich beim Start von jdb die Option -host angeben.

Die Syntax zum Aufruf des jdb nach Start des Java-Interpreters (in zwei Schritten):

java -Xdebug [KlassenName] 
jdb -host [Hostname] -password [password]

Diese zweite Methode müssen Sie zum Debuggen des Programms verwenden, sofern Sie ein Betriebssystem haben, das die Eingabe nur über den Standard-Input bezieht. In diesem Fall besteht das Problem, dass jede Eingabe, die Sie eintippen, als Eingabe für jdb behandelt wird, wenn Sie jdb bereits gestartet haben. Bei der Benutzung der zweiten Methode können Sie zwei separate Eingabeströme verwenden: einen für Ihr Programm, einen für jdb.

jdb zum Debuggen eines Applets starten

Wenn Sie ein Applet mit jdb debuggen wollen, gehen Sie analog wie bei der zweiten Methode mit dem Interpreter vor. Sie starten nur in diesem Fall den Appletviewer aus der Befehlszeile mit der Option -debug3. Das Resultat ist jedoch sehr unterschiedlich gegenüber Methode 2. Es wird jdb gestartet, der wiederum den Appletviewer ohne weitere Aufrufe startet, jedoch anhält, bevor eine ausführbare Zeile im Appletviewer ausgeführt wird. Um die Ausführung im Appletviewer zu starten, müssen Sie run eingeben. Jedes Applet der HTML-Datei wird in einem einzelnen Fenster gestartet:

Die Syntax zum Debuggen eines Applets:

appletviewer -debug [Html-DateiName]

Wenn Sie den Appletviewer erst einmal in der Debug-Einstellung gestartet haben, antwortet jdb mit einigen Zeilen, die in etwa wie bei Methode 1 aussehen. Bis jetzt wurde der Code noch nicht ausgeführt. Deshalb sehen Sie im Ausgabefenster nicht viel mehr als diese Zeilen.

Die jdb-Befehlszeile

Egal wie Sie eine Debugger-Sitzung starten, in jedem Fall sollten Sie sich jetzt auf der Befehlszeilenebene des Debuggers befinden. Sie erkennen diess an dem jdb-Prompt, das auf Ihre Eingaben wartet - egal ob Sie eine Klasse geladen haben oder nicht. Sie können nur die diversen Kommandos an den Debugger geben, wobei diese zum einen erst einmal erkannt, aber auch in der richtigen Reihenfolge angewandt werden müssen. Wie schon angedeutet - der Debugger ist leistungsfähig, aber sehr unkomfortabel. jdb unterstützt folgende Kommandos für das Debuggen (Auflistung in alphabetischer Reihenfolge):

Kommando Beschreibung
!! Der zuletzt eingegebene Befehl wird nochmals wiederholt.
? Erzeugt eine Liste aller gültigen Kommandos für den Debugger.
catch [exception] Das Kommando bewirkt eine Unterbrechung des Programmablaufs, sobald die angegebene Exception ausgelöst wird. Wenn kein Parameter angegeben wird, erhält man eine Liste der Ausnahmen, die aufgefangen werden.
classes Gibt die Namen und IDs der Klassen aus, die bereits geladen worden sind.
clear[class:line] Entfernt Haltepunkte, die bei der angegebenen Klasse an der angegebenen Zeile gesetzt worden sind. Der Aufruf ohne Parameter generiert eine Angabe aller gesetzten Haltepunkte.
cont Der aktuelle, unterbrochene Thread wird fortgesetzt (continue).
down[n] Durch das Kommando wird der aktuelle Stack-Bereich eines Threads um n Frames nach unten gesetzt. Ohne Parameter wird der Frame um eine Einheit nach unten bewegt. Dazu gehört das umgekehrte Kommando up.
dump id(s) Mit dump werden alle Felder (Werte der Variablen) einer Klasse oder der Instanz einer Klasse des angegebenen Objekts bzw. der Objekte angegeben, wenn Sie als id den Namen einer Klasse oder der Instanz einer Klasse angeben. dump <classname> gibt die Werte der Variablen der statischen Klasse aus, und dump this oder dump <classInstanceVariableName> die Werte der Mitgliedsvariablen. Objekte und Klassen können sowohl durch Ihren Namen als auch durch eine achtstellige Hexadezimalzahl (ihrer Identifikator-ID) angegeben werden. Ebenso können Threads durch die Angabe der Kurzbezeichnung t@thread-number angegeben werden.
exit (oder quit) Beenden des Debuggers
gc Erzwingt die direkte Ausführung des Garbage Collectors.
help Identisch mit dem Kommando ?
ignore <exception> Unterbindet die Ausführung einer Unterbrechung der angegebenen Ausnahme. Das bedeutet, sie wird aus der Ausnahmenliste des jeweiligen catch-Kommandos entfernt. Beachten Sie, dass der ignore-Befehl die spezifizierte Ausnahme nur im Fall des Debuggers ignoriert; der Java-Interpreter wird Sie weiterhin auffangen. ignore ohne Parameter listet die Ausnahmen in der catch-Liste auf.
list [Zeilennummer] Zeigt den Quellcode an der angegebenen Zeilenummer an. Wenn keine Zeilennummer angegeben wird, wird die Zeile angegeben, die im aktuellen Frame des des aktuellen Threads steht. Um Quellcode-Zeilen aufzulisten, muss das Programm zunächst an einem Haltepunkt angehalten werden oder Sie müssen bereits einen Thread spezifiziert haben und diesen Thread dann unterbrechen. Andernfalls antwortet jdb mit einer Fehlermeldung (No thread specified or Current thread isn't suspended.) Wenn ein Thread unterbrochen wurde, anstatt an einem Haltepunkt angehalten worden zu sein, müssen Sie den Zusammenhang mit dem Thread über den Thread-Befehl spezifisch festlegen. Sie müssen sich dann eventuell im Stack mit dem up-Befehl nach oben bewegen, um den Stack-Kontext in dem Code Ihres Programms festzulegen. Wenn sich die Quelle zu den Klassen, die Sie bearbeiten wollen, nicht im eingestellten Klassenpfad befindet (oder in dem Klassenpfad, der durch den Befehlszeilen-Parameter -classpath festgelegt wurde), kann jdb die Quelle nicht auflisten. Allerdings gibt es für diesen Fall den Befehl use, um einen Dateipfad zur Quelle festzulegen.
load [Klassenname] Die mit Klassenname angegebene Klasse wird in den Debugger geladen.
locals locals gibt die lokalen Variablen des aktuellen Stack-Bereichs aus. Dafür muss allerdings zwingend der Bytecode mit der Compileroption -g erzeugt worden sein.
memory memory zeigt den Speicherbedarf des aktuellen Programms bis zum derzeitigen Zeitpunkt an. Sowohl der freie als auch der gesamte verfügbare Speicher wird angezeigt.
methods <Klasse> Durch diesen Befehl werden alle Methoden der angegebenen Klasse angezeigt.
print id(s) Der Debugger zeigt mit diesem Befehl die Werte für eine angegebene Klasse, ein Objekt, ein Feld oder eine lokale Variable an. id kann sowohl ein Name als auch ein Identifikator - die Objekt-ID - sein. Die Objekt-ID einer Klasse wird beim Laden derselben angezeigt oder kann mit dem Kommando classes nachträglich abgefragt werden. Durch die Angabe der speziellen Syntax t@thread-number ist es möglich, sich auf spe-zielle Threads zu beziehen. Das Kommando print -verwendet zur Ausgabe die Methode toString().
resume [thread1 ...threadN] Veranlasst den Debugger, die angehaltenen Threads wieder fortzuführen. Wenn keine Parameter angegeben worden sind, werden alle mit dem Kommando suspend angehaltenen Threads wieder fortgeführt.
run [Klasse] [arg1...argN] Dieses Kommando startet die Ausführung der angegebenen Klasse, d.h., es führt die main()-Methode der angegebenen Klasse aus. Die optionalen Parameter arg1 bis argN werden gegebenenfalls übergeben. Falls keine Argumente angegeben worden sind, wird die Klasse ausgeführt, die beim Start von dem Debugger angegeben worden ist.
step Führt die aktuelle Zeile des aktuellen Threads aus und stoppt im Anschluss daran.
stop [at Klasse:Zeile] Setzt einen Haltepunkt in der angegebenen Zeile der Klasse. Ohne Angabe der Argumente werden alle gesetzten Haltepunkte ausgegeben.
stop [in Klasse:Zeile] Setzt einen Haltepunkt am Anfang der angegebenen Methode der Klasse. Ohne Angabe der Argumente werden alle gesetzten Haltepunkte ausgegeben.
suspend [thread1...threadN] Die angegebenen Threads werden unterbrochen. Falls kein Argument angegeben worden ist, werden alle aktiven Threads unterbrochen. Mit resume können die Zustände von Threads wieder geändert und die Threads wieder gestartet werden.
thread [thread] Nach Aufruf des angegebenen Threads in diesem Kommando wird dieser zum aktuellen Thread.
threadgroup [Name der threadgroup] Wenn Sie sich einen Thread außerhalb der voreingestellten Thread-Gruppe ansehen wollen, müssen Sie zuerst die entsprechende Thread-Gruppe über den threadgroup-Befehl spezifizieren. Nach Aufruf dieses Kommandos ist die angegebene Thread-Gruppe die aktuelle Thread-Gruppe, und Sie können sich einen einzelnen Thread herauspicken.
threadgroups Zeigt alle gerade aktiven Threadgruppen innerhalb eines Programms an. Sie werden mit aufsteigenden Nummern davor aufgelistet, gefolgt vom Klassennamen, wiederum gefolgt vom Handle der Thread-Gruppe und dem Namen der Thread-Gruppe. Nur die Thread-Gruppen von Threads, die gestartet wurden, werden angezeigt.
threads [threadgroup1... threadgroupN] Listet alle Threads in der angegebenen Gruppe auf. Wenn keine Gruppe angegeben worden ist, werden die Threads der aktuellen Gruppe angegeben. Threads werden mit vorangestellten Indexnummern aufgelistet. Der letzte Bestandteil einer Threadzeile ist der Zustand des Threads. Nur Threads, die bereits gestartet wurden, werden angezeigt.
up[n] Durch das Kommando wird der aktuelle Stack-Bereich eines Threads um n Frames nach oben gesetzt. Ohne Parameter wird der Frame um eine Einheit nach oben bewegt. Dazu gehört das umgekehrte Kommando down.
use [Sourcefile Pfad] Setzt den Pfad, den jdb verwenden soll, um nach eventuell benötigten Quellcodes zu suchen. Der Befehl use, ohne irgendwelche Parameter, veranlasst jdb dazu, den Pfad aufzulisten, den er gerade zum Finden des Quellcodes verwendet. use, gefolgt von einem Datei-Pfad, ändert den Pfad der Quelldatei auf den neu angegebenen Pfad. Die bei den anderen Tools verwendete Option -classpath hat eine ähnliche Bedeutung. jdb folgt dem spezifizierten Pfad, um den Quellcode zu finden.
where [thread] [all] Bewirkt die Ausgabe des Stacks für den angegebenen Thread. Falls kein Thread angegeben worden ist, wird der Stack des aktuellen Threads angezeigt. Durch Angabe des Arguments all können alle Stacks angezeigt werden.

Tabelle A.5:   Die Kommandos an den Debugger

Ab der Version 1.2 unterstützt die Java Virtual Machine Low-Level-Services für das Debuggen. Die API für diese Low-Level-Services ist das Java Virtual Machine Debugger Interface (JVMDI). Deren detaillierte Behandlung sprengt jedoch den Rahmen des Buchs. In der JDK-Dokumentation finden Sie mehr dazu.

jdb reagierte in der Version 1.2 (oldjdb tut es immer noch) ganz witzig auf einen Fehler bei der Befehlseingabe, wenn er einen Befehl nicht kennt: Auf > xit (Buchstabe vergessen) kommt folgende Antwort von jdb:
huh? Try help...
>

Das Java Archive Tool (jar)

Bereits ab der JDK-Version 1.1.1 können Java-Programme JAR-Dateien (Java-Archive mit der Erweiterung .jar) nutzen. Statt vieler einzelner und unkomprimierter Dateien kann man ein gepacktes Archiv verwenden und auch über Netze übertragen. Der Vorteil dieses Konzepts liegt bei Netzwerkaktionen darin. dass die Applikation in einer einzigen Transaktion übertragen wird und nicht in vielen einzelnen Übertragungsschritten. Außerdem wird die Datenmenge ziemlich komprimiert.

JAR-Archive basieren auf der ZIP-Technologie und dem ZIP-Format. Zu der Theorie der Datenkomprimierung finden Sie einen kleinen Exkurs im Anhang C.

Zum Erstellen der Java-Archive wird das Java Archive Tool jar genutzt. Man kann beliebig viele Java-Klassen und andere Ressourcen zu einer einzelnen JAR-Datei damit zusammenfassen.

Die Syntax für jar:

jar [Optionen] [manifest] [JAR-Datei] [Eingabedatei(en)]

Die Syntax besteht aus vier Bestandteilen nach dem Programmaufruf:

  • Den Optionen.
  • Der mit manifest bezeichneten Teil der Syntax gibt eine Datei an, die sämtliche Meta-Informationen über das Archiv enthält. Eine Manifest-Datei wird immer automatisch vom jar-Tool generiert und ist immer der erste Eintrag in der .jar-Datei. Sie müssen diese Angabe nur dann machen, wenn Sie eine vom Defaultwert abweichende Datei als Meta-Informationsdatei des Archives verwenden wollen. Andernfalls wird diese Meta-Informationsdatei mit Namen META-INF/MANIFEST.MF erstellt.
  • JAR-Datei ist der Name des zu erstellenden oder zu dekomprimierenden Java-Archivs.
  • Eingabedatei(en) bezeichnet die Datei(en), die komprimiert werden sollen. Dabei kann mit Wildcards gearbeitet werden (z.B. *.class für die Komprimierung alle Klassendateien im Verzeichnis in der angegebenen JAR-Datei). Die Dateien müssen beim Entkomprimieren nicht unbedingt angegeben werden.

Das jar-Tool ist in der Syntax den weit verbreiteten DOS-Komprimierungsprogrammen lha oder arj sehr ähnlich. Es gibt aber einen wichtigen Unterschied, denn die nachfolgenden Optionen sind immer gekoppelt. Dies bedeutet Folgendes: Eine der Optionen -{ctx} muss angegeben werden und wird dann meistens mit der entsprechenden weiteren Option aus [vfm0M] kombiniert. Dabei können zwar die Optionen aus den beiden Bereichen in der Reihenfolge vertauscht werden; sie dürfen aber nicht alleine verwendet werden, sondern nur in Verbindung mit zwei Optionen aus dem Trippel -{ctx}.

Beispiele:

jar -fc test.jar *.class
jar -xf test.jar *.class

Dies ist etwas gewöhnungsbedürftig, jedoch wenn Sie sich nicht daran halten, kann es sogar passieren, dass eine Fehlermeldung (im günstigsten Fall) das Resultat ist oder sich das Tool sogar aufhängt (scheinbar). Wenn das Tool auf Befehlszeilenebene wartet, probieren Sie einmal die Tastenkombination STRG+Pause aus. Auf dem Standard-Ausgabegerät werden die Aktionen seitenweise ausgegeben.

Optionen Beschreibung
-c Diese Option generiert ein neues oder leeres Archiv auf dem Standard-Ausgabegerät. Dies bedeutet, wenn Sie die Option alleine verwenden, füllt sich in der Regel der Bildschirm mit Sonderzeichen. Diese Option macht nur Sinn in Kombination mit einer anderen Option. Das folgende Kommando jar -fc test.jar *.class erstellt aus sämtlichen in dem Verzeichnis vorhandenen Dateien mit der Erweiterung .class ein JAR-Archiv test.jar.
-t Listet eine Tabelle des Inhalts einer Datei auf dem Standard-Ausgabegerät auf. Allerdings macht diese Option nur Sinn in Kombination mit einer anderen Option, etwa jar -tf test.jar *.class
-x [Datei] Extrahiert alle Files oder die namentlich angegeben Dateien. Auch hier gilt, dass in Verbindung mit der weiteren Option -f die Hauptanwendung zu sehen ist.
-f Nur als zweites Argument für die Aktionen Erstellen, Extrahieren oder Inhaltsangabe zu verwenden. Die Option spezifiziert die zu bearbeitende JAR-Datei.
-v Generiert eine Statusausgabe auf das Standardausgabegerät. Die Option macht nur Sinn in Verbindung mit laufenden Aktionen, die mit anderen Optionen ausgelöst werden.
-m Integriert Manifest-Informationen in die angegebene Manifest-Datei.
-0 Nur Zusammenfassung von Dateien. Es wird keine ZIP-Kompression verwendet. Ein solches JAR-Archiv kann nicht im Suchpfad von Tools spezifiziert werden.
-M Generiert keine Manifest-Datei.
-u Update einer existierenden JAR-Datei, indem Dateien hinzugefügt werden. Beispiel: jar -uf mein.jar meineKlasse.class
-C Wechselt Verzeichnisse während der Ausführung eines jar-Kommandos.

Tabelle A.6:   Die jar-Optionen

Wenn in der Angabe der Dateien ein Verzeichnis auftaucht, wird dieses Verzeichnis rekursiv verarbeitet.

Dieses Tool unterscheidet bei den Optionen zwischen Groß- und Kleinschreibung.

Das Utility für jar-Konflikte - extcheck

Zu den Basis-Tools zählt auch das Programm extcheck, ein Diagnose-Tool für JAR-File-Versionskonflikte. Damit können solche Probleme zwischen jeder JAR-Datei und den JAR-Dateien aufgedeckt werden, die als Erweiterung der JDK-Software installiert sind.

Die Syntax für extcheck:

extcheck [ -verbose ] targetfile.jar

Die Option -verbose listet alle JAR-Dateien auf, die überprüft wurden.

A.1.2 Internationalization Tools

Diese Art von Programmen umfasst nur das Programm native2ascii, das Text in Unicode nach der Norm Latin-1 konvertiert. Der Java-Compiler und andere Java-Tools können nur mit in Latin-1 und/oder Unicode-verschlüsselten (\udddd-Notation) Dateien arbeiten. Der Native-To-ASCII Converter konvertiert eine native-kodiertes Datei (nicht-Latin-1 und nicht-Unicode) in eine reine ASCII-Datei, das die \udddd-Unicode-Notation beinhaltet. Die umgekehrte Richtung funktioniert genauso.

Syntax:

native2ascii [Optionen] [inputfile [outputfile]]

Wenn die Output-Datei weggelassen wird, wird die Standard-Ausgabe verwendet. Wenn die Input-Datei weggelassen wird, wird die Standard-Eingabe verwendet.

Option Beschreibung
-reverse Diese Option veranlassst native2ascii, Unicode- oder Latin-1-kodierten Text in native-kodierten Text zu übersetzen.
-encoding [Verschlüssel_name] Spezifiziert den Verschlüsselungsnamen, der bei der Konvertierung verwendet wird. Dieser Verschlüssel_name-String muss als korrektes Argument der Klasse CharacterEncoding definiert sein.

Tabelle A.7:   Die native2ascii -Optionen

Hier ist eine kleine Liste mit möglichen Verschlüsselungsnamen:

8859_1 ISO Latin-1
8859_2 ISO Latin-2
8859_3 ISO Latin-3
8859_5 ISO Latin/Cyrillic
8859_6 ISO Latin/Arabic 
8859_7 ISO Latin/Greek 8859_8 ISO Latin/Hebrew 
8859_9 ISO Latin-5 
Cp1250 Windows Eastern Europe / Latin-2 
Cp1251 Windows Cyrillic 
Cp1252 Windows Western Europe / Latin-1 
Cp1253 Windows Greek 
Cp1254 Windows Turkish 
Cp1255 Windows Hebrew 
Cp1256 Windows Arabic 
Cp1257 Windows Baltic 
Cp1258 Windows Vietnamese 
Cp437 PC Original 
Cp737 PC Greek
Cp775 PC Baltic 
Cp850 PC Latin-1 
Cp852 PC Latin-2 
Cp855 PC Cyrillic 
Cp857 PC Turkish 
Cp860 PC Portuguese 
Cp861 PC Icelandic 
Cp862 PC Hebrew 
Cp863 PC Canadian French 
Cp864 PC Arabic 
Cp865 PC Nordic 
Cp866 PC Russian 
Cp869 PC Modern Greek 
Cp874 Windows Thai 
EUCJIS Japanese EUC 
JIS JIS 
MacArabic Macintosh Arabic 
MacCentralEurope 
Macintosh Latin-2 
MacCroatian Macintosh Croation
MacCyrillic Macintosh Cyrillic 
MacDingbat Macintosh Dingbat 
MacGreek Macintosh Greek 
MacHebrew Macintosh Hebrew 
MacIceland Macintosh Iceland 
MacRoman Macintosh Roman 
MacRomania Macintosh Romania 
MacSymbol Macintosh Symbol 
MacThai Macintosh Thai 
MacTurkish Macintosh Turkish 
MacUkraine Macintosh Ukraine 
SJIS PC and Windows Japanese 
UTF8 Standard UTF-8

A.1.3 Security Tools

Das JDK beinhaltet diverse Sicherheitsprogramme. Diese Programme sind zum Setzen und Verwalten von Sicherheitspolicen auf Ihrem System gedacht. Sie können damit Applikationen entwickeln, die mit anderen Sicherheitspolicen zusammenarbeiten.

  • keytool dient zum Schlüssel- und Zertifikat-Management. Es wird eine Datenbank mit privaten Schlüsseln und ihren zugehörigen X.509-Zertifikaten sowie den Zertifikaten von vertrauenswürdigen Entities verwaltet. Dieses Tool basiert auf dem DSA-Algorithmus mit der SHA-1 Signatur.
  • jarsigner generiert oder verifiziert eine digitale Signatur für eine JAR-Datei.
  • policytool ist ein GUI-Tool (d.h. mit grafischer Oberfläche) für das Management von Policy-Dateien.
  • Das digitale Signierungs-Tool javakey verwaltet Datenbankentitäten, inklusive ihrer Schlüssel, Zertifikate und ihren Vertrauensebenen. Allerdings nach dem alten Java-Sicherheitsmodell. Dieses Tool ist als eine der bedeutendsten Neuerungen in der Version 1.2 durch die Programme keytool und jarsigner sowie policytool ersetzt worden.

Mit dem Thema Verschlüsselung und Datensicherheit müssen wir ein Thema ansprechen, in dem Sun bei der Version 1.1 einen kleinen Flop landeten. Zwar ist Java auch hier mittlerweile erwachsen geworden und in der Version 1.1 kam mit javakey ein wichtiges Tool zum JDK. Dieses Programm hat sich allerdings als teilweise nicht voll befriedigend herausgestellt und ist als eine der bedeutendsten Neuerungen in der Version 1.2 durch die Programme keytool und jarsigner sowie policytool ersetzt worden.

Wir wollen für die Besprechung der Hintergründe der Java-Sicherheits-Tools dennoch hauptsächlich javakey verwenden. Zum einen können wesentliche Hintergrundinformationen über Verschlüsselung und Datensicherheit daran recht gut erklärt werden und die Anwendung der neuen Programme ist weigehend analog. Zum anderen werden wohl noch einige Leser weiter mit javakey arbeiten wollen! Besonders diejenigen Anwender, die bereits mit javakey eine Datenbank an Schlüsseln aufgebaut haben, stehen sonst vor einem gewissen Problem. Die beiden Programme keytool und jarsigner ersetzen javakey zwar vollständig und bieten eine Fülle neuer Features (etwa Schutz der Datenbank und der privaten Schlüssel mit Passwörtern). Die beiden Programme sind jedoch ausdrücklich nicht abwärtskompatibel zu dem Keystore- und Datenbankformat, das von javakey in dem JDK 1.1 verwendet wurde.

javakey

javakey ist ein kommandozeilenorientiertes Sun-Sicherheits-Tool, dessen primäre Anwendung das Generieren von digitalen Signaturen für Archive ist. Eine Signatur verifiziert, dass eine Datei von einer bekannten Quelle kommt. Um eine Signatur für eine Datei zu generieren, muss zuerst ein öffentlicher Schlüssel und dann ein privater Schlüssel generiert werden, mit dem der öffentliche Schlüssel dann wieder dekodiert werden kann. javakey erstellt solche Schlüssel und eine Datenbank zur Verwaltung der Schlüssel und der zugeordneten Zertifikate, die den Status der Vertrauenswürdigkeit dokumentieren.

Die Syntax für javakey:

javakey [Optionen]

Zu den Hintergründen und der Theorie der Datenverschlüsselung finden Sie einen Exkurs im Anhang. Sowohl javakey als auch die neueren Tools verwenden defaultmäßig eine Verschlüsselung nach dem DSA-Standard (Digital Signature Algorith>) bzw. darauf aufbauenden Verfahren.

Es gibt zwei Arten von Einträgen in der Datenbank, die von javakey verwaltet werden:

  • Identities
  • Signers

Unter Identities (Identitäten) kann man sich jede Form juristischer Personen aus der realen Welt (Personen, Firmen, Organisationen) vorstellen. Diese haben von Ihnen einen öffentlichen Schlüssel bekommen. Weiter kann eine Verbindung zwischen dem öffentlichen Schlüssel einer Identity und einem oder mehreren Zertifikaten bestehen. Ein Zertifikat ist eine digitale Unterschrift dieser verwalteten juristischen Personen. Sie überprüft, von wem das mit dem öffentlichen Schlüssel kodierte Datenpaket stammt. Wenn also mehrere juristische Personen denselben öffentlichen Schlüssel zum Kodieren verwenden, können Sie durch die digitale Unterschrift eine eindeutige Zuordnung vornehmen.

Signers sind juristische Personen, die zu einem öffentlichen Schlüssel auch einen passenden privaten Schlüssel haben. Um ein Datenpaket eindeutig zu signieren, müssen ein öffentlicher Schlüssel und ein passender privater Schlüssel vorhanden sein sowie ein Zertifikat zur Sicherstellung der Authentizität des öffentlichen Schlüssels.

Wenn Ihnen jemand also ein Datenpaket zuschicken will, und Sie sollen es als vertrauenswürdig einstufen, dann läuft der Vorgang bei der Verwendung von einem Programm wie javakey normalerweise folgendermaßen ab.

1. Mit dem Sicherheitsprogramm erstellen Sie einen öffentlichen Schlüssel und einen dazu passenden privaten Schlüssel. Beide werden vom Sicherheitsprogramm in einer Datenbank verwaltet.
2. Das Objekt Ihrer Wahl aus der realen Welt (Personen, Firmen, Organisationen) bekommt den öffentlichen Schlüssel.
3. Ein Zertifikat mit der speziellen digitalen Unterschrift für die jeweilige juristische Person wird ausgetauscht. Diese digitale Unterschrift kann von Ihnen mit dem Sicherheitsprogramm erstellt und dem Partner zugeschickt werden, sie kann aber auch vom Partner erstellt und Ihnen zugeschickt werden. In beiden Fällen tragen Sie mit dem Sicherheitsprogramm diese digitale Unterschrift in der Datenbank bei dem passenden Schlüsselpaar ein.
4. Wenn Sie nun ein Datenpaket erhalten, können Sie den Absender auf Grund der digitalen Unterschrift identifizieren und nur Sie sind durch Ihren privaten Schlüssel in der Lage, das Datenpaket zu dekodieren.

Sie können in javakey wie in den meisten so arbeitenden Sicherheitsprogrammen sowohl Schlüssel und Zertifikate neu erstellen als auch bestehende Schlüssel importieren.

Jede Datenbank benötigt zur Verwaltung einen internen Zugriffsschlüssel für die darin enthaltenen Datensätze. Alle Objekte (Identities und Signers) haben in der lokalen Datenbank einen von javakey verwalteten Username. Dieser Username ist der interne und eindeutige Schlüssel zum Verwalten der Datenbank. Das Hinzufügen eines Eintrags in die Datenbank mit der Option -c (create identity) oder -cs (create signer) ist eine Verwaltungsaktion, wo ein solcher Username vergeben wird. Alle javakey-Kommandos müssen anschließend diesen eindeutigen Username zur Referenz auf ein Objekt verwenden.

Lassen Sie uns ein Beispiel - wieder unter der Verwendung von javakey - durchsprechen:

Der Befehl javakey -cs safetyfirst true generiert einen als vertrauenswürdig eingestuften Signer und weist ihm den Username safetyfirst zu (Ausgabe: Created identity [Signer]safetyfirst[identitydb.obj][trusted]).

Anschließend werden mit javakey ein öffentlicher und ein privater Schlüssel generiert. Für unser Beispiel soll ein Schlüssel mit 512 Bit nach DSA für diesen Signer generiert werden:

javakey -gk safetyfirst DSA 512

javakey erlaubt es, bestimmte juristische Personen als vertrauenswürdig einzustufen. Der Appletviewer gestattete in dem ehemaligen Sicherheitskonzept jedem aus dem Netz geladenen Applet in JAR-Dateien, die als vertrauenswürdig eingestuft und mit diesem Tool entsprechend signiert wurden, mit denselben Rechten auf dem lokalen Rechner zu laufen wie eine lokale Applikation. Dies hatte extrem weitreichende Konsequenzen, denn ein solches Applet ist nicht mehr Bestandteil des »Laufstalls«, in den das Java Sicherheitsmodell Applets normalerweise zwingt. Wenn Sie also eine Organisation als prinzipiell vertrauenswürdig einstufen wollten, mussten Sie sich schon sehr sicher sein. Es gab übrigens bis zu den 1.1.x-Versionen nur die Möglichkeit »vertrauenswürdig« oder »nicht vertrauenswürdig«. Eine differenziertere Abstufung war nicht möglich. Mittlerweile wurde eine solche weitergehende Differenzierung realisiert. Defaultwert ist »nicht vertrauenswürdig«.

Wenn Sie also Einträge in der Datenbank vornehmen, können Sie folgende Vertrauensstufen setzen:

javakey -cs safetyfirst  true
javakey -cs microsoft false
javakey -cs cia

Fall eins steht für »vertrauenswürdig«, die anderen beiden für »nicht vertrauenswürdig«. Die Einträge können später natürlich wieder verändert werden.

Klären wir nun, was Zertifikate sind. Mit den meisten Sicherheitsprogrammen sind Sie in der Lage, Zertifikate zu importieren, zu generieren, anzeigen und zu speichern. Ein Zertifikat ist eine digitale Unterschrift einer juristischen Person. Vereinfacht gesagt drückt ein Zertifikat nur aus, dass der öffentliche Schlüssel von einer anderen juristischen Person einen abweichenden Wert hat. javakey verwendet X.509-Zertifikate. Wenn Sie mit javakey ein Zertifikat generieren wollen, müssen Sie als Erstes eine Datei generieren, in die folgende Informationen gehören:

  • Informationen über den Unterzeichner
  • Informationen über die juristische Person selbst
  • Informationen über das Zertifikat selbst
  • Optional der Name des verwendeten Verschlüsselungsalgorithmus (falls Sie nicht DSA verwenden)
  • Der Name der Datei, die eine Kopie des Zertifikats enthält

Um ein Zertifikat zu generieren und eine Datei zu spezifizieren, verwenden Sie die Option -gc.

Beispiel: javakey -gc bembelmaniaCertDirFile

javakey wird ein Zertifikat generieren, indem es die Informationen verwendet, die in der angegebenen Datei abgelegt sind. Zusätzlich werden Informationen verwendet, die in der Datenbank vorhanden sind (öffentlicher und privater Schlüssel usw.).

Zum Anzeigen von Zertifikatinformationen verwenden Sie die Option -dc.

Beispiel: javakey -dc certfile.cer

Dies zeigt die Informationen über das Zertifikat an, die in der Datei certfile.cer abgelegt sind.

Zum Importieren von Zertifikaten verwenden Sie die Option -ic.

Beispiel: javakey -ic joe jcertfile.cer

Der Befehl importiert das Zertifikat in die Datei jcertfile.cer und ordnet es dem Username joe zu.

Zum Exportieren von Zertifikaten verwenden Sie die Option -ec.

Beispiel: javakey -ec jane 2 janecertfile.cer

Der Befehl exportiert das zweite Zertifikat der mit dem Username jane bezeichneten juristischen Person in die Datei janecertfile.cer. Die Nummer des Zertifikats muss dieselbe Nummer sein, die bei der Generierung oder dem Import zugewiesen wurde.

javakey kann JAR-Dateien auf jeden Fall mit DSA (Digital Signature Algorithm) signieren und verifizieren. In einigen Fällen funktioniert genauso der MD5/RSA-Algorithmus, was vom Typ der verwendeten Schlüssel des Signers und der Unterstützung durch den Provider abhängt.

Signieren einer JAR-Datei generiert für den angegebenen Signer eine digitale Unterschrift und schließt diese in die angegebene JAR-Datei ein. Dazu muss der Signer in der von javakey verwalteten Datenbank mit seinem Schlüsselpaar und einen X.509-Zertifikat vorhanden sein. Wie die Generierung eines Zertifikates basiert die Generierung einer digitalen Unterschrift auf den Anweisungen aus einer Datei, die das Profil eines Signers enthält. Wenn die JAR-Datei und die Anweisungsdatei generiert wurden, kann der javakey-Befehl zum signieren der JAR-Datei angewendet werden:

javakey -gs directivefile jarfile

directivefile ist der Name (und Pfad) der Anweisungsdatei, und jarfile ist der Name (und Pfad) der JAR-Datei.

Die Ausgabe dieses Befehls ist eine signierte JAR-Datei, deren Name von dem Wert in der Eigenschaft out.file spezifiziert wird, sofern dort ein Wert steht. Andernfalls wird der Name der signierten JAR-Datei identisch sein mit der Orginaldatei, aber mit der Erweiterung .sig.

Auf die konkrete Auflistung aller Optionen von javakey wollen wir verzichten - immerhin ist das Tool nur noch für abwärtskompatible Arbeit sinnvoll. In der Dokumentation von Sun finden Sie aber mehr dazu. Beachten Sie jedoch, dass Sie unter Umständen die Dokumentation eines 1.1.x-JDK laden müssen.

keytool und jarsigner

Wie bereits angedeutet, hat sich javakey nicht sonderlich bewährt und wurde deshalb durch einen Satz von Tools ausgetauscht. javakey dient indes immer noch als Basis für diese Tools. Viele Funktionalitäten und die Bedienung sind daran angelehnt oder gar identisch. Andere dagegen sind komplett neu.

Zum Schlüssel- und Zertifikat-Management dient nun keytool. Wie bei javakey wird eine Datenbank (keystore) mit privaten Schlüsseln und ihren zugehörigen X.509-Zertifikaten sowie den Zertifikaten von vertrauenswürdigen Entities verwaltet. Auch dieses Tool basiert auf dem DSA-Algorithmus mit der SHA-1-Signatur. Die Schlüsselgröße muss im Bereich zwischen 512 und 1024 Bits liegen, und muss ein Vielfaches von 64 sein. Die Defaultschlüsselgröße ist 1024 Bits.

Das jarsigner-Tool benutzt dieses Informationen, um eine digitale Signatur für eine JAR-datei zu generieren oder verifizieren. jarsigner verifiziert die digitale Signatur von einer JAR-Datei, indem das mitgeschickte Zertifikat dahingehend überprüft wird, ob der öffentliche Schlüssel vertrauenswürdig ist oder nicht (beispielsweise eine Übereinstimmung mit einem Eintrag im keystore). Das jarsigner-Tool unterstützt den DSA-Algorithmus und das RSA-Verfahren mit dem MD5-Algorithmus.

Um es noch einmal zu betonen: Die beiden Programme keytool und jarsigner ersetzen javakey zwar vollständig und bieten eine Fülle neuer Features. Die beiden Programme sind jedoch ausdrücklich nicht abwärtskompatibel zu dem Keystore- und Datenbankformat, das von javakey in dem JDK 1.1 verwendet wurde.

Wir werden Befehle und Optionen von keytool nur skizzieren. Mehr Informationen dazu finden Sie u.a. in der Dokumentation des JDK.

  • Allen Befehlen und Optionen geht ein Minuszeichen voran.
  • Die Optionen für die Befehle werden in jedem Befehl unterstützt.
  • Klammern werden unterstützt.
  • Klammern um eine Option bedeuten, dass der Defaultwert genutzt wird, wenn die Option in der Kommandozeile nicht spezifiziert wird.
  • Klammern um eine Option bedeuten ebenfalls, dass der Anwender Werte eingeben kann, wenn die Option in der Kommandozeile nicht spezifiziert wird.
  • Angaben in geschweiften Klammer bedeuten, dass der dort stehende Wert durch einen erlaubten Wert zu ersetzen ist. Beispiel:
    keytool -printcert {-file cert_file} {-v}
    Um ein Kommando einzugeben, muss cert_file mit dem aktuellen Dateinamen ersetzt werden, etwa so:
    keytool -printcert -file VScert.cer
  • Optionswerte müssen mit einem Leerzeichen getrennt werden.
  • Das Kommando -list ist die Defaulteinstellung und äquivalent zu dem Aufruf keytool. Wenn Sie keytool -list eingeben, erhalten Sie eine Auflistung der keytool-Befehle, der Optionen und der Syntax, auf die auch hier weiter verwiesen werden soll.

Die Befehle und Optionen von jarsigner skizzieren wir ebenfalls nur grob. Mehr Informationen dazu finden Sie u.a. in der Dokumentation des JDK.

  • Sie müssen mit dem Befehlsaufruf die Datei angeben, die Sie signieren oder verifizieren wollen. Wenn Sie jarsigner benutzen, um eine JAR-Datei zu signieren, wird die signierte JAR-Datei exakt identisch zu der Input-JAR-Datei sein, es sei denn, in dem META-INF-Directory sind zwei einander zugeordnete Dateien angegeben. Auch dazu finden Sie Informationen in der Dokumentation.
  • Auch für die jarsigner-Optionen gilt, dass alle Optionen mit einem Minuszeichen beginnen.
  • Die Optionen werden in den meisten Befehlen unterstützt.
  • Angaben in geschweiften Klammer bedeuten, dass der dort stehende Wert durch einen erlaubten Wert zu ersetzen ist.

Ein Beispiel soll das Signieren einer JAR-Datei demonstrieren. Die JAR-Datei heißt im Beispiel bundle.jar. Wir verwenden einen privaten Schlüssel mit dem Keystore-Aliasnamen (siehe dazu die Dokumentation) safety in dem Keystore mykeystore im daten-Directory. Das Keystore-Password soll mykeypass sein und das Passwort für den privaten Schlüssel abc. Mit diesen Voraussetzungen können Sie eine JAR-DAtei signieren und die signierte JAR-Datei sbundle.jar nennen:

jarsigner -keystore "\daten\mykeystore" -storepass mykeypass -keypass abc -signedjar 
sbundle.jar bundle.jar safety

Das Policytool

Das Policytool ist eine grafische Benutzerschnittstelle (neben dem Appletviewer das einzige Programm des JDK mit GUI), die den Anwender beim Spezifizieren, Generieren, Editieren, Exportieren oder Importieren von einer Sicherheitspolice unterstützt. Damit kann unter Java auf fremde Hosts zugegriffen werden, ohne das Java-Sicherheitsmodell zu verlassen. Das Tool selbst ist weitgehend selbsterklärend und wird von der Kommandozeile mit policytool aufgerufen.

A.1.4 Java IDL- und RMI-Tools

Diese Programme dienen zum Generieren von Applikationen, die über das Web oder andere Netzwerken interagieren. Das bedeutet, es geht um die Unterstützung von Remote-Prozessen. Dabei kann entweder auf IDL und CORBA oder das RMI-Konzept zurückgegriffen werden.

Im Wesentlichen geht es dabei um die Angabe einer gemeinsamen Schnittstelle für den Server und die Clients. Diese Schnittstelle wird vom Server implementiert, der sich bei einem Nameserver anmeldet. Von diesem können die Clients eine Referenz auf den Server erfragen, um ihn anschließend zu benutzen. Ziemlich einfach ist die Implementierung eines Clients: Der einzige Unterschied zu einem Client, der keine verteilten Objekte nutzt, ist das Holen einer Referenz auf den Server vom Nameserver.

  • Das unter dem JDK 1.2 neu eingeführte Programm tnameserv unterstützt den Zugriff auf die benannten Services4.
  • Neu in der Java-2-Plattform ist mit dem JDK 1.2 das Tool idltojava eingeführt worden. Dieses Tool generiert .java-Dateien, die ein OMG IDL-Interface mappen. Damit können in Java geschriebene Applikationen CORBA-Funktionalität nutzen. Dieses Tool war ursprünglich nicht direkt Bestandteil des JDK, sondern konnte von der Java IDL-Webseite geladen werden. Im JDK ist ein solches Tool nun enthalten. Es heißt zwar idlj, hat jedoch die gleiche Funktionalität - es generiert aus der IDL-Metasprache Java-Schablonen für CORBA.
  • Der Java RMI Stub Converter (rmic) generiert Stub-Dateien und Gerüststrukturen für so genannte Remote-Objekte (Remote Objects).
    Syntax:
  • rmic [ Optionen ] package-qualified-class-name(s)
  • Das generierte Remote-Objekt ist ein Objekt, das die Schnittstelle java.rmi.Remote enthält. Die Stub-Dateien und Gerüststrukturen werden von den Namen der kompilierten Klassen, die Remote-Object-Im-plementationen enthalten, abgeleitet. Die im rmic-Kommando angegebenen Klassen müssen Klassen sein, die erfolgreich mit dem Java-Compiler javac kompiliert wurden und sie müssen vollständig qualifizierte Angabe bzgl. der Packages enthalten.
  • Beispiel: Das Kommando
  • rmic hello.HelloImpl
  • generiert die Dateien HelloImpl_Skel.class und HelloImpl_Stub.class.
  • Das Tool rmiregistry (Java Remote Object Registry) ist dafür da, auf dem angegebenen Port eines Hosts eine so genannte Remote Object Registry zu generieren und dann zu starten. Wie auch rmic - der Java RMI Stub Compiler - dient rmiregistry zur programmiertechnischen Umsetzung des RMI-Konzepts für die verteilte Programmierung.
  • Das Tool rmid (Java RMI Activation System Daemon) ist in das RMI-Konzept integriert und startet den so genannten Activation System Daemon, mit dessen Hilfe Objekte in einer JVM registriert und aktiviert werden können. Das dahinter liegende Konzept wird Activation-Framework genannt und erlaubt es beispielsweise, eine GIF-Datei als solche zu erkennen und ein passendes Objekt zu deren Bearbeitung zur Verfügung zu stellen.
    Syntax:
    rmid [-port port] [-log dir]
  • Für den Bereich der verteilten Programmierung (RMI) benötigt Java das Konzept der so genannten Object Serialization, auf dem das Tool serialver (Serial Version Command) aufbaut. Es ermöglicht das Abspeichern der Inhalte eines Objekts in einen Stream. Hauptanwendung hierfür ist das Versenden von Objekten über das Netzwerk im Zusammenhang mit dem RMI. Das Serialization-API wird benutzt, um die Daten eines Objekts in einen Datenstrom zu packen und anschließend, an anderer Stelle, wieder auszupacken. Dies kann aber auch im Prinzip eine beliebige Datei sein. Ein Objekt kann in einem Stream zwischengespeichert und zu einem späteren Zeitpunkt daraus wieder aufgebaut werden. Die Lebensdauer eines Objekts kann also über die eigentliche Laufzeit eines Programms hinaus verlängert werden. Dazu muss ein Java-Objekt normalerweise nur die Schnittstelle Serializable implementieren. In der einfachsten Form hat die Schnittstelle nur die Aufgabe einer Kennzeichnung. Die Serialisierung selbst wird in diesem Fall vom Laufzeitsystem vorgenommen. Sollte dies dem Programmierer nicht ausreichen, besteht die Möglichkeit, die gesamte Serialisierung des Objekts manuell durchzuführen. Das Tool serialver gibt u.a. die serialVersionUID für eine oder mehrere Klassen so zurück, dass man sie in eine konkrete Klasse kopieren kann.

A.2 IDEs für Java

Grundsätzlich ist die Arbeit mit dem JDK ziemlich mühsam und unkomfortabel. Zwar wird das JDK kostenlos zur Verfügung gestellt und ein einfacher Texteditor genügt als Ergänzung (wir beschränken uns in dem Buch auch auf diese Konfiguration). In der Praxis wird man sich jedoch kaum damit zufrieden geben. Die Arbeit dauert einfach zu lange, ist zu fehleranfällig und vor allem muss man bei Standardvorgängen zu viele Dinge von Hand erledigen, die eine Entwicklungsumgebung mit wenigen Klicks auch kann.

Es gibt mittlerweile zahlreiche kommerzielle IDEs für Java, die von wenigen Euro bis hin zu vierstelligen Beträgen kosten. Das ist vom Produkt und dem Hersteller, vor allem aber der Version des jeweiligen Tools abhängig. Die meisten IDEs gibt es in einer Grundversion sowie darauf aufbauenden umfangreicheren Versionen. Die Grundversionen unterstützen meist keine weitergehenden Techniken wie Datenbankanbindungen, JavaBeans, Servlets oder Netzwerktechniken. Sie sind aber für die einfachere Erstellung von Oberflächen meist ausreichend. Insbesondere gibt es von vielen Profi-Tools oft eine kostenlose Light-Version, die als Basis für die Arbeit mit Java bedeutend komfortabler ist als die Arbeit mit dem JDK direkt und einem einfachen Texteditor. Wir wollen hier keine kommerziellen Tools vorstellen, sondern einige kostenlose - oder zumindest über einen gewissen Zeitraum frei einsetzbare.

A.2.1 JCreator für Windows

Ein sehr brauchbarer, kompakter, in C++ geschriebener, Freeware-Editor für Java mit einem recht intuitiv bedienbaren User-Interface ist der JCreator von Xinox Software (http://www.jcreator.com). Der Editor ist insbesondere bei schwachbrüstigen Rechnern eine sehr gute Wahl, denn er benötigt keinen sonderlich leistungsfähigen Computer.

Abbildung A.3:  Hier gibt es den JCreator

Die keine zwei MByte große Installationsdatei wird als ZIP-File bereitgestellt.

Abbildung A.4:  Der Download

Die Installation vom JCreator ist unkompliziert. Das ZIP-Archive muss nur extrahiert werden. Danach steht Ihnen ein Windows-Standard-Setup zur Verfügung, in dem Sie wie üblich Verzeichnisse und ähnliche Details auswählen können. Der JCreator liefert kein JDK oder eigene Java-Tools mit und auch keine virtuelle Maschine. Deshalb muss der JCreator wissen, wo sich die virtuelle Maschine und die JDK-Tools befinden. Die Installationsroutine sucht danach.

Abbildung A.5:  Gefundenes JDK-Verzeichnis

Sie können auch individuell ein JDK-Verzeichnis auswählen.

Abbildung A.6:  Auswahl eines JDK-Verzeichnisses

Das Programm kann dann nach der Installation ohne Neustart direkt aufgerufen werden.

JCreator bietet ein Projektmanagement mit Projekt-Templates, Klassenbrowser, Syntax-Highlighting, Wizards und einem frei konfigurierbarem User-Interface. Mit dem JCreator kann direkt Java-Quelltext kompiliert und ausgeführt werden. Generell kann der Zugriff auf sämtliche Tools eines zugrunde liegenden JDK in die IDE integriert werden. Auch die Verwendung von verschiedenen Compiler-Tools ist möglich. Ansonsten bietet der Editor u.a. Zeilennummerierung, praktisch unbegrenztes Undo/Redo, Drag&Drop, gleichzeitige Arbeit mit verschiedenen Dokumenten, Autoeinrückung bei neuen Zeilen, Wortkomplettierung, automatische Kontrolle von externen Dokumentveränderungen und Lesezeichen.

Abbildung A.7:  Die Arbeitsoberfläche des JCreators

Ein kleiner Nachteil des JCreators bezüglich des Komforts ist, dass es sich nicht um ein visuelles Tool handelt, also eine IDE, wo Programme in gewissen Teilen per Maus erstellt werden können. Im Wesentlichen sind das zwar nur Komponenten der Oberfläche (bei einfachen Ausführungen), aber den Komfort einer IDE à la Visual Basic ist bei der Erstellung einer Applikation oder eines Applets auch nicht zu verachten. Auch solche Tools gibt es kostenlos, sogar bei Sun selbst. Der Preis für deren Verwendung ist jedoch der immense Bedarf an Ressourcen und die meist recht große Installationsdatei.

A.2.2 Forte 2.0 for Java

Eine visuelle IDE für das JDK, die in einer Grundversion von Sun frei zur Verfügung gestellt wird, ist Forte 2.0 for Java. Es gibt Versionen für Linux, Solaris und Windows sowie eine universelle Version für alle Plattformen, wo eine passende virtuelle Maschine vorhanden ist. Das Programm ist in Java geschrieben und funktioniert mit dem JDK ab der Version 1.3, das zusätzlich auf dem Rechner vorhanden sein muss. Sie können die ca. 9 MByte große Installationsdatei (nur die IDE - ohne Java-Tools) in verschiedenen Versionen von den Sun-Servern unter der Adresse http://www.sun.com/forte laden.

Abbildung A.8:  Hier gibt es Forte

Die IDE gibt es in verschiedenen Versionen, wobei die so genannte Community Edition kostenlos ist, was sich natürlich dann auch im Leistungsumfang zeigt.

Abbildung A.9:  Auswahl der Version - die Community Editon ist kostenlos

Grundsätzlich müssen Sie sich aber vor einem Download registrieren lassen, auch für die kostenlose Community-Version.

Abbildung A.10:  Die Registrierung ist unumgänglich.

Wenn Sie sich registriert haben, können Sie eine Download-Quelle und die gewünschte Version auswählen.

Abbildung A.11:  Download-Quelle und Plattform-version

Wenn Sie die Version für alle Plattformen laden, wird eine Java-class-Datei übertragen.

Die Installation der Windows-Version des Programms ist unkompliziert, aber dennoch ein paar Erwähungen wert. Der Installationsvorgang ist Java-basierend, was sich auch optisch äußert.

Abbildung A.12:  Ein Java-Installa-tionsdialog

Wie schon angedeutet, muss für die Arbeit mit der Forte-IDE mindestens ein JDK 1.3 (genau genommen eine passende virtuelle Maschine, aber auch die entsprechenden JDK-Tools wie der Compiler, wenn man aus der IDE he-raus kompilieren möchte) zur Verfügung stehen. Der Installationsvorgang sucht selbstständig nach einem solchen JDK.

Abbildung A.13:  Gefundene JDKs ab einer JVM 1.3

Man kann aber auch - wenn mehrere JDKs ab der Version 1.3 installiert sind - selbst eine Version auswählen.

Abbildung A.14:  Auswahl eines JDKs

Abschließend können alle Dateien mit der Endung .java mit dem Programm verknüpft werden.

Abbildung A.15:  Verknüpfen der Dateierweiterung mit Forte

Das selbst in Java geschriebene Programm bietet eine visuelle Entwicklungsumgebung für Java mit diversen frei auf dem Bildschirm platzierbaren Fenstern. Von besonderer Bedeutung ist die Leiste mit Komponenten, mit der Sie per Mausklick AWT- und Swing-Elemente in einem grafischen Modus in ein Programm integrieren und mit passendem Eventhandling versehen können. Das wirkt sich natürlich auch in dem textbasierenden Modus aus, der synchron verwaltet wird und entsprechende Programmierung auf Quelltext-ebene erlaubt. Darüber hinaus finden Sie Debug-Unterstützung, Projektmanagement, einen Komponenteninspektor, Klassen- und Objektbrowser und zahlreiche weitere Möglichkeiten.

Abbildung A.16:  Der Arbeitsbereich von Forte

Zusammen mit dem Java-Editor wird auch ein JavaScript-Editor bereitgestellt.

Abbildung A.17:  Der JavaScript-Editor von Forte

Leider gilt für dieses Tool (wie für viele visuelle Entwicklungstools -besonders, wenn sie selbst in Java geschrieben sind), dass der Rechner nicht zu schwach sein sollte - vorsichtig ausgedrückt. Selbst bei einem Athlon 600 mit 256 Megabyte werden ungeduldige Naturen bei einigen Vorgängen nervös. Oder Kaffee holen. Da beißt die Maus keinen Faden ab. Das Tool ist kein Spielzeug und wer nicht ausreichend mit der Hardware ausgestattet ist, wird damit wenig Freude haben. Das gilt auch für das nachfolgend behandelte Tool JBuilder.

A.2.3 JBuilder

Von dem Hersteller des legendären Turbo Pascals Inprise (früher Borland) gibt es ein kommerzielles Java-Entwicklungstool namens JBuilder. Eine Lightversion (die Version JBuilder Foundation - die Installationsdatei im ZIP-Format ist für die Version 3.5 ca. 28 MByte groß) wird kostenlos zur Verfügung gestellt, wenn man sich bei Inprise registrieren lässt (http://www.borland.com).

Abbildung A.18:  Ein auf Java basierender Installationsassistent installiert den JBuilder.

Diese Registrierung ist notwendig, denn beim ersten Start des installierten Programms muss man den von Inprise zugesandten Schlüssel zur Freischaltung eingeben.

Abbildung A.19:  Ohne Registrierung startet der JBuilder nicht.

Dazu betätig man den Add...-Button und erhält ein passendes Eingabefenster.

Abbildung A.20:  Beim ersten Start werden diese Angaben notwendig.

Der JBuilder bietet in der Foundation-Version einen weitgehend mit Forte 2.0 vergleichbaren Leistungsumfang. Besonderes Highlight ist die Verknüpfung von grafischem und textbasierendem Programmiermodus. Änderungen im Textmodus wirken sich sofort - sofern davon berührt - im grafischen Modus und umgekehrt aus. Auch diverse Schablonen und Wizards machen das Leben leichter.

Abbildung A.21:  Die Arbeitsoberfläche des JBuilders.

Insbesondere gilt für beide visuellen Tools, dass die Programmierung des Eventhandlings damit zum Kinderspiel wird. Der Doppelklick auf eine Komponente generiert bereits eine vollständige Event-Schablone zum Standardereignis der Komponente und auch die Auswahl anderer Ereignisse lässt sich mithilfe eines Komponenten-Inspektors mühelos realisieren.

Abbildung A.22:  Einfachste Generierung von Event-methoden per Mausklick - auch Forte bietet einen solchen Inspektor

Marketing-Trick von Inprise ist die deselektierte Anzeige all der Leistungen, die in der Foundation-Version des JBuilders nicht funktionieren.

Abbildung A.23:  Appetitthappen auf die kommerziellen Versionen des JBuilders

A.2.4 Kawa

Abschließend soll noch das Entwicklungstool Kawa erwähnt werden. Eine längere Zeit war das Tool unter http://www.tek-tools.com zu laden. Es ist jedoch mittlerweile an die Firma Allaire übergegangen, von deren Seiten es nun zu laden ist (http://www.allaire.com/products/kawa).

Abbildung A.24:  Hier gibt es Kawa.

Vor einem Download muss man sich registrieren lassen (siehe Abbildung A.25).

Abbildung A.25:  Registrierung

Danach können Sie zwischen verschieden Versionen für den Download auswählen. Die Benutzerführung dahin ist ziemlich unglücklich, denn es wird nur indirekt deutlich, wie man die kostenlose Evaluation laden kann. Diese darf zudem nur 30 Tage verwendet werden. Sie müssen mindestens in der einfachsten Version eine 15 MByte große Installationsdatei laden, die dann nach der Installation mindestens 46 MByte Platz auf der Festplatte verbraten wird (die Enterprise-Version multipliziert die Eckdaten nochmals um einige Faktoren).

Die Installation von Kawa erfolgt inklusive der Extrahierung vollautomatisch. Beim ersten Start von Kawa müssen Sie unbedingt den Pfad zum JDK - insbesondere zum Compiler - setzen. Sie werden von Kawa darauf automatisch hingewiesen (siehe Abbildung A.26).

Abbildung A.26:  Hinweis, dass der Compiler spezifiziert werden muss

Abbildung A.27:  Der wichtigste Konfigurations-dialog von Kawa

Abbildung A.28:  Der Compiler wird angegeben.

Wenn dann das Programm installiert ist, steht Ihnen - auch schon in der Evaluation-Variante - eine übersichtliche und intuitiv zu bedienende IDE zur Verfügung. Dennoch - die gigantischen Installationsdateien und der immense Platzbedarf auf der Festplatte (im Vergleich zu der Leistung der Evaluation-Version und anderen, kostenlosen Java-Tools) sowie die zeitliche Einschränkung lässt einen Download von Kawa nur dann empfehlenswert erscheinen, wenn man danach die kommerzielle Variante wählt.

Abbildung A.29:  Die Kawa-Oberfläche

1

;-)

2

Sun gibt allerdings an, dass es kaum Gründe für die Verwendung dieser explizit abwärtskompatiblen Version gibt.

3

Beachten Sie die Inkonsistenz zwischen -Xdebug beim Interpreter und -debug beim Appletviewer.

4

Die meisten der hier erklären Tools werden im Kapitel über die erweiterten Java-Techniken bei der Behandlung von CORBA verwendet.


© Copyright Markt+Technik Verlag, ein Imprint der Pearson Education Deutschland GmbH
Elektronische Fassung des Titels: Java 2 Kompendium, ISBN: 3-8272-6039-6 Kapitel: Anhang A