Galileo Computing <openbook>
Galileo Computing - Programming the Net
Galileo Computing - Programming the Net


Java ist auch eine Insel von Christian Ullenboom
Programmieren für die Java 2-Plattform in der Version 1.4
Buch: Java ist auch eine Insel - Zum Katalog
gp Kapitel 26 Dienstprogramme für die Java-Umgebung
  gp 26.1 Die Werkzeuge im Überblick
  gp 26.2 Der Compiler javac
    gp 26.2.1 Der Java-Interpreter java
  gp 26.3 Das Archivformat Jar
    gp 26.3.1 Das Dienstprogramm Jar benutzen
    gp 26.3.2 Das Manifest
    gp 26.3.3 Jar-Archive für Applets und Applikation
  gp 26.4 Mit JavaDoc und Doclets dokumentieren
    gp 26.4.1 Mit JavaDoc Dokumentationen erstellen
    gp 26.4.2 Wie JavaDoc benutzt wird
    gp 26.4.3 Dokumentation erstellen
    gp 26.4.4 JavaDoc und Doclets
    gp 26.4.5 Doclets programmieren
    gp 26.4.6 Das Standard-Doclet
  gp 26.5 Dienstprogramme zur Signierung von Applets
    gp 26.5.1 keytool
    gp 26.5.2 jarsigner
    gp 26.5.3 policytool
  gp 26.6 Konverter von Java nach C
    gp 26.6.1 Toba
    gp 26.6.2 Arbeitsweise von Toba
    gp 26.6.3 Abstriche des Konverters
  gp 26.7 Konverter von Java Byte Code in ein Windows-Exe mit JET
  gp 26.8 Manteln von Javaklassen in ein Windows-Exe mit JToExe
  gp 26.9 Decompiler
    gp 26.9.1 Jad, ein schneller Decompiler
    gp 26.9.2 SourceAgain
    gp 26.9.3 Decompilieren erschweren
  gp 26.10 Obfuscate Programm RetroGuard
  gp 26.11 Source-Code Beautifier

Kapitel 26 Dienstprogramme für die Java-Umgebung

Erfolg sollte stets nur die Folge,
nie das Ziel des Handelns sein.
– Gustave Flaubert


Galileo Computing

26.1 Die Werkzeuge im Überblick  downtop

In diesem Kapitel werden unter anderem die wichtigsten Programme des Java Development Kit vorgestellt. Da die Programme kommandozeilenorientiert arbeiten, werden sie zusammen mit ihrer Aufrufsyntax vorgestellt. Es handelt sich dabei um folgende Tools:

gp  Der Java-Compiler »javac« zum Übersetzen von .java in .class-Dateien
gp  Der Java-Interpreter »java« zum Ausführen der Java-Applikationen
gp  Der Applet-Viewer »appletviewer« zum Ausführen von Java-Applets in einer HTML-Datei
gp  Debuggen eines Programms mit dem Debugger »jdb«
gp  Erzeugen von Dokumentationen mit »javadoc«
gp  Das Archivierungswerkzeug »jar«, um Dateien in einem Archiv zusammenzufassen
gp  Programme zum Einstellen der Sicherheitseigenschaften über »keytool«, »jarsigner« und »policytool«

Es werden die Optionen der Version 1.4 aufgezeigt.


Galileo Computing

26.2 Der Compiler javac  downtop

javac übersetzt den Quellcode einer Datei in Java-Bytecode. Jede Klasse, die innerhalb einer Datei definiert wurde, wird zu einer Klassendatei umgewandelt. Ergibt es sich, dass zu einer Klasse (nennen wir sie A) eine Abhängigkeit zu einer anderen Klasse (nennen wir sie B) besteht, wenn zum Beispiel A von B erbt, und liegt B nicht als Bytecode-Datei vor, dann wird B automatisch mitcompiliert. Der Compiler überwacht dabei automatisch die Abhängigkeiten zwischen den Quelldateien. Der allgemeine Aufruf ist:

javac [ Optionen ] Dateiname(n).java
Tabelle 26.1   Optionen des Compilers javac
Option Bedeutung
-classpath Path Eine Liste von Pfaden, durch die der Compiler die Klassendateien finden kann. Diese Option überschreibt die unter Umständen gesetzte Umgebungsvariable CLASSPATH und ergänzt sie nicht. Es können mehrere Verzeichnisse durch Semikolon (Windows) oder Doppelpunkt (Unix) getrennt werden.
-d Verzeichnis Gibt an, wo die übersetzten .class-Dateien gespeichert werden. Ohne Angabe werden die Dateien im Verzeichnis der Quelldateien abgelegt.
-deprecation Als deprecated, veraltetet, markierte Methoden (JavaDoc-Comment @deprecated) werden angezeigt.
-g Erzeugt Debug-Informationen. Die Option muss gesetzt sein, damit der Debugger verwendet werden kann.
-nowarn Deaktiviert die Ausgabe von Warnungen. Es werden noch Fehler (Errors) angezeigt.
-sourcepath Quellpfad Ähnlich wie -classpath, nur wird in sourcepath nach den Quelldateien gesucht.
-verbose Ausgabe von Meldungen über geladene Quell- und Klassendateien während der Übersetzung.


Galileo Computing

26.2.1 Der Java-Interpreter java  downtop

Der Java-Interpreter führt den Java-Bytecode in der Laufzeitumgebung aus. Dazu sucht der Interpreter in der als Parameter übergebenen Klassendatei nach der speziellen main()-Methode. Der allgemeine Aufruf ist:

java [ Optionen ] Klassenname [ 
Argumente ]

Ist die Klasse in einem Paket definiert, muss der Name der Klasse voll qualifiziert sein. Das heißt, wenn etwa die Klasse Haupt im Paket com.java-tutor, also im Unterverzeichnis com/java-tutor, angesiedelt ist, dann muss als Klassenname com.java-tutor.Haupt angegeben werden. Die benötigten Klassen müssen die Laufzeitumgebung finden könnten. Der Interpreter wertet jedoch wie der Compiler die Umgebungsvariable CLASSPATH aus und lässt sich alternativ den Klassenpfad durch die Option -classpath angeben.

Die Argumente sind optional und werden beim Aufruf an die Klasse übergeben.

Tabelle 26.2   Optionen des Interpreters java
Option Bedeutung
-client Wählt die Java HotSpot Client VM, Standard
-server Wählt die Java HotSpot Server VM
-cp, -classpath Path Eine Liste von Pfaden, wo der Compiler die Klassendateien finden kann. Diese Option überschreibt die unter Umständen gesetzte Umgebungsvariable CLASSPATH und ergänzt sie nicht. Es können mehrere Verzeichnisse durch Semikolon (Windows) oder Doppelpunkt (Unix) getrennt werden.
-D Ressource = Wert Setzt den Wert einer Ressource, etwa java -Djdbc.drivers=sun.jdbc.odbc.JdbcOdbcDriver XY
-help oder -? Listet alle vorhandenen Optionen auf
-jar Startet Klasse aus dem Jar-Archiv, falls sie in der Manifest-Datei genannt ist. Die Haupt-Klasse lässt sich aber immer noch angeben.

-verbose

Informationen über die Laufzeitumgebung -verbose:class gibt Information über geladene Klassen -verbose:gc informiert über GC -verbose:jni informiert über native Aufrufe
-version Zeigt die aktuelle Version an
-X Zeigt nicht standardisierte Optionen an
-Xdebug Startet mit Debugger
-Xincgc Schaltet die inkrementelle GC ein
-Xms x Anfangsgröße des Speicherbereichs für die Allokation von Objekten (x MB), voreingestellt sind 2 MB

-Xmx x

Maximal verfügbarer Speicherbereichs für die Allokation von Objekten. Voreingestellt sind 64 MB. x beschreibt als einfache Zahl die Bytes oder Kilobytes mit einem angefügtem k oder Megabyte (angefügtes m).

-Xnoclassgc

Schaltet die GC für geladene aber nicht mehr benötigte Klassen aus

-Xprof

Der Interpreter schreibt Profiling-Informationen in der Datei java.prof

-Xrs

Reduziert intern die Verwendung von Unix-Signalen durch die Laufzeitumgebung. Das ergibt gegebenenfalls eine schlechtere Performance aber bessere Kompatibilität mit div. Unix/Solaris-Versionen.


Galileo Computing

26.3 Das Archivformat Jar  downtop

Sun Microsystems hat in der Version 1.1 ein Archivformat eingeführt, welches durch ein Dienstprogramm Jar beim JDK unterstützt wird. Verbinden wir Java und Archiv, so ergibt sich schnell Suns Wortschöpfung JAR (Java-Archive). Es ist selbst in Java implementiert und daher sehr portabel. Zusätzlich zum Dienstprogramm gibt es auch eine API im Paket java.util.jar. Unter 1.2 hat das Jar-Dateiformat ein paar Erweiterungen erfahren. Wie für ein Archivformat üblich, werden bei Jar mehrere Dateien zusammengepackt. »Gepackt« heißt aber nicht zwingend, dass die Dateien auch komprimiert werden. Jar-Dateien werden oft nicht komprimiert, sondern bündeln nur einfach die einzelnen Dateien. Ein Auspackprogramm wie Winzip kann jedoch auch Jar-Archive auspacken. Hier bleibt zu überlegen, ob ein Programm wie Winzip bei .jar geöffnet werden soll, oder ob das Standardverhalten bei installiertem Jre beibehalten wird. Unter Windows ist mit der Dateiendung Jar das Programm Jre verbunden, welches die Hauptklasse des Archivs startet.

