In Part 1, I wrote about the many benefits of Kotlin for writing better, easier to understand code, and eliminating third-party libraries and tools.
This post will focus on Code Quality, what Kotlin has to improve quality, and tools available for Static Code Analysis.
Not surprisingly, all teams/organizations are concerned with code quality. Reading books like “Effective Java” by Joshua Bloch and “Code Complete” by Steve McConnell, testing, code reviews and pair programming are all items that can improve the quality of code.
Anyone coding with Java should at least be aware of the “Effective Java” book by Joshua Bloch. It details a number of strongly recommended practices for code development in general, and Java specifically.
The developers of Kotlin have as a stated goal to implement all of Effective Java into the compiler/language. Not everything is covered, but the major cases are.
var to clearly mark if something can/should change or not (prefer final).
Classes are closed (final) by default, and must be explicitly opened, thereby prohibiting inheritance unless it is designed for.
The compiler warns of unused items in a class/object, provides explicit null management via the type system, can enforce nullability from Java code if it’s annotated appropriately (JSR-305 and the other flavours of annotations).
The other main tool used by many Java shops is Sonarqube. This provides static analysis of the code base, and is performed as part of the Continuous Integration phase. i.e. on a build server after code has been pushed.
This can be a sore spot for many developers as they think they’re done their code, and depending on pipeline speed, don’t get notified of issues until well after making a Pull Request. Given there are tools like SonarLint, this doesn’t have to be the case, but it does require additional ‘effort’ by the team to ensure SonarLint is installed in their IDE, and they monitor the status.
For Kotlin, Sonarqube does not currently have official support. This is unfortunate, as it will prevent some organizations from adopting Kotlin.
There are static analysis tools available for Kotlin, including the analysis built-in to IntelliJ. If you use IntelliJ for Git interations too, ensure you enable the ‘Perform code analysis’ checkbox on the Commit dialog, and review the warnings it raises. IntelliJ will also show suggestions when coding, so there shouldn’t be any items left by the time you’re committing.
The tool my team has adopted is Detekt. This tool is constantly improving, and provides the ability to create custom rules.
It can be run standalone, or via a plugin for Maven or Gradle. I prefer the plugin approach, and have it execute after build and unit test, but before Integration tests.
By integrating it directly into the build, the team is assured that Detekt is always run on the code. Any issues are raised directly during development, and it’s always easiest to address things during development, while you’re in the context of the code.
Detekt configuration is quite easy. My team has recently adopted the approach of having all rules on by default, and then modifying/disabling only those specific ones that we feel should be different. As Detekt doesn’t currently provide a mechanism for a central configuration for rules, this simplifies ensuring all projects are conforming to the same standards.
If too many issues exist in the code base, Detekt will break the build. This forces the team to address code quality issues NOW, rather than letting them accumulate on a dashboard, never to be addressed. This also means the team decides what rules are important to it, and which ones it doesn’t want.
The author of Detekt has also created a plugin for Sonarqube. This plugin is not yet available through the Sonarqube Update Centre, so may be a problem to get installed at your corporation. It needs to be built from source, and installed into the plugins folder on the Sonarqube server. I was able to have this done at my employer as the decision to support Kotlin has been made, and having stats on the Sonarqube dashboard is also a pre-requisite.
Once the plugin is installed, Sonarqube will execute Detekt on any projects that contain Kotlin code. The results will appear as expected on the dashboard.
The plugin will also show Jacoco code coverage information on the dashboard. To get the Jacoco coverage information appearing, add the following to your Gradle coniguration for Sonarqube:
By default, Sonarqube will use the Detekt configuration incorporated into the plugin installed on Sonarqube. At the time of writing, there is no option to customize the configuration used by Sonarqube via the Sonarqube UI.
In order to ensure consistency, my team configures Sonarqube to use the same configuration file that is used during the local build. This is performed by adding the following to Sonarqube properties in the build.gradle file. The following will use the file ‘detekt.yml’ located in the root directory of the project.
Using the above, I have been able to ensure code quality in the Kotlin code base, and comply with organization requirements. The experience of developing Kotlin code has been very good overall, and it keeps getting better. Jetbrains, and the community, are very active. Constantly improving the tooling, more documentation, more podcasts. Everytime I’ve run into an issue, I’ve been able to find a solution with a quick search. Kotlin Forums, Stackoverflow or blog posts exist.
Pivotal is improving their support of Kotlin in the Spring Framework. Spring Framework 5.0 has been fully updated with @Null annotations, as well as helpers to allow for more idiomatic Kotlin usage of Spring.
Spring Boot 2.0 (currently M7) contains a number of enhancements to support Kotlin as well.
Google provided a huge boost to Kotlin, and now most teams developing Android apps are at least investigating Kotlin.
It’s definitely a promising language, with great community, and tool support behind it!