Java SE 8 Standard-Bibliothek  
Professionelle Bücher. Auch für Einsteiger.
 
Inhaltsverzeichnis


Vorwort
1 Neues in Java 8 und Java 7
2 Fortgeschrittene String-Verarbeitung
3 Threads und nebenläufige Programmierung
4 Datenstrukturen und Algorithmen
5 Raum und Zeit
6 Dateien, Verzeichnisse und Dateizugriffe
7 Datenströme
8 Die eXtensible Markup Language (XML)
9 Dateiformate
10 Grafische Oberflächen mit Swing
11 Grafikprogrammierung
12 JavaFX
13 Netzwerkprogrammierung
14 Verteilte Programmierung mit RMI
15 RESTful und SOAP-Web-Services
16 Technologien für die Infrastruktur
17 Typen, Reflection und Annotationen
18 Dynamische Übersetzung und Skriptsprachen
19 Logging und Monitoring
20 Sicherheitskonzepte
21 Datenbankmanagement mit JDBC
22 Java Native Interface (JNI)
23 Dienstprogramme für die Java-Umgebung
Stichwortverzeichnis

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java SE 8 Standard-Bibliothek von Christian Ullenboom
Das Handbuch für Java-Entwickler
Buch: Java SE 8 Standard-Bibliothek

Java SE 8 Standard-Bibliothek
Pfeil 23 Dienstprogramme für die Java-Umgebung
Pfeil 23.1 Programme des JDK
Pfeil 23.2 Monitoringprogramme vom JDK
Pfeil 23.2.1 jps
Pfeil 23.2.2 jstat
Pfeil 23.2.3 jmap
Pfeil 23.2.4 jstack
Pfeil 23.2.5 jcmd
Pfeil 23.2.6 VisualVM
Pfeil 23.3 Programmieren mit der Tools-API
Pfeil 23.3.1 Java-Tools in Java implementiert
Pfeil 23.3.2 Tools aus eigenen Java-Programmen ansprechen
Pfeil 23.3.3 API-Dokumentation der Tools
Pfeil 23.3.4 Eigene Doclets
Pfeil 23.3.5 Auf den Compiler-AST einer Klasse zugreifen
Pfeil 23.4 Ant
Pfeil 23.4.1 Bezug und Installation von Ant
Pfeil 23.4.2 Das Build-Skript build.xml
Pfeil 23.4.3 Build den Build
Pfeil 23.4.4 Properties
Pfeil 23.4.5 Externe und vordefinierte Properties
Pfeil 23.4.6 Weitere Ant-Tasks
Pfeil 23.5 Disassembler, Decompiler und Obfuscator
Pfeil 23.5.1 Der Diassembler javap *
Pfeil 23.5.2 Decompiler
Pfeil 23.5.3 Obfuscatoren
Pfeil 23.6 Weitere Dienstprogramme
Pfeil 23.6.1 Sourcecode Beautifier
Pfeil 23.6.2 Java-Programme als Systemdienst ausführen
Pfeil 23.7 Zum Weiterlesen
 
Zum Seitenanfang

23.3Programmieren mit der Tools-API Zur vorigen ÜberschriftZur nächsten Überschrift

Tools wie der Java-Compiler javac, aber auch jarsigner, javadoc, xjc, javap und andere Kommandozeilenwerkzeuge, sind rein in Java geschrieben. Einige Tools bieten Entwicklern eine API, sodass sie erweitert und von Programmen angesprochen werden können. Das ist interessant für Tool-Anbieter, die zum Beispiel den Compiler erweitern oder die Ausgabe vom javadoc-Tool anpassen möchten.

 
Zum Seitenanfang

23.3.1Java-Tools in Java implementiert Zur vorigen ÜberschriftZur nächsten Überschrift