Dass ein Archiv gegenüber einzelnen Dateien Vorteile bringt, sehen wir etwa bei kleinen Applets mit zusätzlichen Ressourcen. Erinnern wir uns, dass der Applet-Klassenlader für jede zu übertragende Datei eine neue Verbindung aufbaut. Der Browser muss anstatt vieler kleiner Server-Verbindungen für jede einzelne Klassendatei und jede Ressource bei einem Archiv nur eine HTTP-Verbindung aufbauen. Auch wenn das Archiv etwas größer ist, ist die Zeit für die Übertragung des Archivs günstiger, als die vielen kleinen Dateien, da jeder Verbindungsaufbau überproportional viel Zeit kostet. Da sich das Archiv darüber hinaus komprimieren lässt, sparen wir noch mehr Übertragungszeit und Bandbreite. Wir dürfen jedoch nicht vergessen, dass ein Archiv mitunter auch Nachteile mit sich bringen kann. Dann nämlich, wenn wir nur wenige Klassen des Archivs brauchen. Normalerweise lädt der Applet-Klassenlader die Klassen nur dann, wenn sie gebraucht werden. In einem Archiv sind aber alle Klassen enthalten, die während der gesamten Sitzung verwendet werden.

Microsoft vertraut bei seinem ActiveX-Controls vollständig auf Zertifikate. Es wird angenommen, dass kein Bösewicht ein Control anbietet, da dieser sich ja vorher ein Zertifikat geholt haben müsste, über das der Übeltäter verfolgt werden könnte. Haha! Leider ist in dieser Kette ein Denkfehler, denn Zertifikate kann sich jeder ausstellen lassen, auch unter dem Namen Micky Mouse .

Mit Bedacht angewendet, ist das Konzept jedoch gut zu verwenden. Sun hat daher das gleiche Konzept bei Jar-Archiven eingeführt. Sie lassen sich durch eine Signatur schützen. Eine Laufzeitumgebung kann nun den Java-Programmen anhand der Signatur extra Rechte einräumen, die ein normales Programm sonst nicht hätte. Dies ist bei Programmen aus dem Intranet interessant.

Einige Eigenschaften sind beim Jar-Archiv ab der Version 1.2 hinzugekommen. So etwa, dass Hersteller Informationen über Version und Kennung hinzufügen können. Ebenso eine Versionskontrolle, dass nur Klassen eines Archivs verwendet werden, um innerhalb der gleichen Version zu bleiben. Ferner ein Archivformat, sodass Pakete zur Core-Plattform API hinzugenommen werden können. Ein Beispiel ist etwa die 3D- und Java-Mail API. Eigene Pakete sehen also so aus, als gehörten sie zum Standard.


Galileo Computing

26.3.1 Das Dienstprogramm Jar benutzen  downtop

Jar besitzt verschiedene Optionen, um Archive zu erzeugen, sie auszupacken und anzuschauen. Wenn wir Jar-Archive konstruiert haben, werden wir uns auch damit beschäftigen, wie sie aus Applets genutzt werden können. Das allgemeine Format für Jar ist:

jar Optionen Jar-Datei [Eingabedatei(en)]

Jar-Dateien anlegen

Die notwendige Option ist c (für engl. create) für das Anlegen eines neuen Archivs. Da wir häufig die Ausgabe (das neue Archiv) in einer Datei haben wollen, geben wir zusätzlich noch f (für engl. file) an. Somit können wir schon unser erstes Archiv erstellen. Nehmen wir dazu an, es gibt ein Verzeichnis images für Bilder und die Klasse Slider.class. Dann packt folgende Zeile die Klasse und alle Bilder in das Archiv Slider.jar:

$ jar cvf Slider.jar Slider.class 
images

Während des Komprimierens geht Jar alle angegebenen Verzeichnisse und Unterverzeichnisse durch und gibt, da zusätzlich zu cf der Schalter v gesetzt ist, auf dem Bildschirm die Dateien mit einem Kompressionsfaktor an.

adding: Slider.class (in=2790) 
(out=1506) (deflated 46%)
adding: images/ (in=0) (out=0) (stored 0%)
adding: images/darkwing.gif (in=1065) (out=801) (deflated 24%)
adding: images/volti.gif (in=173) (out=154) (deflated 10%)
adding: images/superschurke.gif (in=1076)(out=926)(deflated 13%)
adding: images/aqua.gif (in=884) (out=568) (deflated 35%)

Anstatt der Dateinamen können wir auch * oder andere Wildcards angeben. Diese Expansionsfähigkeit ist sowieso Aufgabe der Shell.

Möchten wir die Dateien nicht komprimiert haben, so sollten wir den Schalter 0 angeben.

Jar behält bei den zusammengefassten Dateien die Verzeichnisstruktur. Wir sehen in der Ausgabe, dass für images ein eigenes Verzeichnis erstellt und die Bilder dort hinein kopiert werden. Seit den JDK 1.2 bildet der Schalter -C (genau wie -C beim Kompressionsprogramm Gzip) diese hierarchische Struktur flach ohne Verzeichnisstruktur ab. Wenn wir mehrere Verzeichnisse zusammenpacken lässt sich für jedes Verzeichnis bestimmen, ob die Struktur erhalten bleiben soll oder nicht. Nehmen wir zu unserem Sliders-Archiv noch ein weiteres Verzeichnis mit Sound-Dateien hinzu und beobachten die Ausgabe bei

$ jar cfv0 Slider.jar Slider.class 
images -C sounds

Zwei Sachen sind neu. Zum einen komprimieren wir nicht mehr (Schalter 0 ist gesetzt) und wir haben mit -C erreicht, dass Jar in das sound-Verzeichnis geht und dort alle Sound-Dateien in das Basisverzeichnis setzt.

Einer angelegten Archiv-Datei lassen sich später mit u (für engl. update) noch Dateien hinzufügen. Nehmen wir an, es kommt noch eine Bild-Datei hinzu, so schreiben wir:

$ jar vuf Slider.jar images/buchsbaum.gif

Jar-Dateien betrachten

Um die zusammengepackten Dateien anzuzeigen, nutzen wir die Option tf.

$ jar tf Slider.jar
META-INF/MANIFEST.MF
Slider.class
images/volti.gif

Zusätzlich zu unseren Dateien sehen wir noch eine von Jar eigenständig hinzugefügte Manifest-Datei, die wir etwas später besprechen wollen.

Fehlt die Endung oder wird ein falscher Dateiname angegeben, so folgt eine etwas ungewöhnliche Fehlermeldung: java.io.FileNotFoundException: Dateiname und dann ein Stacktrace. Dies wirkt etwas unprofessionell.

Zum Anzeigen der Archive muss auf jeden Fall der Schalter t (für engl. Table of contents) benutzt werden. Wir geben f nur deshalb an, weil wir den Dateinamen auf der Kommandozeile eintragen und nicht von der Standardeingabe etwa über eine Pipe lesen. Zusätzlich dazu gibt uns der Schalter v (für engl. verbose) noch den Zeitpunkt der letzten Änderung und die Dateigröße aus.

291 Fri Dec 17 14:51:08 GMT 1999 
META-INF/MANIFEST.MF
2790 Thu Dec 16 14:54:06 GMT 1999 Slider.class
173 Mon Oct 14 00:38:00 GMT 1996 images/volti.gif

Dateien aus dem Archiv extrahieren

Der wichtigste Schalter beim Entpacken ist x (für engl. eXtract). Zusätzlich gilt für den Schalter f (file) das Gleiche wie beim Anzeigen: ohne den Schalter wird die Archivdatei in der Standardeingabe erwartet. Als Parameter ist zusätzlich das Archiv erforderlich. Sind optional Dateien oder Verzeichnisse angegeben, werden nur diese ausgepackt. Verzeichnisse werden automatisch erzeugt. Hier ist Vorsicht geboten, denn Jar überschreibt alle Dateien, die schon mit dem gleichen Namen auf dem Datenträger existieren. Das Archiv bleibt nach dem Auspacken erhalten. Wir wollen einmal nur die Grafiken aus unserem Archiv Slider.jar auspacken. Dazu schreiben wir:

$ jar vxf Slider.jar images\*
extracted: images\volti.gif

Die Option v haben wir eingesetzt, damit wir sehen, was genau entpackt wird. Sonst erfolgt keine Ausgabe auf der Konsole.


Galileo Computing

26.3.2 Das Manifest  downtop

Ohne das die Ausgabe es zeigt, fügt Jar beim Erzeugen eines Archivs automatisch eine Manifest-Datei mit dem Namen META-INF/MANIFEST.MF ein. Ein Manifest enthält für ein Archiv wichtige Zusatzinformationen, wie die Signatur, die für jede Datei aufgeführt ist. Schauen wir uns einmal die Manifest-Datei an, die sich für

$ jar cfv Slider.jar Slider.class 
images/volti.gif

ergibt. Die Einträge im Manifest erinnern an eine Property-Datei, denn auch hier gibt es immer Schlüssel und Werte, die durch einen Doppelpunkt getrennt sind. Da sich das Manifest zwischen 1.1 und 1.2 geändert hat, listen wir einmal beide Dateien auf. Für das JDK 1.1 sieht das Manifest dann wie folgt aus:

Manifest-Version: 1.0

Name: Slider.class
Digest-Algorithms: SHA MD5
SHA-Digest: /RD8BF1mwd3bYXcaYYkqLjCkYdw=
MD5-Digest: WcnCNJbo08PH/ATqMHqZDw==

Name: images/volti.gif
Digest-Algorithms: SHA MD5
SHA-Digest: 9zeehlViDy0fpfvOKkPECiMYvH0=
MD5-Digest: qv913KlZFi5tdPr2BjatIg==

Galileo Computing

26.3.3 Jar-Archive für Applets und Applikation  downtop

