{"id":290,"date":"2009-04-13T22:16:00","date_gmt":"2009-04-13T22:16:00","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=290"},"modified":"2012-07-29T12:18:52","modified_gmt":"2012-07-29T10:18:52","slug":"projekte-und-pakete-aus-den-langtools","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2009\/04\/projekte-und-pakete-aus-den-langtools\/","title":{"rendered":"Projekte und Pakete aus den langtools"},"content":{"rendered":"<p>Achtung! Nur g\u00fcltig in f\u00fcr JDK 6, in JDK 7 gibt es Umbenennungen.<\/p>\n<p>Die langtools von Java sind die bekannten Kommandozeilenprogramme wie javac, jar, javap, \u2026 Die Quellen kann man sich zum Beispiel aus dem <a href=\"http:\/\/www.selenic.com\/mercurial\/wiki\/\">Mercurial<\/a> Repository holen. F\u00fcr Java 6 liefert <a title=\"http:\/\/hg.openjdk.java.net\/jdk6\/jdk6\/langtools\/\" href=\"http:\/\/hg.openjdk.java.net\/jdk6\/jdk6\/langtools\/\">http:\/\/hg.openjdk.java.net\/jdk6\/jdk6\/langtools\/<\/a> den Zugriff auf die Sourcen. Sie lassen sich auch in einem Rutsch (<a title=\"zip\" href=\"http:\/\/hg.openjdk.java.net\/jdk6\/jdk6\/langtools\/archive\/tip.zip\">zip<\/a>) beziehen. Im Verzeichis src\/share\/classes beginnen die Pakete:<\/p>\n<ul>\n<li><strong>com.sun.javadoc<\/strong>. Die Java Doclet-API, also nur Schnittstellen etwa um Pakete, Variablen oder Typen zu beschreiben<\/li>\n<li><strong>com.sun.mirror<\/strong>. Mirror API repr\u00e4sentiert Konstrukte eines Java-Programms wie Klassen, Modifizierer. Anweisungen und Ausdr\u00fccke werden nicht repr\u00e4sentiert. Wird in Java 7 verschwinden, denn dort gibt es mit <strong>javax.lang.model<\/strong> (seit Java 6) einen Ersatz. Die Mirror API wurde in Java 5 f\u00fcr das APT eingef\u00fchrt, aber nie standardisiert<\/li>\n<li><strong>com.sun.source.tree<\/strong>. Repr\u00e4sentiert den AST (abstract syntax trees) eines Java-Programms vom Java-Compiler. <strong>com.sun.source.util<\/strong>. Utility-Klassen f\u00fcr den AST<\/li>\n<li><strong>javax.annotation.processing<\/strong>. Um Annotation-Prozessoren zu beschreiben<\/li>\n<li><strong>javax.lang.model.Element<\/strong>, <strong>javax.lang.model.type<\/strong>, <strong>javax.lang.model.util<\/strong>. Deklarationen, f\u00fcr Typen, die Meta-Daten aus einem Java-Programm beschreiben, etwa Modifizierer oder Generics-Typen. In erster Linie f\u00fcr APT<\/li>\n<li><strong>com.sun.tools.apt.*<\/strong>. Annotation Processing Tool (apt). Greift auf <strong>javax.lang.model<\/strong> zur\u00fcck<\/li>\n<li><strong>com.sun.tools.doclets.internal.toolkit<\/strong>. Implementierung des Standard-Doclets<\/li>\n<li><strong>com.sun.tools.javadoc<\/strong>. Implementierung des Schnittstellen aus <strong>com.sun.javadoc<\/strong><\/li>\n<li><strong>com.sun.tools.javac.*<\/strong>. Java-Compiler<\/li>\n<li><strong>com.sun.tools.javah<\/strong>. C Header and Stub File Generator<\/li>\n<li><strong>sun.tools.javap<\/strong>. Der Java Class File Disassembler.<\/li>\n<\/ul>\n<p>Wenn man ein Beispiel programmieren m\u00f6chte, muss man <em>tools.jar<\/em> in den Klassenpfad aufnehmen. Dann kann man schon loslegen. So nutzt folgendes Programm die Datenstrukturen von javap, und ist somit der Java-Quellcode-Gegenspieler von Reflection.<\/p>\n<pre class=\"prettyprint\">import java.io.*; \r\nimport sun.tools.javap.*;\r\npublic class MyJavap \r\n{ \r\n  static String filename = \"bin\/MyJavap.class\";\r\n  public static void main( String[] args ) throws FileNotFoundException \r\n  { \r\n    ClassData classData = new ClassData( new FileInputStream( filename ) );\r\n    for ( FieldData field : classData.getFields() )\r\n       System.out.println( field.getType() + \" \" + field.getName() );\r\n    for ( MethodData method : classData.getMethods() )\r\n      System.out.println( method.getName() + method.getParameters() ); \r\n  } \r\n}<\/pre>\n<p>Ausgabe:<\/p>\n<pre>java.lang.String filename \r\n&lt;clinit&gt;() \r\n&lt;init&gt;() \r\nmain(java.lang.String[])<\/pre>\n<p>Die API um Programmcode zu beschreiben ist komplizierter. Folgendes Programm baut einen internen Baum auf und l\u00e4sst ihn \u00fcber die komfortablen print()-Funktionen ausgeben:<\/p>\n<pre class=\"prettyprint\">import javax.tools.DiagnosticCollector; \r\nimport javax.tools.JavaCompiler; \r\nimport javax.tools.JavaFileManager; \r\nimport javax.tools.JavaFileObject; \r\nimport javax.tools.StandardJavaFileManager; \r\nimport javax.tools.ToolProvider;\r\nimport com.sun.tools.javac.code.Flags; \r\nimport com.sun.tools.javac.code.TypeTags; \r\nimport com.sun.tools.javac.tree.JCTree; \r\nimport com.sun.tools.javac.tree.TreeMaker; \r\nimport com.sun.tools.javac.tree.JCTree.JCAnnotation; \r\nimport com.sun.tools.javac.tree.JCTree.JCBlock; \r\nimport com.sun.tools.javac.tree.JCTree.JCClassDecl; \r\nimport com.sun.tools.javac.tree.JCTree.JCCompilationUnit; \r\nimport com.sun.tools.javac.tree.JCTree.JCExpression; \r\nimport com.sun.tools.javac.tree.JCTree.JCModifiers; \r\nimport com.sun.tools.javac.tree.JCTree.JCStatement; \r\nimport com.sun.tools.javac.tree.JCTree.JCTypeParameter; \r\nimport com.sun.tools.javac.tree.JCTree.JCVariableDecl; \r\nimport com.sun.tools.javac.util.Context; \r\nimport com.sun.tools.javac.util.List; \r\nimport com.sun.tools.javac.util.ListBuffer; \r\nimport com.sun.tools.javac.util.Name; \r\nimport com.sun.tools.javac.util.Name.Table;\r\npublic class BuildSomeCode \r\n{ \r\n  public static void main( String[] args ) \r\n  { \r\n    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); \r\n    DiagnosticCollector&lt;JavaFileObject&gt; diagnostics = new DiagnosticCollector&lt;JavaFileObject&gt;(); \r\n    StandardJavaFileManager fm = compiler.getStandardFileManager( diagnostics, null, null );\r\n    Context context = new Context(); \r\n    context.put( JavaFileManager.class, fm );\r\n    TreeMaker maker = TreeMaker.instance( context ); \r\n    Table table = new Table();\r\n    ListBuffer&lt;JCTree&gt; methods = new ListBuffer&lt;JCTree&gt;();\r\n    JCModifiers mmods = maker.Modifiers( Flags.PUBLIC | Flags.STATIC ); \r\n    Name mname = Name.fromString( table, \"test\" ); \r\n    JCExpression retType = maker.TypeIdent( TypeTags.VOID ); \r\n    ListBuffer&lt;JCVariableDecl&gt; params = new ListBuffer&lt;JCVariableDecl&gt;(); \r\n    ListBuffer&lt;JCStatement&gt; stmts = new ListBuffer&lt;JCStatement&gt;(); \r\n    JCBlock methodBody = maker.Block( 0, stmts.toList() ); \r\n    methods.append( maker.MethodDef( mmods, mname, retType, List.&lt;JCTypeParameter&gt; nil(), \r\n                                     params.toList(), List.&lt;JCExpression&gt; nil(), methodBody, null ) );\r\n    JCModifiers cmods = maker.Modifiers( Flags.PUBLIC ); \r\n    Name cname = Name.fromString( table, \"Test\" ); \r\n    JCClassDecl classDef = maker.ClassDef( cmods, cname, List.&lt;JCTypeParameter&gt; nil(), null, \r\n                                           List.&lt;JCExpression&gt; nil(), methods.toList() );\r\n    ListBuffer&lt;JCTree&gt; classDefs = new ListBuffer&lt;JCTree&gt;(); \r\n    classDefs.append( classDef );\r\n    JCCompilationUnit compilationUnit = maker.TopLevel( List.&lt;JCAnnotation&gt; nil(), null, \r\n                                                        classDefs.toList() );\r\n    System.out.println( compilationUnit ); \r\n  } \r\n}<\/pre>\n<p>Das ergibt:<\/p>\n<pre class=\"prettyprint\">public class Test { \r\n    public static void test() { \r\n    } \r\n}<\/pre>\n<p>Zum Weiterlesen:<\/p>\n<ul>\n<li><a title=\"http:\/\/javadots.blogspot.com\/2006\/11\/javac-internals.html\" href=\"http:\/\/javadots.blogspot.com\/2006\/11\/javac-internals.html\">http:\/\/javadots.blogspot.com\/2006\/11\/javac-internals.html<\/a><\/li>\n<li><a title=\"http:\/\/www.ahristov.com\/tutorial\/java-compiler.html\" href=\"http:\/\/www.ahristov.com\/tutorial\/java-compiler.html\">http:\/\/www.ahristov.com\/tutorial\/java-compiler.html<\/a><\/li>\n<li><a title=\"http:\/\/www.cs.ucla.edu\/~smarkstr\/javacop\/docs\/ASTQuickReference.pdf\" href=\"http:\/\/www.cs.ucla.edu\/~smarkstr\/javacop\/docs\/ASTQuickReference.pdf\">http:\/\/www.cs.ucla.edu\/~smarkstr\/javacop\/docs\/ASTQuickReference.pdf<\/a><\/li>\n<li><a title=\"http:\/\/blogs.sun.com\/yj\/entry\/yet_another_way_to_hack\" href=\"http:\/\/blogs.sun.com\/yj\/entry\/yet_another_way_to_hack\">http:\/\/blogs.sun.com\/yj\/entry\/yet_another_way_to_hack<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Achtung! Nur g\u00fcltig in f\u00fcr JDK 6, in JDK 7 gibt es Umbenennungen. Die langtools von Java sind die bekannten Kommandozeilenprogramme wie javac, jar, javap, \u2026 Die Quellen kann man sich zum Beispiel aus dem Mercurial Repository holen. F\u00fcr Java 6 liefert http:\/\/hg.openjdk.java.net\/jdk6\/jdk6\/langtools\/ den Zugriff auf die Sourcen. Sie lassen sich auch in einem Rutsch [&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":[1],"tags":[],"class_list":["post-290","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/290","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=290"}],"version-history":[{"count":4,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/290\/revisions"}],"predecessor-version":[{"id":552,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/290\/revisions\/552"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=290"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=290"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=290"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}