Skip to content

Lab 08

In this lab session you will practice basic Linter and abstract code analysis tools, and how to efficiently use them as IntelliJ or Maven plugin. In this lab session you will be working with the BookStore code.

Checkstyle

Checkstyle is a classic linter, that is, it ensures that code respects coding conventions, e.g. those of a company.

IDE based scans

  • Access Moodle and watch the setup instructions for the checkstyle plugin.
  • After login, the video capsule is available in folder 08

Your turn

  • Clone the BookStore project: git clone https://github.com/m5c/BookStoreInternals/
  • Open the clones project in IntelliJ
  • Inspect the project, you should find a file google_checks.xml
  • Create a checkstyle report, i.e. install the checkstyle plugin, manually select google checks and let it run over all classes and inspect the report.
  • Introduce a checkstyle error, e.g. by adding a linebreak before a method name
  • Run checkstyle again and verify it provides a warning message for the modified line

IDE based formatting

  • Manual formatting corrections are slow and tedious.
  • Revise the checkstyle video capsule and revise how to configure IntelliJ to use google_checks.xml as formatting configuration.

Your turn

  • Configure your IntelliJ to use google_checks.xml as formatting configuration.
  • Add again some formatting issues to any java file in the BookStore, e.g. by adding linebreaks or changing indentation.
  • Open the IntelliJ key combo reference chart (Also available in Help -> Keyboard Shortcuts PDF)
    • Find the key combo to format code
    • Use the keycombo to format code
  • You can add the Shift key to the combo, to get an additional formatting menu, make sure all "Options" boxes are checked:
  • Verify you can fix all checkstyle problems in a file using the key combo.

Maven checkstyle plugin

  • Checkstyle is not only an IDE plugin, but also a maven plugin.
  • Adding checkstyle as maven plugin is as simple as adding the plugin to the pom.xml configuration file.
Why is the maven plugin preferable over the IDE plugin ?

IDE plugins are up to the developer to use or ignore. But even if all developers care for code quality, one can easily forget to run a plugin before sharing new code. A maven plugin is a lot harder to ignore, especially if configured to systematically reject insufficiently commented or linted code.

Your turn

  • Inspect the BookStores, pom.xml. Can you identify where the plugin has been added ?
  • Once more change a java file of the BookStore project, such as indentation or some linebreaks.
  • Run mvn clean package. The build should fail.
  • Carefully inspect the output. Do the maven errors match the lines you just changed ?
  • Use the intelliJ format keycombo to format your code again.
  • Rebuild, using mvn clean package. Verify the project can now be built.

Complexity

In class, I've briefly mentioned another code metric: Complexity.

Complexity IDE plugin

  • The complexity IDE plugin gives you immediate feedback on complexity of your code.
  • For each method, the plugin adds a short percentage number and qualitative complexity estimation.

Your turn

  • Install the Code complexity plugin
  • Restart your IDE
  • Add the following method to any class of your BookStore project:
      public static boolean test(int input) {
      int x = -1;
      boolean[] yyy = new boolean[input];
      while (!(x > input - 2)) {
        if (input % (x + 2) == 0) {
          yyy[x + 1] = true;
          if(input == -1) {
            return false;
          }
        } else {
          yyy[x + 1] = !true;
        }
        x++;
      }
      for (int k = input - 2; k >= 1; k--) {
        if (yyy[k] == true) {
          return false;
        }
      }
      return true;
    }
    
  • Locate where the complexity plugin gives you feedback.
What causes the feedback 125%, mildly complex

There are different complexity metrics. The complexity plugin assesses based on Cognitive Complexity, a metric evaluating how difficult code is to understand. The more if/else statements or possible execution paths the more complex is the method. Note that variable naming has no effect.

  • Inspect various methods of your Halma implementation and see if you have any that are considered "very complex".
  • Apply refactoring techniques presented in the previous lab, and improve the complexity rating of your Halma methods.

Bonus: PMD

PMD (Project Meets Deadline) is probably the most notorious java static code analyzer of them all.

  • PMD provides wide freedom of configuration, from detecting poor coding, to missing documentation, to spotting severe security or performance flaws.
  • PMD is available as IDE plugin and Maven plugin.

Configuration

Add the following plugin to your pom.xml:

<!-- PMD static code analysis -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-pmd-plugin</artifactId>
    <version>3.13.0</version>
    <configuration>
        <rulesets>
        <!-- full list: bestpractices, codestyle, design, documentation, errorprone, multithreading, performance-->
        <ruleset>/category/java/bestpractices.xml</ruleset>
        </rulesets>
        <!-- failOnViolation is actually true by default, but can be disabled -->
        <failOnViolation>true</failOnViolation>
        <!-- printFailingErrors is pretty useful -->
        <printFailingErrors>true</printFailingErrors>
        <linkXRef>false</linkXRef>
    </configuration>
    <executions>
        <execution>
        <goals>
            <goal>check</goal>
        </goals>
        <!-- Enforce the pmd:check goal is auto-executed during package phase-->
        <phase>package</phase>
        </execution>
    </executions>
</plugin>

Invokation:

  • The plugin is configured to be automcatically executed on every mvn clean package.
  • To run the code analysis without the full package phase, type: mvn clean pmd:check.

Tweaks

Above default configuration only tests for codestyle violations. To get the full range of feedback, enable the full rulesets list:

    <ruleset>/category/java/bestpractices.xml</ruleset>
    <ruleset>/category/java/codestyle.xml</ruleset>
    <ruleset>/category/java/design.xml</ruleset>
    <ruleset>/category/java/documentation.xml</ruleset>
    <ruleset>/category/java/errorprone.xml</ruleset>
    <ruleset>/category/java/multithreading.xml</ruleset>
    <ruleset>/category/java/performance.xml</ruleset>