Wir haben gesehen, dass Jar-Archive für Applets in der Regel ein Vorteil sind, da gleich alle Dateien zusammen übertragen werden und der Klassenlader nicht immer Netzwerkverbindungen aufbauen muss. Dass die Dateien zusammen in einem Archiv sind, hat für Entwickler den Vorteil, dass sie dem Kunden nur eine einzige Datei ausliefern müssen und nicht ein ganzes Bündel von Klassen- und Ressourcen-Dateien. Zudem sind Bibliotheken eleganter getrennt. Unter Windows ist mit der Endung jar gleich die JRE (Java Runtime Evironment) verbunden, sodass Programme direkt gestartet werden können. Ein schöner Vorteil, denn vorher war das Ausführen nach einem Doppelklick schon etwas umständlicher.

Applikationen in Jar-Archiven

Bei Applikationen müssen wir zwischen Jar-Archiven für die Versionen 1.1 und 1.2 unterscheiden. Unter Java 1.1 müssen wir Java Runtime Environment mit dem Schalter -cp nutzen. Als Parameter ist zusätzlich zum Archivnamen auch der Name der Hauptdatei mit der statischen main()-Methode anzugeben.

$ jre -cp JarDatei.jar MainKlasse 
   // JDK 1.1

Ab Java 1.2 lässt sich der normale Interpreter java mit der Option -jar verwenden. (Dieser wurde erst ab 1.2 eingeführt.)

$ java -jar JarDatei.jar       
      // >= JDK 1.2

Wenn wir uns unter 1.1 befinden haben wir bei einem fremden Programm das Problem, dass wir nicht unbedingt wissen, wie die Main-Klasse heißt. Das ist für den Benutzer auch nicht nötig und erschwert das Benutzen des Jar-Archive. Doch irgendwo muss auch unter 1.2 die Main-Klasse stecken. Damit der Interpreter weiss, wo er seine Arbeit beginnen kann, schaut er ins Manifest und sucht nach dem Schlüssel Main-Class:

Main-Class: Klassenname_vom_main

Dies ist sehr elegant für den Benutzer, denn nun ist der Hersteller für den richtigen Einstiegspunkt verantwortlich. Aber dann haben wir ja das Problem!

Damit dem Jar-Archiv die Main-Klasse mitgeteilt werden kann, lässt sich das m-Flag (für engl. merge) beim Dienstprogramm Jar nutzen, um Einträge zum Manifest hinzuzufügen. Bevor ein Archiv erzeugt wird, erstellen wir eine beliebige Textdatei, die wir hier einmal MainfestMain.txt nennen wollen, mit dem Eintrag Main-Class. Wenn unser Slider-Programm etwa die Hauptklasse Main.class besitzt, schreiben wir

Main-Class: Main

Nun lässt sich die Datei MainfestMain.txt mit der Manifest-Datei zusammenbinden und anschließend benutzen:

$ jar cmf MainfestMain.txt Slider.jar 
Main.class
$ java -jar Slider.jar
$ java -jar Slider.jar Main

Applets in Jar-Archiven

Ebenso wie eine normale Klasse in der HTML-Datei innerhalb eines APPLET-Tags gesetzt wird, erscheint zusätzlich auch die Jar-Datei:

<applet
code=Main.class archive="Slider.jar"
width=320 height=200>
</applet>

Wie bei Applets erwarten wir hier das Archiv zusammen mit der Klasse und der HTML-Datei in einem Verzeichnis. Ist etwa das Jar-Archiv in einem speziellen Unterverzeichnis applets, so schreiben wir statt dessen:

<applet
code=Main.class archive="applets/Slider.jar"
width=320 height=200>
</applet>

Galileo Computing

26.4 Mit JavaDoc und Doclets dokumentieren  downtop

Dokumentation von Softwaresystemen ist ein wichtiger, aber oft vernachlässigter Teil der Softwareentwicklung. Im Entwicklungsprozess müssen die Entwickler Zeit in Beschreibungen der einzelnen Komponenten stecken, besonders dann, wenn weitere Entwickler diese Komponenten wieder verwerten. Diese Wiederverwertung wird besonders bei der objektorientierten Programmierung angestrebt. Deshalb müssen die Schnittstellen sorgfältig beschrieben werden. Wichtige Beschreibungen sind die Art und die Anzahl der Parameter, die Wirkung der Funktionen und das Laufzeitverhalten. Da das Erstellen einer externen Dokumentation – also eine Beschreibung außerhalb der Quellcodedatei – fehlerträchtig und deshalb nicht gerade motivierend für die Beschreibung ist, werden spezielle Anweisungen in den Java-Quelltext eingeführt. Ein spezielles Programm generiert aus den Formatierungsanweisungen eine Textdatei mit den gewünschten Informationen .


Galileo Computing

26.4.1 Mit JavaDoc Dokumentationen erstellen  downtop

JavaDoc geht durch den Quelltext und parst die Deklarationen und zieht die Dokumentation heraus. Daraus generiert das Tool eine Beschreibung, die in der Regel als HTML-Seite zu uns kommt. Die Dokumentation beschreibt die Klassen (auch innere), die Vererbung, die Methoden und Felder, Interfaces und Konstruktoren.

Aus den Beschreibungen im Java-Quelltext werden folgende Informationen zusammengetragen:

gp  Kopf
gp  Diagramm der Klassenhierarchie
gp  Klassenbeschreibung
gp  Index der Public-Variablen
gp  Index der Public-Methoden
gp  Index der Konstruktoren
gp  Beschreibung der Public-Variablen
gp  Beschreibung der Public-Konstruktoren
gp  Beschreibung der Public-Methoden

Galileo Computing

26.4.2 Wie JavaDoc benutzt wird  downtop

In einer besonders ausgezeichneten Kommentarumgebung werden die beschreibenden Anweisungen Dokumentationskommentare (»Doc Comments«) eingesetzt. Die Kommentarumgebung ähnelt dem Blockkommentar.

Beispiel Ein Dokumentationskommentar

/**
* Socken sind spezielle Kleidungsstücke.
*/
public class Socke extends Kleidung
{
}

Da ein Dokumentationskommentar mit /** beginnt, ist es für den Compiler ein normaler Block-Kommentar. Die Kommentare werden oft optisch aufgewertet, in dem am Anfang ein Sternchen steht. Dieses wird von JavaDoc ignoriert.

Hinweis Die Dokumentationskommentare sind so aufbaut, dass der erste Satz in der Auflistung der Methoden und Attribute erscheint und der Rest in der Detail-Ansicht.

/**
* Das ist ein kurzer Satz.
* Das ist die ausführliche Beschreibung.
* Die Ausführliche Beschreibung erscheint
* später im Abschnitt "Method Detail".
* Der kurze Satz erscheint im Abschnitt "Method Summary".
*/
public void foo() { }

Dokumentationskommentare

Tabelle 26.3   Die wichtigsten Dokumentationskommentare im Überblick
Kommentar Beschreibung
@see Klassenname Verweis auf eine andere Klasse
@see Klassenname oder Methodenname Verweis auf eine andere Methode
@see Ausgeschriebener Klassenname Verweis auf voll qualifizierte Klasse
@see Ausgeschriebener Klassenname oder Methodenname Verweis auf voll qualifizierte Methode
@version Versionstext Version
@author Autor Schöpfer
@return Rückgabetext Rückgabewert
@param Parametername oder Parametertext Beschreibung der Paramter
@exception Exception-Klassenname oder Exceptiontext Ausnahmen, die ausgelöst werden können
@throws Exception-Klassenname oder
Exceptiontext
Synonym zu oben
{@link Verweis } Einen eingebauten Verweis im Text Parameter sind wie bei @see.

Beispiele Eine externe Zusatzquelle angeben:
@see <a href="spec.html#section">Java 
Spec</a>.

Verweis auf eine Funktion, die mit der beschriebenen Funktion verwandt ist:

/**
* @see String#equals(Object) equals */

Dokumentiere eine Variable. Gebe einen Verweis auf die Methode an:

/**
* The X-coordinate of the component.
*
* @see #getLocation()
*/
int x = 1263732;

Eine veraltete Methode, die auf eine Alternative zeigt:

/**
* @deprecated As of JDK 1.1,
* replaced by {@link #setBounds(int,int,int,int)}
*/

HTML-Tags in Dokumentationskommentaren

In den Kommentaren können HTML-Tags verwendet werden – beispielsweise <B>..</B> und <I>..</I> –, um Textattribute zu setzen. Sie werden direkt in die Dokumentation übernommen, müssen also korrekt geschachtelt sein, damit die Ausgabe nicht falsch dargestellt wird. Die Überschriften-Tags <H1>..</H1> und <H2>..</H2> sollten jedoch nicht verwendet werden. JavaDoc verwendet sie zur Gliederung der Ausgabe und weist ihnen Formatvorlagen zu.


Galileo Computing

26.4.3 Dokumentation erstellen  downtop

Um eine Dokumentation zu erzeugen, wird dem Konsolen-Programm javadoc als Parameter ein Dateinamen der zu kommentierenden Klasse übergeben; aus kompilierten Dateien können natürlich keine Beschreibungsdateien erstellt werden.

Beispiel Erstelle aus der Socken- und Kleidung-Klasse eine Dokumentation

Listing 26.1   Kleidung.java
/**
* Kleidung bildet die Oberklasse für alle Kleidungs-Objekte.
*/

import java.io.*;

public abstract class Kleidung implements Serializable
{
/**
* Jede Kleidung hat eine Farbe.
*/
protected String farbe;

/**
* Erzeugt neues Kleidungs-Objekt.
*/
protected Kleidung()
{
}

/**
* Erzeugt neues KleidungsObjekt,
* welches mit einer Farbe initialisiert wird.
*/
protected Kleidung( String farbe )
{
this.farbe = farbe;
}

/**
* Jede Kleidung hat einen Namen.
* Wird von Unterklassen überschrieben.
*/
abstract String getName();
}
Listing 26.2   Socke.java
/**
* Socken sind spezielle Kleidungsstücke.
*/