Alle in Java geschriebenen Programme befinden sich in einem Extra-Java-Archiv mit dem Namens tools.jar, das sich im lib-Verzeichnis des JDK befindet. Das JDK liefert allerdings nur die Klassendateien mit aus, die Quellen mit Javadoc müssen sich Interessierte selbst aus dem Mercurial Repository[ 154 ](Für Java 8 liefert http://hg.openjdk.java.net/jdk8/jdk8/langtools/ den Zugriff auf die Quellen. Sie lassen sich auch in einem Rutsch in unterschiedlichen Archivformaten, auch ZIP, beziehen.) holen, denn sie sind nicht im üblichen src.zip vom JDK mit dabei.

Die normalen ausführbaren Programme wie javadoc oder javah haben (unter Windows) alle die gleiche Größe um 15 KiB, da sie nichts anderes machen, als die Java-Laufzeitumgebung mit tools.jar im Klassenpfad aufzurufen und dann an die entsprechende main(String[])-Methode des Programms weiterzuleiten. Statt javadoc aufzurufen, kommt com.sun.tools.javadoc.Main.main(args) zum gleichen Ziel.

 
Zum Seitenanfang

23.3.2Tools aus eigenen Java-Programmen ansprechen Zur vorigen ÜberschriftZur nächsten Überschrift

Um ein Werkzeug direkt aus einem Java-Programm anzusprechen, gibt es zwei Möglichkeiten:

  • Die öffentliche Klasse javax.tools.ToolProvider bietet eine API, um Zugang zum Compiler zu bekommen und um das javadoc-Tool aufzurufen, mit dem die Java-Dokumentation erstellt oder die Javadoc-Kommentare verarbeitet werden können. Das Problem: Nur zwei Tools sind zugänglich, keine weiteren Tools wie javap, xjc, …

  • Aufrufe der Tool-Einstiegsklassen, etwa com.sun.tools.javadoc.Main.main(…). Da alle Tools über eine solche Klasse verfügen, ist ein direkter Aufruf aus einem Java-Programm immer möglich, aber nicht unproblematisch, da Entwickler sich hier von den internen Paketstrukturen abhängig machen.

 
Zum Seitenanfang

23.3.3API-Dokumentation der Tools Zur vorigen ÜberschriftZur nächsten Überschrift

Die öffentliche Klasse javax.tools.ToolProvider ist Teil der Java SE und folglich dokumentiert, so wie auch der Zugang zum Compiler und zum javadoc-Werkzeug. Ein Beispiel für die Übersetzung von Java-Quellen zeigte Kapitel 18, »Dynamische Übersetzung und Skriptsprachen«.

Die anderen JDK-Tools, die Entwickler aus Java heraus ansprechen können, haben ebenfalls API-Dokumentationen, die aber nicht zur Java SE-Standarddokumentation gehören, sondern in der Dokumentations-ZIP unter docs\jdk\api liegen. Dort lassen sich alle Details ablesen, wie etwa der Java-Compiler angesprochen wird oder wie Programme, die aus der Java-API-Dokumentation zum Beispiel verlinkte HTML-Dokumente aufbauen, so genannte Doclets, geschrieben werden. Oracle definiert nicht für jedes Tool eine öffentliche API. So ist es zum Beispiel nicht vorgesehen, in den Erzeugungsprozess von javah einzugreifen, und Oracle dokumentiert diese Eigenschaft in den Quellen auch wie folgt:

»This is NOT part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are subject to change or deletion without notice.«

 
Zum Seitenanfang

23.3.4Eigene Doclets Zur vorigen ÜberschriftZur nächsten Überschrift

Das javadoc-Tool hat die Aufgabe, den Java-Quellcode auszulesen und die Javadoc-Kommentare zu extrahieren. Was dann mit den Daten passiert, ist die Aufgabe eines Doclets. Das Standard-Doclet von Oracle erzeugt die bekannte Struktur auf verlinkten HTML-Dateien, aber es lassen sich auch eigene Doclets schreiben, um etwa in Javadoc-Kommentaren enthaltene Links auf Erreichbarkeit zu prüfen oder UML-Diagramme aus den Typbeziehungen zu erzeugen.

Die Doclet-API ist nicht Teil der Java-Standardbibliothek und auch nicht im Klassenpfad eingebunden. Um eigene Doclets zu schreiben, muss zunächst tools.jar in den Klassenpfad aufgenommen werden. Teil des Java-Archivs ist das Paket com.sun.javadoc, was Typen und Methoden deklariert, mit denen sich besuchte Pakete, Klassen, Methoden usw. und deren Javadoc-Texte erfragen lassen.

Im folgenden Beispiel wollen wir ein kleines Doclet schreiben, das Klassen, Methoden und Konstruktoren ausgibt, die das Tag @since 1.8 tragen (bzw. @since 8, was aber eigentlich falsch ist). So lässt sich leicht ermitteln, was in der Version Java 8 alles hinzugekommen ist. Doclets werden normalerweise von der Kommandozeile aufgerufen und dem javadoc-Tool übergeben. Unser Programm vereinfacht das, indem es direkt das Tool über Java mit dem passenden Parameter aufruft. tools.jar muss dafür im Klassenpfad sein und die Dokumentation ausgepackt am angegeben Ort.

Listing 23.2com/tutego/tools/javadoc/SinceJava8FinderDoclet.java

package com.tutego.tools.javadoc;

import java.util.*;
import java.util.function.Predicate;
import com.sun.javadoc.*;
import com.sun.tools.javadoc.Main;

public class SinceJava8FinderDoclet {

public static boolean start( RootDoc root ) {
for ( ClassDoc clazz : root.classes() )
processClass( clazz );
return true;
}

private static void processClass( ClassDoc clazz ) {
Predicate<Tag> isJava18 = tag -> tag.text().matches( "(1\\.)?8" );

if ( Arrays.stream( clazz.tags( "since" ) ).anyMatch( isJava18 ) )
System.out.printf( "Neuer Typ %s%n", clazz );

for ( MethodDoc method : clazz.methods() )
if ( Arrays.stream( method.tags( "since" ) ).anyMatch( isJava18 ) )
System.out.printf( "Neue Methode %s%n", method );

for ( ConstructorDoc constructor : clazz.constructors() )
if ( Arrays.stream( constructor.tags( "since" ) ).anyMatch( isJava18 ) )
System.out.printf( "Neuer Konstruktor %s%n", constructor );

for ( FieldDoc field : clazz.fields() )
if ( Arrays.stream( field.tags( "since" ) ).anyMatch( isJava18 ) )
System.out.printf( "Neues Attribut %s%n", field );
}

public static void main( String[] args ) {
String[] params = {
"-quiet", "-XDignore.symbol.file",
"-doclet", SinceJava8FinderDoclet.class.getName(),
"-sourcepath", "C:/Program Files/Java/jdk1.8.0/src/",
// "java.lang", // Nur java.lang
"-subpackages", "java:javax" // Alles rekursiv unter java.* und javax.*
};
Main.execute( params );
}
}

Unsere main(String[])-Methode ruft das JDK-Doclet-Programm über Main.execute(String[]) auf und übergibt die eigene Doclet-Klasse per Parameter – die Argumente von execute(String[]) erinnern an die Kommandozeilenparameter. Das Doclet-Hauptprogramm wiederum ruft unsere start(RootDoc root)-Methode auf – das Gleiche würde auch passieren, wenn das Doclet von außen über javadoc aufgerufen würde. Unser start(RootDoc) läuft über alle ermittelten Typen und übergibt zum Abarbeiten der Innereien die Verantwortung an processClass(ClassDoc). Die Metadaten kommen dabei über diverse XXXDoc-Typen. Ein Precidate zieht den Tag-Test heraus, ein weiterer Einsatz der neuen Java 8-Streams würde das Programm nicht übersichtlicher machen.

Das Programm nutzt ein paar Tricks, um die Ausgabe auf das Wesentliche zu konzentrieren. Der Schalter -quit schaltet den üblichen Ladestatus ab, der zu Ausgaben wie

Loading source files for package java.lang...
Loading source files for package java.applet...
Loading source files for package java.awt...

führt.

Der Schalter -XDignore.symbol.file wiederum unterdrückt Meldungen wie diese hier:

C:\…\src\java\lang\Class.java:57: warning: Unsafe is internal proprietary API and may ¿
be removed in a future release
import sun.misc.Unsafe;
^

Die Meldungen landen auf dem System.err-Kanal, sodass sie auch mit System.setErr(…) in einen ausgabeverwerfenden Strom geschickt werden können, um sie zu unterdrücken.

 
Zum Seitenanfang

23.3.5Auf den Compiler-AST einer Klasse zugreifen Zur vorigen ÜberschriftZur nächsten Überschrift

Der Zugriff auf den Java-Compiler ist über die Java-Compiler-API standardisiert, jedoch sind alle Interna, wie die tatsächliche Repräsentation des Programmcodes verborgen. Die Compiler-API abstrahiert alles über Schnittstellen, und so kommen Entwickler nur mit JavaCompiler, StandardJavaFileManager und CompilationTask in Kontakt – alles Schnittstellen aus dem Paket javax.tools. Um etwas tiefer einzusteigen, lässt sich zu einem Trick greifen: Klassen implementieren Schnittstellen, und wenn ein Programm den Schnittstellentyp auf den konkreten Klassentyp anpasst, dann stehen in der Regel mehr Methoden zur Verfügung. So lässt sich der CompilationTask auf eine com.sun.tools.javac.api.JavacTaskImpl casten, und dann steht eine parse()-Methode für Verfügung. Die parse()-Methode liefert als Rückgabe eine Aufzählung von CompilationUnitTree. Damit stehen wir direkt in der internen Repräsentation, die der Compiler von einem Programmcode aufgebaut hat. Er nennt sich Abstract Syntax Tree (AST). Um diesen Baum nun abzulaufen, lässt sich das Besuchermuster einsetzen. CompilationUnitTree bietet eine accept(…)-Methode, der übergeben wir einen TreeScanner mit Callback-Methoden. Die accept(…)-Methode ruft dann beim Ablaufen jedes Knotens unseren Besucher auf:

Listing 23.3com/tutego/tools/javac/PrintAllMethodNames.java

package com.tutego.tools.javac;

import java.io.*;
import java.net.*;
import javax.tools.*;
import javax.tools.JavaCompiler.CompilationTask;
import com.sun.source.tree.*;
import com.sun.source.util.TreeScanner;
import com.sun.tools.javac.api.JavacTaskImpl;

public class PrintAllMethodNames {

final static TreeScanner<?, ?> methodPrintingTreeVisitor = new TreeScanner<Void, Void>() {
@Override public Void visitCompilationUnit( CompilationUnitTree unit, Void arg ) {
System.out.println( "Paket: " + unit.getPackageName() );
return super.visitCompilationUnit( unit, arg );
};
@Override public Void visitClass( ClassTree classTree, Void arg ) {
System.out.println( "Klasse: " + classTree.getSimpleName() );
return super.visitClass( classTree, arg );
}
@Override public Void visitMethod( MethodTree methodTree, Void arg ) {
System.out.println( "Methode: " + methodTree.getName() );
return super.visitMethod( methodTree, arg );
}
};

public static void main( String[] args ) throws IOException, URISyntaxException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = ¿
compiler.getStandardFileManager( null, null, null );
URI filename = ¿
PrintAllMethodNames.class.getResource( "PrintAllMethodNames.java" ).toURI();
Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects( new File( filename ) );
CompilationTask task = compiler.getTask( null, null, null, null, null, fileObjects );

JavacTaskImpl javacTask = (JavacTaskImpl) task;

for ( CompilationUnitTree tree : javacTask.parse() )
tree.accept( methodPrintingTreeVisitor, null );
}
}

