{"id":2536,"date":"2013-11-16T12:42:56","date_gmt":"2013-11-16T10:42:56","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=2536"},"modified":"2013-11-16T12:42:56","modified_gmt":"2013-11-16T10:42:56","slug":"alle-neuerungen-von-java-8-ber-die-javadoc-finden","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2013\/11\/alle-neuerungen-von-java-8-ber-die-javadoc-finden\/","title":{"rendered":"Alle Neuerungen von Java 8 &uuml;ber die Javadoc finden"},"content":{"rendered":"<p>Im folgenden Beispiel wollen wir ein kleines Doclet schreiben, das Klassen, Methoden und Konstruktoren ausgibt, die das Tag @since 1.8 (bzw. @since 8, was aber eigentlich falsch ist) tragen. So l\u00e4sst sich leicht ermitteln, was in der Version Java 8 alles hinzugekommen ist. Doclets werden normalerweise von der Kommandozeile aufgerufen und dem javadoc-Tool \u00fcbergeben. Unser Programm vereinfacht das, indem es direkt das Tool \u00fcber Java mit dem passenden Parameter aufruft. tools.jar muss daf\u00fcr im Klassenpfad sein und die Dokumentation ausgepackt am angegeben Ort. <\/p>\n<pre>\npackage com.tutego.tools.javadoc;\n\nimport java.util.*;\nimport java.util.function.Predicate;\nimport com.sun.javadoc.*;\nimport com.sun.tools.javadoc.Main;\n\npublic class SinceJava8FinderDoclet {\n\n  public static boolean start( RootDoc root ) {\n    for ( ClassDoc clazz : root.classes() )\n      processClass( clazz );\n    return true;\n  }\n\n  private static void processClass( ClassDoc clazz ) {\n    Predicate&lt;Tag&gt; isJava18 = tag -> tag.text().equals( \"8\" ) || tag.text().equals( \"1.8\" );\n\n    if ( Arrays.stream( clazz.tags( \"since\" ) ).anyMatch( isJava18 ) )\n      System.out.printf( \"Neuer Typ %s%n\", clazz );\n\n    for ( MethodDoc method : clazz.methods() )\n      if ( Arrays.stream( method.tags( \"since\" ) ).anyMatch( isJava18 ) )\n        System.out.printf( \"Neue Methode %s%n\", method );\n\n    for ( ConstructorDoc constructor : clazz.constructors() )\n      if ( Arrays.stream( constructor.tags( \"since\" ) ).anyMatch( isJava18 ) )\n        System.out.printf( \"Neuer Konstruktor %s%n\", constructor );\n\n    for ( FieldDoc field : clazz.fields() )\n      if ( Arrays.stream( field.tags( \"since\" ) ).anyMatch( isJava18 ) )\n        System.out.printf( \"Neues Attribut %s%n\", field );\n  }\n\n  public static void main( String[] args ) {\n    String[] params = {\n        \"-quiet\", \"-XDignore.symbol.file\",\n        \"-doclet\", SinceJava8FinderDoclet.class.getName(),\n        \"-sourcepath\", \"C:\/Program Files\/Java\/jdk1.8.0\/src\/\",\n\/\/        \"java.lang\",  \/\/ Nur java.lang\n        \"-subpackages\", \"java:javax\"  \/\/ Alles rekursiv unter java.* und javax.*\n    };\n    Main.execute( params );\n  }\n}\n<\/pre>\n<\/p>\n<p>Unsere main(String[])-Methode ruft das JDK-Doclet-Programm \u00fcber Main.execute(String[]) auf und \u00fcbergibt die eigene Doclet-Klasse per Parameter \u2013 die Argumente von execute(String[]) erinnern an die Kommandozeilenparameter. Das Doclet-Hauptprogramm wiederum ruft unsere start(RootDoc root)-Methode auf \u2013 das Gleiche w\u00fcrde auch passieren, wenn das Doclet von au\u00dfen \u00fcber javadoc aufgerufen w\u00fcrde. Unser start(RootDoc) l\u00e4uft \u00fcber alle ermittelten Typen und \u00fcbergibt zum Abarbeiten der Innereien die Verantwortung an processClass(ClassDoc). Die Metadaten kommen dabei \u00fcber diverse XXXDoc-Typen. Ein Precidate zieht den Tag-Test heraus, ein weiterer Einsatz der neuen Java 8 Streams w\u00fcrde das Programm nicht \u00fcbersichtlicher machen.\n<\/p>\n<p>Das Programm nutzt ein paar Tricks, um die Ausgabe auf das Wesentliche zu konzentrieren. Der Schalter \u2013quit schaltet den \u00fcblichen Ladestatus, der zu Ausgaben wie\n<\/p>\n<p>Loading source files for package java.lang&#8230;\n<\/p>\n<p>Loading source files for package java.applet&#8230;\n<\/p>\n<p>Loading source files for package java.awt&#8230;\n<\/p>\n<p>f\u00fchrt ab.\n<\/p>\n<p>Der Schalter -XDignore.symbol.file wiederum unterdr\u00fcckt Meldungen wie diese hier:\n<\/p>\n<p>C:\\\u2026\\src\\java\\lang\\Class.java:57: warning: Unsafe is internal proprietary API and may be removed in a future release\n<\/p>\n<p>import sun.misc.Unsafe;\n<\/p>\n<p>^\n<\/p>\n<p>Die Meldungen landen auf dem System.err-Kanal, sodass sie sich auch mit System.setErr(\u2026) in einem ausgabeverwerfenden Strom geschickt werden k\u00f6nnen um sie zu unterdr\u00fccken.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im folgenden Beispiel wollen wir ein kleines Doclet schreiben, das Klassen, Methoden und Konstruktoren ausgibt, die das Tag @since 1.8 (bzw. @since 8, was aber eigentlich falsch ist) tragen. So l\u00e4sst sich leicht ermitteln, was in der Version Java 8 alles hinzugekommen ist. Doclets werden normalerweise von der Kommandozeile aufgerufen und dem javadoc-Tool \u00fcbergeben. Unser [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[11,66],"tags":[],"class_list":["post-2536","post","type-post","status-publish","format-standard","hentry","category-insel","category-java-8"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2536","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=2536"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2536\/revisions"}],"predecessor-version":[{"id":2537,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2536\/revisions\/2537"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=2536"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=2536"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=2536"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}