import java.io.*;

public class Socke extends Kleidung implements Serializable
{
/**
* Erzeugt ein neues Socken-Objekt mit der Farbe Schwarz.
*/
Socke()
{
super( "schwarz" );
}

/**
* Überschrieben von der Oberklasse.
*/
public String getName()
{
return "Socke";
}
}

Wir starten javadoc im Verzeichnis, in dem auch die Klassen liegen, und bekommen eine Reihe von HTML-Dokumenten.

Möchten wir Dokumentation für das gesamte Verzeichnis erstellen, so geben wir alle Dateien mit der Endung .java an:

javadoc *.java

Generierte Dateien

Für jede öffentliche Klasse erstellt JavaDoc eine HMTL-Datei. Sind Klassen nicht öffentlich, muss ein Schalter angegeben werden. Die HTML-Dateien werden zusätzlich mit Querverweisen zu den anderen dokumentieren Klassen versehen. Daneben erstellt JavaDoc weitere Dateien:

gp  index-all.html
Die Übersicht aller Klassen, Schnittstellen, Ausnahmen, Methoden, Felder in einem Index.
gp  overview-tree.html
Zeigt in einer Baumstruktur die Klassen an, damit die Vererbung deutlich sichtbar ist.
gp  allclasses-frame.html
Anzeige aller dokumentierter Klasse in allen Unterpaketen.
gp  deprecated-list.html
Liste der veralteten Methoden und Klassen.
gp  serialized-form.html
Listet alle Klassen auf, die Serializable implementieren. Jedes Attribut erscheint mit einer Beschreibung in einem Absatz.
gp  help-doc.html
Eine Kurzbeschreibung von JavaDoc.
gp  index.html
JavaDoc erzeugt eine Ansicht mit Frames. Das ist die Hauptdatei, die die rechte und linke Seite referenziert. Die linke Seite ist die Datei allclasses-frame.html. Rechts im Frame wird bei fehlender Paketbeschreibung die erste Klasse angezeigt.
gp  stylesheet.css
Formatvorlage für HTML-Dateien, in der sich Farben und Zeichensätze einstellen lassen, die dann alle HTML-Dateien nutzen.
gp  packages.html
Eine veraltete Datei. Sie verweist auf die neuen Dateien.

Schalter für das Programm javadoc

Über die umfangreichen Parameter informiert eine HTML-Datei, die beim Java-SDK beigelegt ist.

Beispiel Für die Java API-Dokumentation haben die Entwickler eine ganze Reihe von Schaltern eingesetzt. Umgebungsvariablen machen den Aufruf besser deutlich.

WINDOWTITLE = 'Java Platform 1.2 
Final API Specification'
DOCTITLE = 'Java<sup><font size="-2">TM</font></sup> Platform 1.2 Final\
API Specification'
HEADER = '<b>Java Platform 1.2</b><br><font size="-1">Final</font>'
BOTTOM = '<font size="-1"><a href="http://java.sun.com/cgi-bin/\
bugreport.cgi">Submit a bug or feature</a><br><br>Java is a\
trademark or registered trademark of Sun Microsystems, Inc. in the\
US and other countries.<br>Copyright 1993-1998 Sun Microsystems,\
Inc. 901 San Antonio Road,<br>Palo Alto, California, 94303, U.S.A.\
All Rights Reserved.</font>'
GROUPCORE = '"Core Packages" "java.*:com.sun.java.*:org.omg.*"
GROUPEXT = '"Extension Packages" "javax.*"'

javadoc -sourcepath /jdk/src/share/classes \
-d /jdk/build/api \
-use \
-splitIndex \
-windowtitle $(WINDOWTITLE) \
-doctitle $(DOCTITLE) \
-header $(HEADER) \
-bottom $(BOTTOM) \
-group $(GROUPCORE) \
-group $(GROUPEXT) \
-overview overview-core.html \
-J-Xmx180m \
java.lang java.lang.reflect \
java.util java.io java.net \
java.applet \

Galileo Computing

26.4.4 JavaDoc und Doclets  downtop

Die Ausgabe von JavaDoc kann den eigenen Bedürfnissen angepasst werden, in dem Doclets eingesetzt werden. Ein Doclet ist ein Java-Programm, das auf der Doclet-API aufbaut und die Ausgabedatei schreibt. Das Programm liest dabei wie das bekannte JavaDoc-Tool die Quelldateien ein und erzeugt daraus ein beliebiges Ausgabeformat. Dieses Format kann selbst gewählt und implementiert werden. Wer also neben dem von JavaSoft beigefügten Standard-Doclet für HTML-Dateien Framemaker-Dateien (MIF) oder RTF-Dateien erzeugen möchte, muss nur ein eigenes Doclet programmieren. Daneben dient ein Doclet aber nicht nur der Schnittstellendokumentation. So kann ein Doclet auch dokumentieren, ob es zu jeder Methode auch eine Dokumentation gibt, oder ob jeder Parameter und Rückgabewert beschrieben ist.


Galileo Computing

26.4.5 Doclets programmieren  downtop

Die Doclets sind normale Java-Programme, die eine spezielle Doclet API benutzen, um an die Informationen der Quelltexte zu kommen, denn das Parsen wird uns schon abgenommen. Die Funktionen dazu sitzen in dem Paket sun.tools.javadoc. Das Paket ist also kein Teil der Core-API. Somit hängen die Klassen auch nicht im src-Baum. Werden die JDK-Dokumentationen installiert, so liegen die Quelldateien für das Standard-Doclet im Verzeichnis docs/ tooldocs/javadoc/source.

Doclets besitzen weder eine init()- noch eine main()-Methode zum Starten des Parsevorgangs. Hier ist der Beginn durch die Methode start() gekennzeichnet. Die Signatur ist

public static boolean start( Root 
root )

Eine Klasse Root wird als Parameter übergeben. Sie dient als Einstiegspunkt und verwaltet Informationen über die zu überprüfenden Pakete, Klassen, Interfaces und Parameter in der Kommandozeile. Um einen Einstieg zu bekommen, schauen wir uns ein kleines Doclet an. Es ist in einer Klasse ListDoclet eingebunden. In einigen Implementierungen ist die abstrakte Klasse Doclet erweitert:

import com.sun.javadoc.*;

public class ListDoclet
{
public static boolean start( RootDoc root )
{
ClassDoc[] classes = root.classes();

for ( int i = 0; i < classes.length; i++ )
System.out.println( classes[i] );

return true;
}
}

Die Klasse Root hat eine Methode classes(), die eine Liste zu parsender Klassen zurückgibt. classes() liefert dazu ein ClassDoc-Objekt und jedes von ihnen repräsentiert eine Klasse. In einer Schleife geben wir nun alle Klassen aus. Die toString()-Methode ist auf ClassDoc-Objekte so implementiert, dass sie den Namen der Klasse ausgibt.

Da Doclets ganz normale Java-Programme sind, müssen sie zunächst kompiliert werden. Da sich sun.tools.javadoc jedoch nicht im vordefinierten Jar-Archiv befindet (»jre/lib/rt.jar«), sondern in einem speziellen Tool-Archiv (unter Windows »lib/tools.jar«), ist dies beim Übersetzen mit anzugeben.

javac -classpath C:\jdk1.2\lib\tools.jar 
ListDoclet.java

Nun kann es dem Programm JavaDoc mit der Option -doclet übergeben werden:

$ javadoc -doclet ListDoclet MyClass.java

Anschließend liefert unser Doclet die gewünschte Ausgabe, den String MyClass. Ist die Option -doclet nicht festgesetzt, so verwendet JavaDoc das Standard-Doclet, welches die API-Dokumentation im HTML-Format erzeugt. Das Programm auf die eigene Klasse angesetzt, liefert als Ausgabe

Constructing Javadoc information...
javadoc: warning – Cannot find class type RootDoc
ListDoclet
1 warnings

Galileo Computing

26.4.6 Das Standard-Doclet  downtop

Um eine HTML-Dokumentation mit Verweisen und Frames zu erzeugen, muss dass Doclet natürlich wesentlich umfangreicher sein. Wir wollen uns daher mit dem Standard-Doclet beschäftigen. Über dieses kommen wir dann leichter zu unserer eigenen Beschreibung der APIs. Wie schon beschrieben, wird das Standard-Doclet immer dann benutzt, wenn die Option -doclet ohne Parameter benutzt wird. Intern sind also

$ javadoc MyClass.java

und

$ javadoc -doclet \
com.sun.tools.doclets.standard.Standard MyClass.java

gleich.

An diesem Aufruf sehen wir schon, dass die Klasse, die die start(Root)-Methode besitzt, Standard heißt. Neben dieser Standard-Klasse gibt es noch weitere Klassen, die für das Standard-Doclet programmiert wurden. Wir können uns diese auch für unsere eigenen Doclets zu nutze machen. Nachfolgend eine Tabelle, in der die Klassen aufgelistet sind, die für die Erstellung der HTML-Dokumentation wichtig sind:

