{"id":1069,"date":"2017-12-21T07:14:46","date_gmt":"2017-12-21T07:14:46","guid":{"rendered":"https:\/\/www.javaadvent.com\/?p=1069"},"modified":"2019-11-27T09:47:37","modified_gmt":"2019-11-27T09:47:37","slug":"javaparser-generate-analyze-modify-java-code","status":"publish","type":"post","link":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html","title":{"rendered":"JavaParser to generate, analyze and modify Java code"},"content":{"rendered":"<p>As developers we frequently look in contempt to people doing repetitive work manually.<\/p>\n<p><em>They should automate that<\/em>, we think.<\/p>\n<p>Still, we do all activities related to coding by hand. Sure, we use fancy IDEs that can perform some little refactoring for us but that is basically the end of it. We do not taste our own medicine.<\/p>\n<p>Let&#8217;s change that. Let&#8217;s see how we can write code to:<\/p>\n<ul>\n<li>Generate the boring, repetitive Java code we have to write<\/li>\n<li>Analyze our code to answer some questions about it<\/li>\n<li>Do some code processing &amp; refactoring<\/li>\n<\/ul>\n<p>The good thing is that we are going to achieve all of this with one set of libraries: JavaParser and its little brother called JavaSymbolSolver.<\/p>\n<h2>getting started<\/h2>\n<p>Well, that is an easy one: just add <a href=\"https:\/\/github.com\/javaparser\/javasymbolsolver\">JavaSymbolSolver<\/a> to your dependencies.<\/p>\n<p>What is JavaSymbolSolver? It is a library that complements <a href=\"https:\/\/github.com\/javaparser\/javaparser\">JavaParser<\/a> giving to it some pretty powerful features which are necessary to answer more complex questions about code.<\/p>\n<p>JavaSymbolSolver depends on JavaParser so you just need to add JavaSymbolSolver and Maven or Gradle will get also JavaParser for you.<\/p>\n<p>I assume you know how to use Maven or Gradle. If you don&#8217;t, stop reading this and go learn that first!<\/p>\n<h2>Generating code with javaparser<\/h2>\n<p>There are several situations in which you may want to generate Java code. For example, you could want to generate code based on some external data, like a database schema or a REST API.<\/p>\n<p>You may also want to translate some other language into Java. For example, I design DSLs for a living and while the users get to see only the DSLs I build for them I frequently generate Java behind the scenes and compile that.<\/p>\n<p>Sometimes you want just\u00a0to generate boilerplate code, like I used to dp when working with JavaEE and all those layers (who can remember how boring was to write EJB?).<\/p>\n<p>Whatever is your reason for generating code you can use JavaParser. JavaParser does not ask question, it is just there to help you.<\/p>\n<p>Let&#8217;s see how we can generate a class with two fields, a constructor and two getters. Nothing terribly advanced but it should give you a feeling of what it means to use JavaParser for code generation.<\/p>\n<pre class=\"lang:java decode:true\">CompilationUnit cu = new CompilationUnit();\n\ncu.setPackageDeclaration(\"jpexample.model\");\n\nClassOrInterfaceDeclaration book = cu.addClass(\"Book\");\nbook.addField(\"String\", \"title\");\nbook.addField(\"Person\", \"author\");\n\nbook.addConstructor(Modifier.PUBLIC)\n        .addParameter(\"String\", \"title\")\n        .addParameter(\"Person\", \"author\")\n        .setBody(new BlockStmt()\n                .addStatement(new ExpressionStmt(new AssignExpr(\n                        new FieldAccessExpr(new ThisExpr(), \"title\"),\n                        new NameExpr(\"title\"),\n                        AssignExpr.Operator.ASSIGN)))\n                .addStatement(new ExpressionStmt(new AssignExpr(\n                        new FieldAccessExpr(new ThisExpr(), \"author\"),\n                        new NameExpr(\"author\"),\n                        AssignExpr.Operator.ASSIGN))));\n\nbook.addMethod(\"getTitle\", Modifier.PUBLIC).setBody(\n        new BlockStmt().addStatement(new ReturnStmt(new NameExpr(\"title\"))));\n\nbook.addMethod(\"getAuthor\", Modifier.PUBLIC).setBody(\n        new BlockStmt().addStatement(new ReturnStmt(new NameExpr(\"author\"))));\n\nSystem.out.println(cu.toString());<\/pre>\n<p>That last instruction print your code, fresh and ready to be compiled. You may want to save the code into a file instead of printing it but you get the idea.<\/p>\n<h2>analyzing code with javaparser<\/h2>\n<p>There are many different questions you could ask about your code, many different ways to analyze it.<\/p>\n<p>First of all let&#8217;s parse all source files of our project:<\/p>\n<pre class=\"lang:java decode:true\">\/\/ Parse all source files\nSourceRoot sourceRoot = new SourceRoot(myProjectSourceDir.toPath());\nsourceRoot.setParserConfiguration(parserConfiguration);\nList&lt;ParseResult&gt; parseResults = sourceRoot.tryToParse(\"\");\n\n\/\/ Now get all compilation unitsList \nallCus = parseResults.stream()        \n        .filter(ParseResult::isSuccessful)        \n        .map(r -&gt; r.getResult().get())        \n        .collect(Collectors.toList());<\/pre>\n<p>Let&#8217;s also create a method to get all nodes of a certain type among all our compilation units:<\/p>\n<pre class=\"lang:java decode:true\">public static  List getNodes(List cus, Class nodeClass) {\n    List res = new LinkedList();\n    cus.forEach(cu -&gt; res.addAll(cu.findAll(nodeClass)));\n    return res;\n}<\/pre>\n<p>Then let&#8217;s start asking questions, like:<\/p>\n<p><i>How many methods take more than 3 parameters?<\/i><\/p>\n<pre class=\"lang:java decode:true\">long n = getNodes(allCus, MethodDeclaration.class)        .stream()        .filter(m -&gt; m.getParameters().size() &gt; 3)\n    .count();System.out.println(\"N of methods with 3+ params: \" + n);\n<\/pre>\n<p><i>What are the three top classes with most methods?<\/i><\/p>\n<pre class=\"lang:java decode:true\">getNodes(allCus, ClassOrInterfaceDeclaration.class)        .stream()        .filter(c -&gt; !c.isInterface())        .sorted(Comparator.comparingInt(o -&gt; \n        -1 * o.getMethods().size()))        .limit(3)        .forEach(c -&gt; \n        System.out.println(c.getNameAsString() + \": \" +             c.getMethods().size() + \" methods\"));\n<\/pre>\n<p>Ok, you get the idea. Now go examine your code. You do not have anything to hide, right?<\/p>\n<h2>transforming code with javaparser<\/h2>\n<p>Suppose you are the happy user of a certain library. You have added it to your dependencies years ago and used it happily ever after. Time has passed and you have used it more and more, basically all over your project.<\/p>\n<p>One day a new version of that useful library comes up and you decide you want to update your dependencies. Now, in the new library they have removed one of the methods you were using. Sure it was deprecated and it was named\u00a0<i>oldMethod<\/i>\u00a0(which could have told you something&#8230;).<\/p>\n<p>Now <em>oldMethod<\/em> has been\u00a0replaced by <i>newMethod<\/i>. The\u00a0<em>newMethod<\/em> takes 3 parameters: the first two are the same as <i>oldMethod, <\/i>they are just inverted the third one is a boolean, which should be set to\u00a0<i>true<\/i> to get the same behavior we were getting with\u00a0<em>oldMethod<\/em>.<\/p>\n<p>You have hundreds of calls to\u00a0<em>oldMethod<\/em>&#8230; are you going to change them one by one? Well, maybe, if you are charging by the hour. Or you could just use JavaParser instead.<\/p>\n<p>First let&#8217;s find all the calls to the old method in a certain file, a.k.a. <i>CompilationUnit<\/i> in JavaParser parlanse:<\/p>\n<pre class=\"lang:java decode:true\">myCompilationUnit.findAll(ethodCallExpr.class)\n        .stream()\n        .filter(m -&gt; m.resolveInvokedMethod()                \n             .getQualifiedSignature()                \n             .equals(\"foo.MyClass.oldMethod(java.lang.String, int)\"))        \n        .forEach(m -&gt; m.replace(replaceCallsToOldMethod(m)));<\/pre>\n<p>And then let&#8217;s transform the old calls in the new ones:<\/p>\n<pre class=\"lang:java decode:true\">public MethodCallExpr replaceCallsToOldMethod(MethodCallExpr methodCall) {    \n     MethodCallExpr newMethodCall = new MethodCallExpr(\n             methodCall.getScope().get(), \"newMethod\");    \n     newMethodCall.addArgument(methodCall.getArgument(1));    \n     newMethodCall.addArgument(methodCall.getArgument(0));    \n     newMethodCall.addArgument(new BooleanLiteralExpr(true));    \n     return newMethodCall;\n}<\/pre>\n<p>Cool, now we just need to get the code for our modified CompilationUnit and just save it into the Java file.<\/p>\n<p>Long life to <i>newMethod<\/i>!<\/p>\n<h2>where to find out more about javaparser<\/h2>\n<p>There are tons of features of JavaParser we have not seen:<\/p>\n<ul>\n<li>JavaParser can handle comments, figuring out to which elements they refer to<\/li>\n<li>JavaParser can do\u00a0<em>lexical preservation<\/em> or\u00a0<em>pretty printing<\/em>: your choice<\/li>\n<li>It can find out to which method declaration a method call refers to, which ancestors a certain class has, and much more thanks to the integration with JavaSymbolSolver<\/li>\n<li>It can export the AST to JSON, XML, YAML, and even generate diagrams using Graphviz!<\/li>\n<\/ul>\n<p>Where can you learn about all this stuff?<\/p>\n<p>Here there are a few resources:<\/p>\n<ul>\n<li>We wrote a book on JavaParser &amp; JavaSymbolSolver, available for free. It is named <a href=\"https:\/\/leanpub.com\/javaparservisited\">JavaParser: Visited<\/a><\/li>\n<li>The <a href=\"https:\/\/matozoid.github.io\/\">blog<\/a> of the great\u00a0<em>Matozoid<\/em>: he is the glorious maintainer of JavaParser, the unstoppable force that push a new release out every-single-week. Who knows better about JavaParser?<\/li>\n<li>My humble <a href=\"http:\/\/tomassetti.me\">blog on Language Engineering<\/a>. I am the maintainer of JavaSymbolSolver and I try to help as the second in command at JavaParser. A distant second \ud83d\ude42<\/li>\n<li>The <a href=\"http:\/\/javaparser.org\">website of the project<\/a>: not very rich in content at the moment but we are working on it<\/li>\n<li>The <a href=\"https:\/\/gitter.im\/javaparser\/javaparser?utm_source=badge&amp;utm_medium=badge&amp;utm_campaign=pr-badge&amp;utm_content=badge\">gitter channel<\/a>: do you have questions? Asked them there<\/li>\n<\/ul>\n<h2>summary<\/h2>\n<p>It is hardly the case that you can learn how to use one tool to do three different things. By learning how to use JavaParser you can analyze, generate, and modify Java code.<\/p>\n<p>Well, it feels like Christmas, doesn&#8217;t it?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As developers we frequently look in contempt to people doing repetitive work manually. They should automate that, we think. Still, we do all activities related to coding by hand. Sure, we use fancy IDEs that can perform some little refactoring for us but that is basically the end of it. We do not taste our [&hellip;]<\/p>\n","protected":false},"author":31,"featured_media":1101,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[276],"tags":[],"coauthors":[],"class_list":["post-1069","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-276"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>JavaParser to generate, analyze and modify Java code - JVM Advent<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"JavaParser to generate, analyze and modify Java code - JVM Advent\" \/>\n<meta property=\"og:description\" content=\"As developers we frequently look in contempt to people doing repetitive work manually. They should automate that, we think. Still, we do all activities related to coding by hand. Sure, we use fancy IDEs that can perform some little refactoring for us but that is basically the end of it. We do not taste our [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html\" \/>\n<meta property=\"og:site_name\" content=\"JVM Advent\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Java-Advent-Calendar-229536173843473\/\" \/>\n<meta property=\"article:published_time\" content=\"2017-12-21T07:14:46+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-27T09:47:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javaadvent.com\/content\/uploads\/2017\/12\/duke21.png\" \/>\n\t<meta property=\"og:image:width\" content=\"280\" \/>\n\t<meta property=\"og:image:height\" content=\"280\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"ftomassetti\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ftomasse\" \/>\n<meta name=\"twitter:site\" content=\"@javaadvent\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"ftomassetti\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html\"},\"author\":{\"name\":\"ftomassetti\",\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/#\\\/schema\\\/person\\\/6defe150a673e3e5a7a5506aec555d13\"},\"headline\":\"JavaParser to generate, analyze and modify Java code\",\"datePublished\":\"2017-12-21T07:14:46+00:00\",\"dateModified\":\"2019-11-27T09:47:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html\"},\"wordCount\":967,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/www.javaadvent.com\\\/content\\\/uploads\\\/2017\\\/12\\\/duke21.png?fit=280%2C280&ssl=1\",\"articleSection\":[\"2017\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html\",\"url\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html\",\"name\":\"JavaParser to generate, analyze and modify Java code - JVM Advent\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/www.javaadvent.com\\\/content\\\/uploads\\\/2017\\\/12\\\/duke21.png?fit=280%2C280&ssl=1\",\"datePublished\":\"2017-12-21T07:14:46+00:00\",\"dateModified\":\"2019-11-27T09:47:37+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/#\\\/schema\\\/person\\\/6defe150a673e3e5a7a5506aec555d13\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/www.javaadvent.com\\\/content\\\/uploads\\\/2017\\\/12\\\/duke21.png?fit=280%2C280&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/www.javaadvent.com\\\/content\\\/uploads\\\/2017\\\/12\\\/duke21.png?fit=280%2C280&ssl=1\",\"width\":280,\"height\":280},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/2017\\\/12\\\/javaparser-generate-analyze-modify-java-code.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javaadvent.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JavaParser to generate, analyze and modify Java code\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javaadvent.com\\\/\",\"name\":\"JVM Advent\",\"description\":\"The JVM Programming Advent Calendar\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javaadvent.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javaadvent.com\\\/#\\\/schema\\\/person\\\/6defe150a673e3e5a7a5506aec555d13\",\"name\":\"ftomassetti\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a1f03fedd90c6ac0321d0997f8ed82e0279eb92fa409ef6117d875919e7ac593?s=96&d=retro&r=g705d036d52aa373f2666b69307bb3efd\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a1f03fedd90c6ac0321d0997f8ed82e0279eb92fa409ef6117d875919e7ac593?s=96&d=retro&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a1f03fedd90c6ac0321d0997f8ed82e0279eb92fa409ef6117d875919e7ac593?s=96&d=retro&r=g\",\"caption\":\"ftomassetti\"},\"description\":\"I founded Strumenta, a Consulting Studio on Language Engineering. We build languages, DSLs, editors, parsers, compilers, interpreters and that sort of stuff. Before that I got a PhD, I lived in Italy, Germany, Ireland, and France, worked for TripAdvisor and Groupon, created to many projects on GitHub and contributed to JavaParser and JavaSymbolSolver.\",\"sameAs\":[\"https:\\\/\\\/tomassetti.me\",\"https:\\\/\\\/x.com\\\/ftomasse\"],\"url\":\"https:\\\/\\\/www.javaadvent.com\\\/author\\\/ftomassetti\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"JavaParser to generate, analyze and modify Java code - JVM Advent","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html","og_locale":"en_US","og_type":"article","og_title":"JavaParser to generate, analyze and modify Java code - JVM Advent","og_description":"As developers we frequently look in contempt to people doing repetitive work manually. They should automate that, we think. Still, we do all activities related to coding by hand. Sure, we use fancy IDEs that can perform some little refactoring for us but that is basically the end of it. We do not taste our [&hellip;]","og_url":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html","og_site_name":"JVM Advent","article_publisher":"https:\/\/www.facebook.com\/Java-Advent-Calendar-229536173843473\/","article_published_time":"2017-12-21T07:14:46+00:00","article_modified_time":"2019-11-27T09:47:37+00:00","og_image":[{"width":280,"height":280,"url":"https:\/\/www.javaadvent.com\/content\/uploads\/2017\/12\/duke21.png","type":"image\/png"}],"author":"ftomassetti","twitter_card":"summary_large_image","twitter_creator":"@ftomasse","twitter_site":"@javaadvent","twitter_misc":{"Written by":"ftomassetti","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html#article","isPartOf":{"@id":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html"},"author":{"name":"ftomassetti","@id":"https:\/\/www.javaadvent.com\/#\/schema\/person\/6defe150a673e3e5a7a5506aec555d13"},"headline":"JavaParser to generate, analyze and modify Java code","datePublished":"2017-12-21T07:14:46+00:00","dateModified":"2019-11-27T09:47:37+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html"},"wordCount":967,"commentCount":0,"image":{"@id":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2017\/12\/duke21.png?fit=280%2C280&ssl=1","articleSection":["2017"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html","url":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html","name":"JavaParser to generate, analyze and modify Java code - JVM Advent","isPartOf":{"@id":"https:\/\/www.javaadvent.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html#primaryimage"},"image":{"@id":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2017\/12\/duke21.png?fit=280%2C280&ssl=1","datePublished":"2017-12-21T07:14:46+00:00","dateModified":"2019-11-27T09:47:37+00:00","author":{"@id":"https:\/\/www.javaadvent.com\/#\/schema\/person\/6defe150a673e3e5a7a5506aec555d13"},"breadcrumb":{"@id":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html#primaryimage","url":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2017\/12\/duke21.png?fit=280%2C280&ssl=1","contentUrl":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2017\/12\/duke21.png?fit=280%2C280&ssl=1","width":280,"height":280},{"@type":"BreadcrumbList","@id":"https:\/\/www.javaadvent.com\/2017\/12\/javaparser-generate-analyze-modify-java-code.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javaadvent.com\/"},{"@type":"ListItem","position":2,"name":"JavaParser to generate, analyze and modify Java code"}]},{"@type":"WebSite","@id":"https:\/\/www.javaadvent.com\/#website","url":"https:\/\/www.javaadvent.com\/","name":"JVM Advent","description":"The JVM Programming Advent Calendar","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javaadvent.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.javaadvent.com\/#\/schema\/person\/6defe150a673e3e5a7a5506aec555d13","name":"ftomassetti","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a1f03fedd90c6ac0321d0997f8ed82e0279eb92fa409ef6117d875919e7ac593?s=96&d=retro&r=g705d036d52aa373f2666b69307bb3efd","url":"https:\/\/secure.gravatar.com\/avatar\/a1f03fedd90c6ac0321d0997f8ed82e0279eb92fa409ef6117d875919e7ac593?s=96&d=retro&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a1f03fedd90c6ac0321d0997f8ed82e0279eb92fa409ef6117d875919e7ac593?s=96&d=retro&r=g","caption":"ftomassetti"},"description":"I founded Strumenta, a Consulting Studio on Language Engineering. We build languages, DSLs, editors, parsers, compilers, interpreters and that sort of stuff. Before that I got a PhD, I lived in Italy, Germany, Ireland, and France, worked for TripAdvisor and Groupon, created to many projects on GitHub and contributed to JavaParser and JavaSymbolSolver.","sameAs":["https:\/\/tomassetti.me","https:\/\/x.com\/ftomasse"],"url":"https:\/\/www.javaadvent.com\/author\/ftomassetti"}]}},"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2017\/12\/duke21.png?fit=280%2C280&ssl=1","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":6132,"url":"https:\/\/www.javaadvent.com\/2025\/12\/spec-driven-development-in-practice-how-ai-simplify-full-stack-java.html","url_meta":{"origin":1069,"position":0},"title":"Spec-Driven Development in Practice: How AI Simplify Full-Stack Java","author":"Simon Martinelli","date":"December 14, 2025","format":false,"excerpt":"AI is changing how we build software, but many teams still work as if nothing has changed. They treat code as the only reliable artifact. Everything else slowly gets outdated: Requirements documents drift away from reality Diagrams do not match the current architecture Tests only cover part of the behavior\u2026","rel":"","context":"In &quot;2025&quot;","block_context":{"text":"2025","link":"https:\/\/www.javaadvent.com\/category\/2025"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-14.png?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-14.png?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-14.png?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-14.png?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":5073,"url":"https:\/\/www.javaadvent.com\/2024\/12\/the-art-of-static-code-analysis.html","url_meta":{"origin":1069,"position":1},"title":"The art of static code analysis","author":"Martin Toshev","date":"December 7, 2024","format":false,"excerpt":"The necessity for static analysis of source code ... Most Java (and not only) developers have used at minimum some sort of a static analysis tool to perform a task such as (to name a few): deriving source code metrics such as line of code or cyclomatic complexity; discovering bugs,\u2026","rel":"","context":"In &quot;2024&quot;","block_context":{"text":"2024","link":"https:\/\/www.javaadvent.com\/category\/2024"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-7.png?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-7.png?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-7.png?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-7.png?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":5689,"url":"https:\/\/www.javaadvent.com\/2024\/12\/java-migrations-argh-and-now-large-language-models.html","url_meta":{"origin":1069,"position":2},"title":"Java, migrations argh #@! and now Large Language Models","author":"Shaaf Syed","date":"December 19, 2024","format":false,"excerpt":"In today's post, let's talk about modernization, a world so fully loaded and spread out in almost every executive presentation. Well, maybe that's an over-exaggeration on my part, but it indeed feels like that. Like most of my peers, I have taken on the challenge of demystifying this word in\u2026","rel":"","context":"In &quot;2024&quot;","block_context":{"text":"2024","link":"https:\/\/www.javaadvent.com\/category\/2024"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-19.png?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-19.png?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-19.png?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-19.png?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":5926,"url":"https:\/\/www.javaadvent.com\/2025\/12\/out-with-the-old-in-with-the-new.html","url_meta":{"origin":1069,"position":3},"title":"Out with the Old, In with the New: A Guide to Application Upkeep","author":"Andres Sacco","date":"December 20, 2025","format":false,"excerpt":"Migrating an existing application to a new version of Java or a framework such as Spring Boot involves much more than simply updating a version number in a file. Each new release of a library or language brings new features, deprecations, behavioral changes, and sometimes complete API redesigns. When legacy\u2026","rel":"","context":"In &quot;2025&quot;","block_context":{"text":"2025","link":"https:\/\/www.javaadvent.com\/category\/2025"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-20.png?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-20.png?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-20.png?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-20.png?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":3585,"url":"https:\/\/www.javaadvent.com\/2022\/12\/jvm-hello-world.html","url_meta":{"origin":1069,"position":4},"title":"JVM Hello World","author":"James Hamilton","date":"December 22, 2022","format":false,"excerpt":"Writing a \"Hello World\" program is often a rite of passage for a software engineer when learning a new language. If you're a Java developer,\u00a0 you might even remember the first time you typed public static void main(String[] args) in your editor of choice. But did you ever wonder what's\u2026","rel":"","context":"In &quot;2022&quot;","block_context":{"text":"2022","link":"https:\/\/www.javaadvent.com\/category\/jvm-advent-2022"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-22.png?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-22.png?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-22.png?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.javaadvent.com\/content\/uploads\/2021\/12\/Feature-Image-Day-22.png?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":628,"url":"https:\/\/www.javaadvent.com\/2015\/12\/jit-compiler-inlining-escape-analysis.html","url_meta":{"origin":1069,"position":5},"title":"JIT Compiler, Inlining and Escape Analysis","author":"Artur Mkrtchyan","date":"December 17, 2015","format":false,"excerpt":"Just-in-time (JIT) Just-in-time (JIT) compiler is the brain of the Java Virtual Machine. Nothing in the JVM affects performance more than the JIT compiler. For a moment let's step back and see examples of compiled and non compiled languages. Languages like Go, C and C++ are called compiled languages because\u2026","rel":"","context":"In &quot;2015&quot;","block_context":{"text":"2015","link":"https:\/\/www.javaadvent.com\/category\/2015"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/posts\/1069","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/comments?post=1069"}],"version-history":[{"count":14,"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/posts\/1069\/revisions"}],"predecessor-version":[{"id":1109,"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/posts\/1069\/revisions\/1109"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/media\/1101"}],"wp:attachment":[{"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/media?parent=1069"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/categories?post=1069"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/tags?post=1069"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.javaadvent.com\/wp-json\/wp\/v2\/coauthors?post=1069"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}