{"id":18735,"date":"2019-05-27T10:43:13","date_gmt":"2019-05-27T08:43:13","guid":{"rendered":"https:\/\/blog.trifork.com\/?p=18735"},"modified":"2019-05-27T10:43:13","modified_gmt":"2019-05-27T08:43:13","slug":"verifying-coding-standards-using-static-code-analysis-techniques","status":"publish","type":"post","link":"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/","title":{"rendered":"Verifying Coding Standards Using Static Code Analysis Techniques"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-1-300x130.png\" alt=\"\" class=\"wp-image-18739\" width=\"351\" height=\"152\" srcset=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-1-300x130.png 300w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-1-1024x442.png 1024w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-1-768x332.png 768w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-1.png 1280w\" sizes=\"auto, (max-width: 351px) 100vw, 351px\" \/><\/figure><\/div>\n\n\n\n<p>In a <a href=\"https:\/\/blog.trifork.com\/2019\/04\/25\/unit-testing-source-code-verifying-axon-event-upcaster-consistency\/\">previous blog<\/a> we described how we used JUnit and Reflection to verify correct implementation of coding standards addressing Axon Upcaster consistency. We concluded that, although possible, it felt a bit like a hack because we had to change modifiers of Java variables defined as \u201cprivate static final\u201d resulting in Java security manager warnings. We also promised to get back to the subject, this time using static code analysis technology as found in e.g. <a href=\"https:\/\/www.sonarqube.org\/\">SonarQube<\/a>.<br \/><\/p>\n\n\n\n<p>Before we present our solution we recap the case at hand and we will of course close with a comparison and draw some conclusions.<br \/><\/p>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>Source code consistency<\/strong><\/h1>\n\n\n\n<p>The system we were building in my project is using the Axon framework <a href=\"https:\/\/axoniq.io\">(Axon Framework)<\/a> . In Axon all events in the system end up in an event store to be used for event sourcing later. We for example defined \u201cPersons\u201d and \u201cOrganisations\u201d where Persons work for Organisations. During development such entities <em>evolve<\/em>, for example, they get a new property. Events such as \u201cOrganisationUpdated\u201d therefore become <em>versioned<\/em>. When new versions, in Axon terms <em>revisions<\/em>, contain new properties we have older events in our event store without those properties. This is a problem if the new property is mandatory. In Axon terminology they need to be <em>upcasted<\/em> by Java classes called Upcasters to allow for event replaying. Over time there will be several upcasters taking an event first from revision 0 to revision 1, then from 1 to 2 and so on until we reach the current one. <br \/><\/p>\n\n\n\n<p>In our project we introduced a generic way of managing upcasters and we introduced a coding standard for it as follows. We have an event in Kotlin defining the current revision like this:<br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Revision(\"4\")\ndata class OrganisationUpdatedEvent(val id: String, val\n name: String, \u2026\n<\/pre><\/div>\n\n\n<p>Next we have a series of upcasters where the name immediately tells what it does, like:<br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nOrganisationUpdatedEventUpcasterNullTo1.java\n<\/pre><\/div>\n\n\n<p>And<br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nOrganisationUpdatedEventUpcaster1To2.java \n<\/pre><\/div>\n\n\n<p>Next, each of these upcasters contains code like this:<br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nprivate static final SimpleSerializedType INPUT = new\n\t  SimpleSerializedType(\n\t\tOrganisationUpdatedEvent.class.getName(), \"1\");\nprivate static final SimpleSerializedType OUTPUT = new\n\t  SimpleSerializedType(\n\t\tOrganisationUpdatedEvent.class.getName(), \"2\");\n\n<\/pre><\/div>\n\n\n<p>Upcasters use this information to \u201crecognize\u201d if a particular revision of an event can be upcasted. Finally upcasters are Spring Components requiring a particular ordering, so we have code like this:<br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Component\n@Order(1)\npublic class OrganisationUpdatedEventUpcaster1To2\n<\/pre><\/div>\n\n\n<p>We need this ordering because Axon runs all events through a list of all upcasters it knows about at event replay time. Axon does not impose anything in terms of ordering on that list, but we want to apply upcaster \u201c\u2026NullTo1\u201d before \u201c\u20261To2\u201d etc. Managing Axon upcasters over time will be another blog post, as there are a couple of alternative implementations all with different pros and cons. <br \/><\/p>\n\n\n\n<p>Let us get back to our current subject. To summarize, in our coding standard we have:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The current revision in an annotation on an event (e.g. \u201c@Revision(<strong>&#8220;4&#8221;<\/strong>)\u201d)<\/li><li>A series of classes with a particular name (e.g. \u2026NullTo1, \u20261To2, \u2026.)<\/li><li>Per upcaster an INPUT and OUTPUT revision (e.g. <strong>&#8220;1&#8221; <\/strong>and <strong>&#8220;2&#8221;<\/strong>)<\/li><li>The previous revision in an annotation on an upcaster (e.g. @Order(1))<\/li><\/ul>\n\n\n\n<p>Given an event with a Revision \u201c4\u201d this implies:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>There should be 4 upcasters<\/li><li>The name of each upcaster (OrganisationUpdatedEventUpcaster1To2) contains 2 revisions that should match values specified in INPUT (1) and OUTPUT (2) constants<\/li><li>Likewise, the name of each upcaster (OrganisationUpdatedEventUpcaster1To2) contains the TypeName used in INPUT and OUTPUT (OrganisationUpdatedEvent)<\/li><li>The value in the \u201c@Order\u201d annotation should equal the revision used in the INPUT (1)<\/li><\/ul>\n\n\n\n<p>Now how do we know this standard is properly implemented? A static analysis test would add value to catch mistakes that are easily made and easily overlooked at review time such as copy-paste errors:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Forgetting to change the type in INPUT and OUTPUT constants<\/li><li>Forgetting to update the @Order annotation<\/li><\/ul>\n\n\n\n<p>And other errors like omitting the upcaster in the first place.<br \/><\/p>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>Static code analysis<\/strong><\/h1>\n\n\n\n<p>One of the best-known tools in the area of static code analysis is <a href=\"https:\/\/www.sonarqube.org\/\">SonarQube<\/a>. It catches potential bugs, reports on code coverage, analyses complexity and the like. As SonarQube is easily extensible we looked at it for implementing a so-called CustomRule verifying our coding standard. &nbsp;This appeared harder than expected for two reasons:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SonarQube uses plugins per language<\/li><li>SonarQube \u201cunit of analysis\u201d is a single file<\/li><\/ul>\n\n\n\n<p>Let us elaborate on these two before we explain in detail how SonarQube rules work.<br \/><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>SonarQube uses plugins per language<\/strong><\/h2>\n\n\n\n<p>The first hoop we have to jump through is the fact that we have both Kotlin as well as Java source code. SonarQube supports Java since ages but for Kotlin we need to look at other solutions. In the end we used parts of <a href=\"https:\/\/arturbosch.github.io\/detekt\/\">Detekt<\/a>. But we probably could have used other solutions as well. The problem is that adding a CustomRule to the Java plugin is unnatural, as it can\u2019t understand Kotlin files and vice versa.<br \/><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>SonarQube\u2019s \u201cunit of analysis\u201d is a single file<\/strong><\/h2>\n\n\n\n<p>SonarQube takes a path that points at some directory and then recursively analyses each relevant file on a per file basis. So here is the second hoop to jump through: information from a single Kotlin file (the current revision in an annotation on an event) needs to be combined with information coming from <em>several<\/em> Java files.<br \/><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>How SonarQube rules work<\/strong><\/h2>\n\n\n\n<p>A SonarQube rule basically defines a set of tree types we are interested in and a visitor in which we examine the tree and possibly produce errors and warnings. For example, to verify a maximum number of parameters in a method we say we are interested in Java methods. In a visitor we get each method, count the number of parameters and produce an error or a warning when the count exceeds a particular value.<br \/><\/p>\n\n\n\n<p>Key to observe here is that the visitor gets <em>trees<\/em>. &nbsp;These are sub-trees of the Abstract Syntax Tree derived by parsing the source code file.<br \/><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Statically deriving information from Upcaster (java) files<\/strong><\/h2>\n\n\n\n<p>As said upcasters are Java files and we need to obtain information from an annotation (@Order) and from two variables (INPUT and OUTPUT). &nbsp;Our CustomRule becomes:<br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class UpcasterInformationRule extends\n\t\tIssuableSubscriptionVisitor {\n<\/pre><\/div>\n\n\n<p>With: <br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Override\npublic List&lt;Tree.Kind&gt; nodesToVisit() {\n  return ImmutableList.of(\n\t\tTree.Kind.VARIABLE,\n\t\tTree.Kind.ANNOTATION);\n}\n<\/pre><\/div>\n\n\n<p>And:<br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Override\npublic void visitNode(Tree tree) {\n  if (tree instanceof VariableTree) {\n    VariableTree variableTree = (VariableTree)tree;\n    \u2026\n   } else if (tree instanceof AnnotationTree) {\n    AnnotationTree annotationTree = (AnnotationTree)tree;\n    \u2026\n   }\n}\n<\/pre><\/div>\n\n\n<p>Cool. Now we need to look inside the variableTree and inside the annotationTree to obtain the information we are after. The latter is simpler so let us start with that one to get the hang of it. The annotationTree in our case is shown in Figure 1.<br \/><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/tii6EjORjpKNpU6HEWDeESzb9sX-TquAgC7baKvs975DLjsDDrkWYKJ3NxDdz7px8FKdR4acFmXd4nETcaw2YlV4OwWXaFb9gMbgCWT5tCkSZxW-WevdQdgD5Fngr4zuRO3kl6k87NhsKhGbDw\" alt=\"\" \/><\/figure>\n\n\n\n<p><strong>Figure 1. <\/strong>Abstract Syntax Tree representation of \u201c<strong>@Order<\/strong><strong>(<\/strong><strong>1<\/strong><strong>)<\/strong>\u201d.<\/p>\n\n\n\n<p>To verify we have an Annotation with name \u201cOrder\u201d and then derive its value (1) we get, given the annotationTree:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nIdentifierTree identifierTree = (IdentifierTree)\n  annotationTree.annotationType();\nif (identifierTree.name().equals(\"Order\")) {\n  Arguments arguments = annotationTree.arguments();\n  LiteralTree literalTree = (LiteralTree)arguments.get(0);\n  valueOfOrderAnnotation = literalTree.value();\n}\n<\/pre><\/div>\n\n\n<p>Getting the values of the INPUT and OUTPUT variables is more complicated. Let us first show the tree representation of the INPUT variable declaration in Figure 2.<br \/><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/UeATE8qh3WjZZR9jbUA6F_MDA6Z6JqMXd1Fd8D6butxxb_fG8l2sEro528oXzH6TOR7dVBVBr6k2zZv9472uTh619ABLI9cdjEgq8pLp-K-6a2YvQJmqjiY4Jw2XqLKLF8GAZo164gs5MUOQfw\" alt=\"\" \/><\/figure>\n\n\n\n<p><strong>Figure 2. <\/strong>Abstract Syntax Tree representation of variable declaration \u201cINPUT\u201d.<\/p>\n\n\n\n<p>To derive the name of the event and the revision value give the variableTree we now get:<br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nif (variableTree.simpleName().name().equals(\"INPUT\")) {\n  inputInfo = getEventAndRevision(variableTree);\n}\n<\/pre><\/div>\n\n\n<p>And:<br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nprivate EventAndRevision getEventAndRevision(\n     VariableTree variableTree) {\n  NewClassTree newClass =\n    (NewClassTree) variableTree.initializer();\n  if (((IdentifierTree) newClass.identifier()).name()\n        .equals(\"SimpleSerializedType\")) {\n    \/\/ get the name of the event from argument 0\n    Arguments arguments = newClass.arguments();\n    MethodInvocationTree zero = (MethodInvocationTree)\n       arguments.get(0);\n    MemberSelectExpressionTree expressionTree =\n       (MemberSelectExpressionTree) zero.methodSelect();\n    MemberSelectExpressionTree child = (MemberSelectExpressionTree) expressionTree.expression();\n    IdentifierTree id = (IdentifierTree) child.expression();\n    String eventName = id.name();\n\n    \/\/ now get the revision value from argument 1\n    LiteralTree value = (LiteralTree) arguments.get(1);\n    String revision = value.value();\n    return new EventAndRevision(eventName, revision);\n  }\n  return null;\n}\n<\/pre><\/div>\n\n\n<p>To draw an early conclusion, that was quite a bit of coding. Figuring out how to traverse the variableTree is also cumbersome, as up front we do not have any idea about the tree shape and the types involved.<br \/><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Statically deriving information from Event (Kotlin) files<\/strong><\/h2>\n\n\n\n<p>Above we showed how to obtain information from a Java file, so here is its peer for handling Kotlin files. Recall we have an event like this:<br \/><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Revision(\"4\")\ndata class OrganisationUpdatedEvent(val id: String, val\n     name: String, \u2026\n<\/pre><\/div>\n\n\n<p>And we need to obtain the value \u201c4\u201d from the Revision annotation. The tree representation is shown in Figure 3.<br \/><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/ZErRG6rUHw7LLDp3m0jIQrYkp1NI0xFwWRlBtoVbMff-DSEQ68j01s5LP3ymJO8vvi8hFkDS-4QPGf-DFLJal84S334VQRzCYiQsuf0fNI24SgHHjhaiaidiRDvI7FKhrFpRjpfzsJSTAWixyQ\" alt=\"\" \/><\/figure>\n\n\n\n<p><strong>Figure 3.<\/strong><strong> <\/strong>Abstract Syntax Tree representation of an annotated constructor.<\/p>\n\n\n\n<p>The code to obtain the value of the revision annotation looks like this.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nKtCompiler ktCompiler = new KtCompiler();\nPath path = new File(&quot;src\/test\/files&quot;).toPath();\nKtFile ktFile = ktCompiler.compile(path, path.resolve(&quot;events.kt&quot;));\n\nList&lt;KtClass&gt; constructors =\n  PsiTreeUtil.getChildrenOfTypeAsList(ktFile, KtClass.class);\nfor (KtClass constructor : constructors) {\n  if (constructor.getAnnotationEntries().size() &gt; 0) {\n    KtAnnotationEntry annotationEntry =\n      constructor.getAnnotationEntries().get(0);\n    String perhapsRevision = annotationEntry.getShortName().asString();\n    if (perhapsRevision.equals(&quot;Revision&quot;)) {\n      KtValueArgumentList revisionArgList =\n        (KtValueArgumentList) annotationEntry.\n          getChildren()&#x5B;1];\n      String revisionValue = revisionArgList.\n        getArguments().get(0).getText();\n\u2026\n    }\n  }\n}\n<\/pre><\/div>\n\n\n<p>Here we have used KtCompiler from Detekt. All other types such as KtClass, KtFile etc are from the \u201corg.jetbrains.kotlin.psi\u201d package. The PsiTreeUtil is from IntelliJ package \u201corg.jetbrains.kotlin.com.intellij.psi.util\u201d.<br \/><\/p>\n\n\n\n<p>The careful reader may notice a slight mismatch between the tree from Figure 3 and the code above. The code uses some shortcuts by using \u201cgetText\u201d; that is, the textual representation of a tree as it saves some tree walking.<br \/><\/p>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>Comparison and Conclusion<\/strong><\/h1>\n\n\n\n<p>For our use case, verifying a coding standard for Axon upcasters, our first implementation used JUnit and Reflection. It felt a bit hacky, especially because obtaining information from constants is bound to break in the future when security managers will no longer allow changing modifiers of Java variables defined as \u201cprivate static final\u201d. Our second implementation based on SonarQube style parsing and tree analysis can in our opinion also not be qualified as \u201cperfect\u201d. It works, but as we have seen above it is quite tedious and calls for usage of the third party library Detekt.<br \/><\/p>\n\n\n\n<p>Concluding, we prefer the JUnit\/Reflection approach for our use case mainly because it uses already compiled code and thus does not rely on parsing which may fail. In general however, in cases where more complexity is involved we feel static code analysis is the only way to get the job done.<br \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a previous blog we described how we used JUnit and Reflection to verify correct implementation of coding standards addressing Axon Upcaster consistency. We concluded that, although possible, it felt a bit like a hack because we had to change modifiers of Java variables defined as \u201cprivate static final\u201d resulting in Java security manager warnings. [&hellip;]<\/p>\n","protected":false},"author":121,"featured_media":18828,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[81,10],"tags":[80,11,143,466,289],"class_list":["post-18735","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-axon-framework","category-development","tag-axon-framework","tag-java","tag-junit","tag-kotlin","tag-upcasting"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Verifying Coding Standards Using Static Code Analysis Techniques - Trifork Blog<\/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:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Verifying Coding Standards Using Static Code Analysis Techniques - Trifork Blog\" \/>\n<meta property=\"og:description\" content=\"In a previous blog we described how we used JUnit and Reflection to verify correct implementation of coding standards addressing Axon Upcaster consistency. We concluded that, although possible, it felt a bit like a hack because we had to change modifiers of Java variables defined as \u201cprivate static final\u201d resulting in Java security manager warnings. [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/\" \/>\n<meta property=\"og:site_name\" content=\"Trifork Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-05-27T08:43:13+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-5.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2538\" \/>\n\t<meta property=\"og:image:height\" content=\"942\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Wilco Koorn\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wilco Koorn\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/\",\"url\":\"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/\",\"name\":\"Verifying Coding Standards Using Static Code Analysis Techniques - Trifork Blog\",\"isPartOf\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-5.png\",\"datePublished\":\"2019-05-27T08:43:13+00:00\",\"author\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/66efcb420662bc45e623c0f9368b91df\"},\"breadcrumb\":{\"@id\":\"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/#primaryimage\",\"url\":\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-5.png\",\"contentUrl\":\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-5.png\",\"width\":2538,\"height\":942},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/trifork.nl\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Verifying Coding Standards Using Static Code Analysis Techniques\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/trifork.nl\/blog\/#website\",\"url\":\"https:\/\/trifork.nl\/blog\/\",\"name\":\"Trifork Blog\",\"description\":\"Keep updated on the technical solutions Trifork is working on!\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/trifork.nl\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/66efcb420662bc45e623c0f9368b91df\",\"name\":\"Wilco Koorn\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a61a60b2bf91009cbb3f74505ec8e43b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a61a60b2bf91009cbb3f74505ec8e43b?s=96&d=mm&r=g\",\"caption\":\"Wilco Koorn\"},\"url\":\"https:\/\/trifork.nl\/blog\/author\/wilcok\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Verifying Coding Standards Using Static Code Analysis Techniques - Trifork Blog","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:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/","og_locale":"en_US","og_type":"article","og_title":"Verifying Coding Standards Using Static Code Analysis Techniques - Trifork Blog","og_description":"In a previous blog we described how we used JUnit and Reflection to verify correct implementation of coding standards addressing Axon Upcaster consistency. We concluded that, although possible, it felt a bit like a hack because we had to change modifiers of Java variables defined as \u201cprivate static final\u201d resulting in Java security manager warnings. [&hellip;]","og_url":"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/","og_site_name":"Trifork Blog","article_published_time":"2019-05-27T08:43:13+00:00","og_image":[{"width":2538,"height":942,"url":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-5.png","type":"image\/png"}],"author":"Wilco Koorn","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wilco Koorn","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/","url":"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/","name":"Verifying Coding Standards Using Static Code Analysis Techniques - Trifork Blog","isPartOf":{"@id":"https:\/\/trifork.nl\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/#primaryimage"},"image":{"@id":"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/#primaryimage"},"thumbnailUrl":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-5.png","datePublished":"2019-05-27T08:43:13+00:00","author":{"@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/66efcb420662bc45e623c0f9368b91df"},"breadcrumb":{"@id":"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/#primaryimage","url":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-5.png","contentUrl":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2019\/05\/Screenshot-2019-05-16-at-14.27.18-5.png","width":2538,"height":942},{"@type":"BreadcrumbList","@id":"https:\/\/trifork.nl\/blog\/verifying-coding-standards-using-static-code-analysis-techniques\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/trifork.nl\/blog\/"},{"@type":"ListItem","position":2,"name":"Verifying Coding Standards Using Static Code Analysis Techniques"}]},{"@type":"WebSite","@id":"https:\/\/trifork.nl\/blog\/#website","url":"https:\/\/trifork.nl\/blog\/","name":"Trifork Blog","description":"Keep updated on the technical solutions Trifork is working on!","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/trifork.nl\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/66efcb420662bc45e623c0f9368b91df","name":"Wilco Koorn","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a61a60b2bf91009cbb3f74505ec8e43b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a61a60b2bf91009cbb3f74505ec8e43b?s=96&d=mm&r=g","caption":"Wilco Koorn"},"url":"https:\/\/trifork.nl\/blog\/author\/wilcok\/"}]}},"_links":{"self":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/18735","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/users\/121"}],"replies":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/comments?post=18735"}],"version-history":[{"count":0,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/18735\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media\/18828"}],"wp:attachment":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media?parent=18735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/categories?post=18735"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/tags?post=18735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}