gp  Standard
Einstiegspunkt für JavaDoc mit der start()-Methode. Hier wird die Erzeugung aller HTML-Seiten koordiniert.
gp  HtmlWriter
Diese Klassen übernimmt das Schreiben der verschiedenen HTML-Tags.
gp  HtmlDocWriter
Eine Erweiterung von HtmlWriter, die zusätzlich die Hyperlinks verwaltet. Zudem kümmert sich die Klasse um die Links in der Kopf- und Fußzeile der HTML-Seiten.
gp  PackageIndexWriter
Sie generiert eine Datei mit allen Paketen, die auf der Kommandozeile von JavaDoc übergeben wurden. In der Regel heißt die Datei packages.html. Beim JDK ist dies die Startseite, wenn wir die Seite »Java Platform API Specification« anfordern.
gp  PackageIndexFrameWrite
Diese Klasse erzeugt eine Liste von Verweisen im linken oberen Frame (falls die Ausgabe in Frames ist). Die Datei heißt packages-frame.html.
gp  PackageFrameWriter
Jede Klasse eines Pakets ist in der Datei package-frame-<package-name>.html aufgeführt. Der Inhalt des Frames liegt in der linken unteren Ecke des Frame-Sets.
gp  FrameOutputWriter
Falls die Dokumentation in der Frame-Ansicht gewünscht ist, so liegt in frame.html die Verwaltung der vier Fenster.
gp  PackageWriter
Diese Klasse erzeugt eine Seite eines Pakets, die eine Liste aller Interfaces und Klassen enthält, die in der Kommandozeile von JavaDoc angegeben sind. Eine aus dem Awt-Paket erzeugte Datei heißt package-java.awt.html.
gp  ClassWriter
Mit dieser Klasse wird eine HTML-Seite für jedes Interface oder jede Klasse erzeugt. Beispiel dafür ist java.awt.Button.html.
gp  SingleIndexWriter
Dies erzeugt eine Index-Datei mit einer Liste, der in den Klassen definierten Elemente (Klassenname, Methoden, Interfaces, Konstanten). (Die Option -breakindex darf nicht gesetzt sein.)
gp  SplitIndexWriter
Je eine Index-Dateie für einen Buchstaben wird erzeugt. Dies ist die Einstellung für die -breakindex-Option. Ein Beispiel ist 1-index.html für den Buchstaben A.
gp  TreeWriter
Dies erzeugt eine Baumstruktur, in der die Vererbungshierachie aufgelistet ist. In der JDK-Dokumentation die Datei tree.html.
gp  DeprecatedListWriter
Sie erzeugt eine Datei mit dem Namen deprecatedlist.html, in der alle veralteten APIs aufgeführt sind.

Methoden in der Implementierung des Standard-Doclets

Um ein Gefühl für die Doclet-Programmierung zu bekommen, werfen wir einen Blick auf die Implementierung des Standard-Doclets. Diese Klasse besitzt eine statische Variable (Configuration) und eine Reihe von Methoden:

gp  boolean start( Root root )
Die nötige Start-Methode.
gp  public static Configuration configuration()
Erzeugt eine Configuration, falls es noch keine gibt.
gp  protected void startGeneration( Root root )
Beginnt mit der Datei-Erzeugung. Sie ruft die jeweiligen Methoden der Writer-Objekte auf. Als allererstes wird TreeWriter aufgerufen, damit die Klassenhierarchie bekannt ist und diese für die anderen Writer zur Verfügung steht.
gp  protected void startGenerationOneOne( Root root )
Wie startGeneration(), nur für das alte 1.1-Format.
gp  protected void generateClassCycle( ClassDoc[] arr,ClassTree classtree )
Erzeugt ein ClassWriter-Objekt zur Dokumentation jeder Klasse, das in dem Array ClassDoc[] auftaucht.
gp  public static int optionLength( String option )
Überprüft Doclet-Optionen der Statuszeile. null heißt, dass die Option unbekannt ist. Negative Argumente zeigen einen Fehler an.

Zusammenfassung der Klassen des Pakets com.sun.tools.javadoc

Damit wir uns im folgenden Kapitel besser zurechtfinden, listen wir an dieser Stelle die Klassen des Pakets com.sun.tools.javadoc auf. Das Paket enthält nur ein Interface (Type), das einen Java-Typ beschreibt (Objektverbindung, Primitiver Datentyp).

Tabelle 26.4   Klassen im Paket sun.tools.javadoc
Klasse Beschreibung
ClassDoc Eine Java-Klasse
ConstructorDoc Ein Konstruktor einer Klasse
Doc Abstrakte Basisklasse für alle Doc-Klassen
Doclet Dokumentiert die Methoden eines Doclets, abstrakt
ExecutableMemberDoc Methode oder Konstruktor einer Klasse
FieldDoc Eine Variable der Klasse
MemberDoc Abstrakte Klasse, die Gemeinsamkeiten von Feldern,
Konstruktoren und Methoden verwalten
MethodDoc Eine Methode der Klasse
PackageDoc Informationen über ein Paket
ParamTag Ein @param Dokumentations-Tag
Parameter Informationen über Parameter
ProgramElementDoc Abstrakte Klasse, verwaltet ein Programm-Element wie Klasse, Interface, Feld, Konstruktor, Methode
Root Informationen vom Start
SeeTag Das @see Dokumentations-Tag
Tag Ein Dokumentation-Tag wie @since, @author, @version
ThrowsTag @throws- oder @exception-Tag


Galileo Computing

26.5 Dienstprogramme zur Signierung von Applets  downtop

Wir wollen uns in diesem Abschnitt mit einigen Werkzeugen beschäftigen, die zur Signierung von Applets vom Java-SDK in der Standardinstallation angeboten werden. Zum Signieren von Applikationen sowie Applets und zur Vergabe der Zugriffsrechte und –beschränkungen stellt Sun die Dienstprogramme keytool, jarsigner und policytool bereitet.


Galileo Computing

26.5.1 keytool  downtop

Mit dem Programm keytool lassen sich öffentliche und private Schlüssel erzeugen, die in einer passwortgeschützten und verschlüsselten Datei abgelegt werden. Die Datei hat standardmäßig den Namen .keystore und befindet sich im Benutzerverzeichnis des Anwenders. Mit dem Programm keytool lassen sich neben der Schlüsselgenerierung auch Zertifikate importieren, Zertifikatanforderungen ausstellen und Schlüssel als vertrauenswürdig festlegen.

Möchten wir ein Schlüssel erstellen, rufen wir das Programm keytool mit der Option -genkey auf. Das ist einer der wichtigsten Optionen. Daneben wird mit der Option -alias ein Name für den Schlüsselinhaber angegeben:

$ keytool -genkey -alias CUllenboom

Anschließend fragt keytool nach dem Passwort des Schlüsselspeichers und erfragt weitere Angaben zum Schlüsselinhaber. Mit diesen Informationen erzeugt das Programm ein Schlüsselpaar mit einem selbstzertifizierenden Zertifikat. Bei diesem speziellen Zertifikat sind Aussteller und Inhaber identisch.

Tabelle 26.5   Klassen im Paket sun.tools.javadoc
-genkey Erzeugung eines Schlüsselpaares
-import Importieren eines Zertifikats
-selfcert Erstellung eines selbstsignierten Zertifikats
-certreq Export einer Zertifikats-Anforderung; sie kann als Datei an eine CA geschickt werden.
-export Export eines Zertifikats. Dieses kann dann von einem anderen Benutzer importiert und als vertrauenswürdig deklariert werden.
-list Listet alle Zertifikate und Schlüssel auf
-delete Entfernt ein Schlüsselpaar
-help Zeigt eine kurze Hilfe an

Die Angaben der Optionen sind immer dann sinnvoll, wenn die Standardeinstellungen unpassend sind. Über die Optionen lassen sich die Algorithmen zur Verschlüsselung und Schlüsselgenerierung ebenso angeben wie eine Pfadangabe des Schlüsselspeichers oder die Gültigkeitsdauer.


Galileo Computing

26.5.2 jarsigner  downtop

Mit dem Dienstprogramm jarsigner lassen Jar-Archive signieren und verifizieren. Dazu erstellt jarsigner einen Hashcode des Archivs und verschlüsselt dann mit dem privaten Schlüssel die Datei. Das Zertifikat und der öffentliche Schlüssel wird dem Archiv beigelegt. Der allgemeine Aufruf von jarsigner hat folgendes Format:

$jarsigner Archiv Keystore
Beispiel Signiere das Archiv archiv.jar mit dem Schlüsselspeicher von CUllenboom

$jarsigner archiv.jar CUllenboom

Dann werden dem Archiv zwei weitere Dateien hinzugefügt. Eine Signatur-Datei mit der Endung .sf und eine Signaturblock-Datei mit der Endung .dsa. Die Signatur-Datei enthält eine Liste aller Dateien im Archiv und speichert zudem den Hashwert zu einer mit aufgeführten Hash-Funktion. Diese Signatur-Datei wird dann mit dem privaten Schlüssel des Signierers signiert und zusammen mit dem verschlüsselten Zertifikat des Signierers in der Signaturblock-Datei gespeichert.

Möchten wir wissen, ob ein Archiv verifiziert ist, schreiben wir:

$jarsigner -verify Archiv

Galileo Computing

26.5.3 policytool  downtop

Dieses grafische Java-Dienstprogramm bietet uns die Möglichkeit, signierten Applets und Applikationen spezielle Rechte einzuräumen oder zu verweigern. In der Regel werden die Sicherheitseinstellungen von Java standardmäßig in der Datei .java.policy im Unterverzeichnis lib/security der Java-Installation gespeichert. Zusätzlich kann jeder Benutzer eigene Rechte-Dateien, so genannte Policy-Dateien, anlegen. Diese müssen dann unter dem Namen .java.policy im Benutzerverzeichnis abgespeichert werden. Unter Unix ist das das Verzeichnis $HOME.

Nach dem Aufruf des Programms policytool öffnet sich ein Fenster, welches uns einige Menüpunkte bereitstellt, mit wem wir bestehende Rechterdateien editieren, oder auch neue anlegen können.

Abbildung 26.1   Das grafische Policy-Tool
Abbildung