Ein TreeScanner hat viele Methoden, wir interessieren uns nur für den Start einer Kompilationseinheit für den Paketnamen, für alle Klassen und Methoden. Wir könnten uns aber auch über alle Annotationen oder do-while-Schleifen informieren lassen. Die Ausgabe ist:

Paket: com.tutego.tools.javac
Klasse: PrintAllMethodNames
Klasse:
Methode: visitCompilationUnit
Methode: visitClass
Methode: visitMethod
Methode: main

Die zweite Angabe für den Klassennamen ist leer, da die anonyme Klasse eben keinen Namen hat.

 


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java SE 8 Standard-Bibliothek Java SE 8 Standard-Bibliothek
Jetzt Buch bestellen

 Buchempfehlungen
Zum Rheinwerk-Shop: Java ist auch eine Insel
Java ist auch eine Insel


Zum Rheinwerk-Shop: Professionell entwickeln mit Java EE 8
Professionell entwickeln mit Java EE 8


Zum Rheinwerk-Shop: Besser coden
Besser coden


Zum Rheinwerk-Shop: Entwurfsmuster
Entwurfsmuster


Zum Rheinwerk-Shop: IT-Projektmanagement
IT-Projektmanagement


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2018. Original - https://www.rheinwerk-verlag.de/openbook/
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.

 

 
 


29.09.2022 - Sitemap.xml