Neue Einträge für die Zugeständnisse der Laufzeitumgebung an das Programm werden über das Menü Add Policy Entry gemacht. Über das Dialog-Fenster können anschließend eine Reihe von erlaubten Eigenschaften ausgewählt werden, dann Permissions. Folgende Tabelle zeigt einige Permissions und ihre Bedeutungen:

AllPermission Die Anwendung oder das Applet dürfen alles
FilePermission Zugriff auf Dateien und Verzeichnisse
NetPermission Zugriff auf Netzwerkressourcen
PropertyPermission Zugriff auf Systemeigenschaften
ReflectPermission Zugriff über Reflection auf andere Objekte erlauben
RuntimePermission Einschränkungen von Laufzeitsystemen wie Klassenlader
SecurityPermission Einstellen eines allgemeinen Sicherheitskonzepts etwa für den Zugriff auf Policies
SerializablePermission Beschränkung der Serialisierung
SocketPermission Spezielle Einschränkungen an einer Socket-Verbindung


Galileo Computing

26.6 Konverter von Java nach C  downtop

Obwohl wir von der Qualität der Sprache Java mittlerweile überzeugt sein müssten, ist ein Makel immer noch die Geschwindigkeit: Java ist durch den Interpretiervorgang langsam. Da die Compiler- und Interpretertechnik für diese Sprache aber in der Vergangenheit bereits einige Fortschritte gemacht hat, ist auch auf weitere Verbesserungen zu hoffen. Von C wissen wir, dass es schnelle und gute C-Compiler gibt, da diese schon eine lange Tradition haben – zwanzig Jahre sind eine lange Zeit. Warum also nicht beide Welten verbinden und Java-Programme in C-Programme konvertieren?


Galileo Computing

26.6.1 Toba  downtop

Toba ist ein Konverter, der Klassendateien in C-Quellcode umsetzt. Er steht unter dem Copyright von »Arizona Board of Regents«. Bei der Entwicklung von Toba an der Universität Arizona wurde großer Wert auf Portabilität gelegt. Der erzeugte Quellcode läuft mittlerweile auf den Plattformen Solaris, Linux, Irix und Windows NT. Bedauerlichweise laufen bisher nur unter Solaris die Threads und die AWT-Funktionen. Die aktuelle Version ist Beta 6 von April ’97. Toba wird jedoch nicht mehr weiterentwickelt, da die Programmierer die Universität beendet haben und in Unternehmen gegangen sind. Getestet wurde Toba bisher unter folgenden Konfigurationen:

gp  Irix 6.2 mit cc Version 6.2
gp  Linux 2.0.18 (Red Hat 4.0) gcc Version 2.7.2
gp  Solaris 2.5.1 (SunOS 5.5.1) mit SunPro C
gp  Solaris 2.5.1 (SunOS 5.5.1) mit gcc Version 2.7.2
gp  Windows NT 4.0 mit Cygwin32 Beta 17.1

Hat Toba aus den Klassendateien C-Programme erzeugt, benötigen wir nur noch einen C–Compiler und zwei Bibliotheken. Die Bibliotheken sind für die Implementierung des Garbage Collectors und der Threads.

Entwickelt wird Toba von der Sumatra-Gruppe von Todd Proebsting, John Hartman, Gregg Townsend, Patrick Bridges, Tim Newsham und Scott Watterson.

Dem Toba-Paket ist ein Garbage-Collector für C und C++ beigelegt. Das Copyright halten Hans-J. Boehm, Alan J. Demers, Xerox Corporation und Silicon Graphics.

Ebenso liegt Toba das BISS-AWTBISS-AWT-Paket bei. Dieses Paket ist eine einhunderfünfzig Klassen umfassende Sammlung von Funktionen, die es erlauben, Grafische Benutzeroberflächen zu gestalten. Im Gegensatz zu den Sun-Klassen, die den Peer-Ansatz wählen, um auf den verschiedenen Betriebssystemen auch das Look-And-Feel der jeweiligen Oberfläche zu erreichen, kommen diese Klassen ohne Peers aus und implementieren ihr eigenes Look-And-Feel. Die Rechte für BISS hat die BISS GmbH, der Quellcode läuft aber unter der GPL. Er liegt in der Version 0.87 vor.


Galileo Computing

26.6.2 Arbeitsweise von Toba  downtop

Toba selbst ist ein fünftausend Zeilen-Java-Programm, das die Klassen in C-Programme umsetzt, die dann etwa viermal schneller ablaufen. Von der Kommandozeile wird einfach

$toba Dateiname.java

getippt und heraus kommen mehrere C und H Dateien, die, falls sie compiliert werden, eine ausführbare Datei »a.out« ergeben. Der Dateiname kann mit der Option »-o« geändert werden.

Für jede Klasse wird eine Header-Datei (für Funktionsprototypen, Strukturdefinitionen und Klasseninitialisierer) und eine Quellcodedatei für die Klasse (Stukturinitialisierung und Methodencode) erzeugt. Toba sammelt alle Klassen zusammen und verlangt dann in einer Klasse die Methode static void main(String []).


Galileo Computing

26.6.3 Abstriche des Konverters  downtop

Java ist eine mächtige Sprache und C unterstützt viele dieser Eigenschaften nicht; sie müssen also, wollten wir eine eins-zu-eins-Übersetzung, nachgebildet werden. So fängt alles schon beim GC an. Doch auch für C gibt es schon seit längerer Zeit einen konservativen Garbage-Collector von Boehm-Demers-Weiser; er ist auf viele Plattformen angepasst.

Dynamisches Laden

Abstriche bei Toba müssen wir bei Programmen machen, die Klassen dynamisch nachladen. Alle Klassen müssen vorcompiliert vorliegen. Dann werden sie zu einem ausführbaren Programm zusammengebunden. Die Java-Klasse java.lang.ClassLoader zum Laden anderer Klassen zur Laufzeit ist nicht implementiert. Ebenso liefert der Aufruf von java.lang.Class.getClassLoader() immer null. Die Funktion java.lang.Class.forName() funktioniert aber unter Solaris, Irix und Linux einwandfrei, wenn die angesprochene Klasse mit vorkompiliert wurde.

System Properties

Alle System-Properties werden übernommen; jedoch anders belegt.

Tabelle 26.6   Unter Toba belegte System-Properties
Variable Belegung
awt.toolkit biss.awt.kernel.Toolkit
java.vendor The University of Arizona
java.vendor.url http://www.cs.arizona.edu/sumatra
java.vendor.version 1.0.b5
java.version 1.0.2
java.class.version 45.3

Überprüfung auf Korrektheit und Sicherheit

Wird nicht vorgenommen, da Toba annimmt, dass alle Klassen aus korrektem Java-Bytecode bestehen. Ein Security-Manager ist auch nicht nötig.

Threads

Da Toba auf verschiedenen Architekturen compiliert werden kann, gibt es noch systemabhängige Unterschiede: Nur unter Solaris können native Threads benutzt werden, unter Win NT, Linux, IRIX nicht.

AWT

Unter Solaris nutzt Toba das BISS-AWT PaketBISS-AWT Paket, um Fenster und die Grafik darzustellen.


Galileo Computing

26.7 Konverter von Java Byte Code in ein Windows-Exe mit JET  downtop

Für die Konvertierung und Compilierung von Bytecode in ein direkt ausführbares Format (Java to Native Code Compiler) ist die Firma Excelsior, LLC (http://www.excelsior-usa.com/jet.html) mit ihrem Tool JET bekanntgeworden. Die Firma hat unter anderem Modula-2 und Oberon-2 Compiler entworfen und eine langjährige Erfahrung mit Optimierungstechniken. JET nimmt als Eingabe compilierte Klassendateien und wandelt diese in ausführbare exe-Dateien um. Neben der reinen Umsetzung wird der Code auch gleich optimiert. Zwischencode in C wird nicht erstellt und daher ist es auch nicht notwendig, dass ein C-Compiler installiert ist.

Voraussetzung für die Compilation ist eine Menge freier Speicher und ein installiertes Java SDK in der Version 1.3.1 oder 1.3.0_02. JET unterstützt alle Java 2 SE Pakete inklusive AWT/Swing, JNI und die Invocation-API. In der Professional Edition gibt es zusätzlich Unterstützung zum dynamischen Laden von Klassen, was etwa bei RMI genötigt wird. Die freie Version Excelsior JET 2.0 Evaluation Package lässt sich unter http://www.excelsior-usa.com/jetdleval.html beziehen. Sie ist für 60 Tage zur Benutzung frei.

Andere interessante Compiler, da nativen Code erzeugen sind

gp  Jove von Instantiations unter http://www.instantiations.com und
gp  BulletTrain von Natural Bridge unter http://www.naturalbridge.com.

Galileo Computing

26.8 Manteln von Javaklassen in ein Windows-Exe mit JToExe  downtop

Wer Javaprogramme vertreibt, weiß um das Problem der JVM-Versionen, Bibliotheken und Pfade. Einen intelligenten Weg geht das Programm JToExe, denn es kapselt die Java-Klassen – beziehungsweise Jar-Achive – in einem ausführbaren Exe-Programm für Windows. JToExe (http://www.bravozulu.com) ist für nicht-kommerzielle Anwendungen frei, andernfalls beträgt der Preis für ein Jahr Support neununddreißig US-Dollar.

Der Wrapper sucht selbstständig den passenden Java-Interpreter heraus. Die ausführbare .exe Datei bekommt optional ein frei wählbares Icon zugewiesen und lässt sich einfach mit Doppelklick starten. Den Programmen lassen sich über Umgebungsvariablen Parameter beilegen und die Kommandozeilenparameter werden durchgereicht. Leider kapselt JToExe dabei nur die Klassen und fügt die Originalpakete sowie den Interpreter nicht in das Exe hinzu. Ebenso verschlüsselt es den Bytecode nicht, sodass prinzipiell die Klassen wieder aus dem Exe entnommen werden können. Ein weiteres Manko ist, dass Wrapper zusätzlich die Zielplattform einschränken. Selbst wenn das Programm prinzipiell unter anderen Betriebssystemen funktionieren würde, wird die Installation dort erschwert bis unmöglich gemacht.


Galileo Computing

26.9 Decompiler  downtop

Ein Decompiler wandelt Java-Klassendateien in Java-Quellcodedateien zurück. Er verdreht also die Arbeitsweise eines Compilers, der aus der Quellcodedatei eine ausführbare Datei beziehungsweise Klassendatei erzeugt. Obwohl es für die verschiedensten Sprachen Decompiler gibt (unter anderen C und Smalltalk), ist für Java die Zurückübersetzung relativ einfach. Der Java-Compiler erstellt für einen virtuellen Prozessor Bytecode und dieser Bytecode enthält viele wertvolle Informationen, die in herkömmlichem Assembler nicht auftauchen. Darunter sind etwa Typinformationen oder Hinweise, ob ein Methodenaufruf virtuell ist oder nicht. Sie sind für den Interpreter ebenfalls wichtig, um Programme als sicher oder unsicher zu erkennen. Dies macht es einfach, verlorenen Quellcode wiederzubeleben oder an fehlende Information aus Paketen von Fremdherstellern zu gelangen. Ein weites Anwendungsgebiet sind Optimierungen am Quellcode. Über die Rückübersetzung lässt sich die Arbeitsweise eines Compilers gut verstehen und wir können an einigen Stellen optimieren, wenn wir beispielsweise sehen, dass eine Multiplikation mit der Zahl 16 doch nicht zu einem Shift optimiert wurde. Das Übersetzen ist dabei verhältnismäßig einfach. Ein Decompiler benötigt lediglich die Klassendatei, wobei einige Decompiler auch direkt einen Verbund von Klassen aus einem Jar-Archiv unterstützen. Aus dem Java Byte- Code für eine Methode baut er dann einen Kontrollfluss-Graphen auf und versucht Ausdrücke zu erkennen, die bei der Übersetzung bestimmter Sprachkonstrukte entstanden sein müssten. Da Variablennamen durch einen Obfuscator eventuell ungültig gemacht worden sind, muss ein guter Decompiler diese illegalen Bezeichnernamen korrigieren. Somit sollte der Quelltext auch noch gut lesbar sein, obwohl er verunstaltet wurde. Diese Umbenennung ändert den Algorithmus nicht und ein Decompiler hat es bei dieser Art von Verschleierung einfach. Es sind allerdings andere Techniken in der Entwicklung, die den Bytecode erst zur Laufzeit entschlüsseln und dieser ist dann in der Klassendatei nicht mehr lesbar.

Da mittlerweile auch andere Compiler auf den Markt sind, die Java Bytecode erzeugen – etwa aus EIFFEL Programmen oder aus diversen LISP-Dialekten – ist über den Umweg Compiler/Klassendatei/Decompiler ein Crosscompiling denkbar. Hier sind aber einige Einschränkungen bezüglich der auf dem Markt befindlichen Decompiler erkennbar. Denn fremde Compiler, die Java Byte Code erstellen, haben andere Techniken, die dann vom Decompiler nicht immer passend übersetzt werden können. Wir werden uns im Folgenden näher mit Jad beschäftigen. Ein weiterer Open-Source Decompilator und Obfuscator, JODE (Java Optimize and Decompile Environment), findet sich unter http://jode.sourceforge.net. Interessante Artikel und eine Liste gängiger Decompiler finden sich etwa unter

gp  http://www.softpanorama.org/Algorithms/decompilation.shtml
gp  http://www.meurrens.org/ip-Links/java/codeEngineering/decomp.html
gp  http://www.csee.uq.edu.au/~csmweb/decompilation/halstead.htm

Ist das Decompilieren legal?

Wenn der Decompiler auf den eigenen Programmcode losgelassen wird, weil etwa der Quellcode verschwunden ist, dann ist die Anwendung kein Problem. Das Reverse Engineering von kompletten Anwendungen, die unter Urheberschutz stehen, ist dabei auch nicht unbedingt das Problem. Vielmehr beginnt die Straftat, wenn dieser Quelltext verändert und als Eigenleistung verkauft wird.


Galileo Computing

26.9.1 Jad, ein schneller Decompiler  downtop

Jad (von Java Decompiler) ist ein frei verfügbarer Decompiler von Pavel Kouznetsov und unter der nachfolgenden Adresse zu beziehen: http://www.geocities.com/SiliconValley/Bridge/8617/jad.html. Da Jad zu 100 % in C++ geschrieben ist , decompiliert das Tool die Dateien sehr schnell; viel schneller als seine in Java programmierten Konkurrenten. Jad macht es einfach, schon vorhandene Klassendateien zu »reengineeren« . Die Dateien der Laufzeitbibliothek lassen sich somit auch im Quellcode beäugeln. (Da allerdings beim SDK viele Klassen im Quellcode vorliegen, lohnt sich das nur bei Klassen, die nicht öffentlich sind.)

Da Jad nicht vom Java Laufzeitsystem abhängig ist, ist das Setzen des CLASSPATH nicht notwendig und ein Setup wird nicht benötigt. Da Jad auf jeden Fall den Bytecode auseinandernehmen muss, lässt sich zum Disassemblieren der Java Bytecode auch in den Quellcodezeilen einblenden. Eine prima Möglichkeit, Bytecode zu lernen und zu sehen, wie der Compiler funktioniert. Einen weiteren Pluspunkt bekommt Jad im Umgang mit Klassendateien, die durch einen Obfuscator verunstaltet wurden. Daraus wird wieder gültiger Javacode erzeugt. Manchmal muss jedoch auch Jad aufgeben und Zuweisungen verschwinden beispielsweise.

Vom Download zur Installation

Jad liegt zur Zeit in der Version 1.5.8 vor. Obwohl Jad nicht im Quelltext vorliegt, ist die Unterstützung von verschiedenen Betriebssystemen gewährleistet. Unter anderem Windows 95/NT, Linux für Intel (auch statisch gelinkt), AIX 4.2 für IBM RS/600, OS/2, Solaris 2.5 für SUN Sparc, FreeBSD 2.2.

Das Programm ist schnell geladen und auch genauso schnell entpackt. Danach offenbaren sich zwei Dateien, eine ausführbare mit dem Namen jad.exe (Windows 95/NT) oder nur jad (UNIX). Daneben gibt es noch eine Liesmich-Datei readme.txt, welche eine kurze Anleitung für Jad enthält. Eine grafische Oberfläche wie FrontEnd Plus (http://www. reflectonus.pwp.blueyonder.co.uk/download.htm) vereinfacht die Entwicklung noch weiter, denn sie kommt zusammen mit Jad in einem leicht zu nutzendem Windows-Programm daher. Doch bleiben wir bei der Kommandozeile.

Jad benutzen

Um eine Klassendatei zu decompilieren, wird Jad einfach auf diese Datei losgelassen:

$jad example1.class

Ohne zusätzliche Option wird dann eine Datei example1.jad im Arbeitsverzeichnis angelegt. Jad verwendet nicht den Namen der Datei als Ausgabe, sondern den Namen der Klasse. Enthält also example1.class keine Klasse mit dem Namen example1, sondern mit expl1, so heißt die Datei auch expl1.jad und nicht example1.jad. Existiert schon eine Datei mit dem Namen, dann fragt Jad vorher nach, ob sie überschrieben werden kann. Die Option -o, überschreibt ohne zu fragen. Jad lässt auch Wildcards zum Aussortieren der Dateien zu. Ist der Standardname nicht sinnvoll, so lässt sich über den Schalter -s eine andere Extension erzeugen, anstatt die Endung jad im folgenden Beipiel .java:

$jad -sjava example1.class

Beim gleichzeitigen Verwenden der beiden Schalter -o und -sjava muss drauf geachtet werden, dass jad beim Experimentieren die originale Quelldatei nicht überschreibt.

Sollen alle Java-Klassen eines ganzen Dateibaums decompiliert werden, eignet sich dafür der Schalter -r ganz gut. Denn dieser erstellt auch Unterverzeichnisse im angegebenen Stammverzeichnis (Option -d):

$jad -o -r -sjava -dsrc tree/**/*.class (WIN)

$jad -o -r -sjava -dsrc 'tree/**/*.class' (UNIX)

Gibt es also in der Datei tree/a/b/c.class die Klasse »c« vom Paket a.b, dann geht die Ausgabe in src/a/b/c.java.

Optionen der Kommandozeile

Die Optionen sind in der folgenden Tabelle zusammengestellt. Alle Optionen mit Ein/Ausschaltcharakteristik lassen sich in drei Katgorien einteilen:

gp  -o
negiert den Wert der Option
gp  -o+
setzt den Wert auf »wahr« oder »an«
gp  -o-
setzt den Wert auf »falsch« oder »aus«
Tabelle 26.7   Schalter von Jad
Schalter Wirkung
-a JVM-Bytecode wird als Kommentar mit in den Quelltext eingesetzt
-af Wie -a nur mit voll qualifizierten Namen
-b Redundante Klammern um Anweisungen. Per Default aus.
Bsp. if(a) { b(); }
-disass Nur den Bytecode Disassemblieren ohne Quellcodeerzeugung
-d <dir> Verzeichnis der Ausgabedateien (wird wenn nötig auch angelegt)
-f Voll qualifizierte Namen für Klassen, Variablen und Methoden überall im Quelltext verwenden
-i Nichtfinale Variablen werden alle initialisiert
-l<num> String in zwei Hälften teilen, wenn sie länger als <num> sind. Nicht voreingestellt
-nl Strings mit Newline-Zeichen aufspalten. Nicht voreingestellt
-o Ausgabedatei überschreiben
-p Code in die Standardausgabe lenken. Sinnvoll für’s pipen
-r Verzeichnisstruktur vom Paket erhalten
-s <ext> Endung der Ausgabedateien bestimmen
-t Tabulatoren statt Leerzeichen zum Einrücken verwenden
-t<num> Breite der Einrückungen, voreingestellt sind vier Leerzeichen
-v Zeigt die Methodennamen, die decompiliert werden zur Kontrolle an
-8 Unicode String in 8-Bit Strings nach der ANSI Code Tabelle (nur Win32) umwandeln


Galileo Computing

26.9.2 SourceAgain  downtop

SourceAgain und SourceAgain Professional (http://www.ahpah.com/cgi-bin/suid/~pah/demo.cgi) sind zwei kommerzielle Dienstprogramme zum Decompilieren. Da die Qualität bzw. die Leistung von SourceAgain mit Jad vergleichbar und Jad ein freies Programm ist, soll SourceAgain hier nicht vertieft werden. SourceAgain existiert allerdings in einer Web Version und der Benutzer kann eine URL mit einem Java Applet angeben, das dann eingelesen und übersetzt wird. Falls mehrere Applets auf einer Seite existieren, so gibt das Programm einen Auswahldialog. Ähnlich wie bei Jad lassen sich verschiedene Parameter setzen. Für kurze Überprüfungen ist dies eine gute Wahl, da wir die Applets nicht erst auf die Festplatte kopieren und dann in einem zweiten Schritt umwandeln müssen.


Galileo Computing

26.9.3 Decompilieren erschweren  downtop

Obwohl wir Decompilation verhindern können, so können wir immer noch nicht das bloße Disassemblieren des Bytecodes stören. Es gibt allerdings einige einfache Tipps, die dem motivierten Angreifer schnell die Lust am Bytecode verderben. Wir beschreiben einige Regeln, die das Entschlüsseln vom Bytecode oder das Umgehen einer Seriennummereingabe erschweren. Dazu gehört:

gp  Verwendung von Methodennamen und Klassennamen aus Nullen, dem Buchstaben O, Einsen und dem Buchstaben l. Einige freie Obfuscatoren lassen sich leicht anpassen, sodass sie solche Bezeichner erstellen.
gp  Es sollten keine lesbaren Zeichenketten im Quellcode vorkommen. Füge jeder Klasse eine individuelle Entschlüsselungsfunktion zu.
gp  Konstanten sollten über mathematische Funktionen errechnet werden. Erwartet das Programm zum Beispiel die Taste KeyEvent.VK_F1, so wird der Compiler automatisch für die Konstante den Wert 0x70 einsetzen. Wir können natürlich diesen Wert stattdessen auch dynamisch berechnen.
gp  Verwendung vieler bedingter Sprünge, die aber unnütz sind.
gp  Wenn die Möglichkeit besteht, den Bytecode direkt zu manipulieren, können legale aber unsinnige Bytecode-Sequenzen eingefügt werden. Dynamischer Java-Bytecode hat sich (noch) nicht durchgesetzt, wäre aber möglich. Denkbar ist, an bestimmte Stellen einer Klassendatei Zeichen zu schreiben, dann diese Datei über den Klassenlader zu laden und dann wieder die Information zurückschreiben. An der bestimmen Position könnte etwa eine Variable sitzen.
gp  Teile des Programmcodes sollten auf Tabellen zurückgreifen, die dynamisch berechnet werden.
gp  Ein Startbildschirm mit Grafik und Text (Splash-Screen bzw. Nag-Screen) kann leicht zurückverfolgt werden. Daher sollte besser darauf verzichtet werden.
gp  Bei einer Seriennummer und einem Ablaufdatum lässt sich die Systemzeit natürlich zurücksetzen. Wir können kontinuierlich in eine Datei verschlüsselt ein Datum schreiben und dies immer erhöhen. Ist das Datum des Rechners kleiner als das Datum in der Datei, versuchte der Benutzer zu schummeln. Ein alternativer Weg ist plattformabhängig: Einige Systemdateien haben das Datum vor dem Zurückstellen, wie etwa SYSTEM.DAT.
gp  Werden Seriennummern eingegeben, so sucht der Angreifer nach Textfeldern. Besser ist in diesem Fall eine Low-Level-Event-Verarbeitung. Wir legen einen Listener zum Beispiel auf etwas ganz anderes, beispielsweise ein Label. Die Ereignisse werden abgefangen und bearbeitet. Aus dem AWT-Event holen wir dann die Zeichen heraus. Da der Angreifer aber auch nach Eventhandlern sucht, ließe sich auch die System-Queue abhorchen.
gp  Checksummen von Klassen bilden, die eventuell angezapft werden könnten. In einer anderen Klassen lässt sich dann diese Checksumme testen. Zum Entschlüsseln von Daten lassen sich auch weiteren Klassendateien verwenden.

Und mein Lieblingstipp: Zeitmessungen machen, um zu erkennen, dass jemand versucht, das Programm zu debuggen. Zudem lassen sich Cracker leicht befriedigen, in dem ihnen eine offensichtlichen Prüfung einer eingegebenen Seriennummer angeboten wird. An weiteren Stellen kann aber ein Test auf die Seriennummer und subtile Fehlfunktionen ins Programm eingewoben sein. Das Programm hat kleine Fehler oder Unzulänglichkeiten, falls die Seriennummer diese Tests nicht auch noch erfüllt.


Galileo Computing

26.10 Obfuscate Programm RetroGuard  downtop

RetroGuard (http://www.retrologic.com) ist ein Open Source Projekt, das Java-Klassen und Jar-Archive verschleiert, also obfuscated. Die Bezeichner werden dabei für das gesamte Paket umbenannt und für neugierige Augen ermüdend gestaltet.


Galileo Computing

26.11 Source-Code Beautifier  toptop

Einen Quellcodeverschönerer hat die Aufgabe, Quellcode unter Beibehaltung der logischen Struktur lesbarer und damit wartungsfreundlicher zu machen. Die Funktionen, die ein Beautifier anbietet, sind beispielsweise:

gp  Intelligente Einrückung des Quellcodes mit Tabulatoren oder Leerzeichen und Absatzende-Zeichen
gp  Konsistentes behandeln der geschweiften Klammern. Unterschiedliche Schulen propagieren sehr unterschiedliche Auffassungen, wie die geschweiften Klammern im Quelltext gesetzt werden sollen.
gp  Formatieren der Kommentare in einem einheitlichen Format
gp  Automatisches generieren der JavaDoc-Anweisungen. Das, was aus dem Quelltext hervorgeht, lässt sich automatisch in Dokumentationskommentar übersetzen.
gp  Einfügen von Kopf- und Fußzeilen Vorlagen (Templates)
gp  Verarbeitungen im Batch-Prozess
gp  Einige Produkte bieten ebenfalls eine offene API an, sodass das Produkt als Bibliothek von eigenen Programmen genutzt werden kann. Das ist nützlich für Programme, die Java-Quellcode generieren, wie Parser-Generatoren oder UML nach Java-Programme. Die Software kann dann entlastet werden, und muss sich nicht um die Einrückung des erzeugten Quellcodes kümmern.
Abbildung

Einige Programme schicken sich nun an, diese Anforderungen zu erfüllen. Viele Dienstprogramme sind im Quellcode verfügbar. Die folgende Liste zählt einige Produkte auf:

gp  JxBeauty 2.0 unter http://members.magnet.at/johann.langhofer/products/jxbeauty/overview.html ist Freeware und formatiert Quellcode nach den Konventionen von Sun und kann umfangreich angepasst werden. JxBeauty lässt sich als Plugin in JBuilder (Inprise’s JBuilders OpenTools) einsetzen.
gp  JavaBeautifier unter http://www.javaregex.com/cgi-bin/pat/jbeaut.asp.
gp  VanCBJ42 unter http://www.geocities.com/~starkville/vancbj_idx.html. Auf der Webseite des Autors ist ebenfalls ein Java-Applet zu finden.
gp  Jindent unter http://www.jindent.com ist ein kommerzielles Produkt, das aber auch in einer freien Variante angeboten wird. Das Produkt ist sehr professionell und erlaubt eine sehr feine Einstellung der Ausgabe über Konfigurationsdateien. Daneben kann das Programm auch den Quellcode für Web-Seiten oder Präsentationen aufbereiten.

 






1    Obwohl dieser schon vergeben ist, doch vielleicht ist Darkwin Duck ja noch frei.

2    Die Idee ist nicht neu. In den achziger Jahren verwendete D. E. Knuth das WEB-System zur Dokumentation von TeX. Das Programm wurde mit den Hilfsprogrammen »weave« und »tangle« in ein Pascal-Programm und eine TeX-Datei umgewandelt.

3    Diese ist dem JDK (Java Development Kit) beigefügt.

4    http://www.cs.arizona.edu/sumatra

5    Wollte der Autor verhindern, dass auch sein Tool entschlüsselt wird?

6    Abkürzung für »Reverse Engineering« – das Zurückverwandlen von unstrukturiertem Binärcode bzw. Quellcode.

7    Ein Obfuscator benennt Methoden- und Klassennamen in unsinnige Bezeichner um. Er verschlüsselt Zeichenketten und versucht im Code solche Bytecode-Kombinationen einzubauen, die von einem normalen Decompiler nicht wieder umgewandelt werden können.

  

Java 2




Copyright © Galileo Press GmbH 2002
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press GmbH, Gartenstraße 24, 53229 Bonn, fon: 0228.42150.0, fax 0228.42150.77, info@galileo-press.de