OpenKM, the Debt Write-Off

Technical Debt is worth nothing if no pragmatic action is taken into code, in order to control and tackle it. To illustrate Scertify’s capability to automatically correct code defects that increase this unintended debt, we performed code refactoring on OpenKM, a Free/Libre document management system.

The initial Technical Debt of the project has been reduced by 49.2% from 84 days to 42 days. Here, at Tocea, we call it the Debt Write-Off.

For this first Debt Write-Off, we have decided to perform the refactoring of OpenKM (6.2.1-DEV).

According to Wikipedia, OpenKM is a Free/Libre document management system that provides a web interface for managing arbitrary files. OpenKM is a great tool but an audit of the code revealed some technical debt problems. That was a good opportunity to use Scertify and to be useful to an open-source community. The application consists mainly in 200K lines of code of Java. There is also Javascript, JSP, CSS… but we focus here on the Java code.

 

Technical debt before refactoring

Scertify Refactoring Assessment allows us to estimate the technical debt of the application. As you can see on screenshot #1, it is estimated to 84 days. This is the time needed to correct manually each error. This number only includes the time needed to make the change on the code, it does not include things like finding the file, understanding the problem, etc.

Of these 84 days, 60 represent errors that can be automatically refactored, thus taking nearly zero effort to correct.

We can take a closer look on the possibilities of automation (screenshot #2). Not all rules are currently implemented in Scertify, but we are working on it. For this project, we chose 7 rules that seemed particularly interesting.

 

 

Rules used for the refactoring

Here’s a presentation of the rules used to perform the refactoring of OpenKM.

AvoidPrintStackTrace

This rule reports a violation when it finds a code that catch an expression and print its stack trace to the standard error output. A logging framework should be used instead, in order to improve application’s maintainability.
The refactoring replace a call to print stack trace by a call to a logging framework. The rule can also declare the logger in the class and make the required imports. The rule can be configured to use the user’s favorite framework.

Here’s the configuration used for OpenKM:

  • The logger call to use: “log.error({0}.getMessage(), {0})” {0} is replaced by the exception.
  • Do not refactor calls of printStackTrace to other IO (a file, a stream…)
  • Make logger declaration when it’s needed (ie: log is not already declared in class).
  • The logger declaration to use : “private static Logger log = LoggerFactory.getLogger({0}.class);”
  • The required imports : “org.slf4j.LoggerFactory,org.slf4j.Logger”

Original code :

 

Refactored code :

 

AddEmptyStringToConvert

Using the concatenation of an empty string to convert a primitive type to a String is a bad practice. First of all, it makes the code less readable. It is also less efficient in most cases (the only case where the string concatenation is slightly better is when the primitive is final).

Original code :

Refactored code :

 

 

InefficientConstructorCall

Calling the constructor of a wrapper type, like Integer, to convert a primitive type is a bad practice. It is less efficient than calling the static method valueOf.

Original code:

Refactored code:

 

 

IfElseStmtsMustUseBraces

This rule finds if statements that don’t use braces. The refactoring adds required braces.

 

PositionLiteralsFirstInComparisonsRefactor

This rule checks that literals are in the first position in comparisons. The following code is a violation :

Refactored code :

 

The refactoring invert the literal and the variable. This ensures that the code cannot crash due to the variable being a null pointer.

 

MethodArgumentCouldBeFinal

This method flags method’s arguments that could be declared final and are not. The use of the final keyword is a useful information for future code readers.

 

LocalVariableCouldBeFinal

The purpose is the same as the previous rule, except that it treats local variable and not arguments. These two rules are not critical, but since they have a huge number of violations, it is useful to get rid of them quickly with automatic refactoring.

We are now ready to perform the refactoring with Scertify.

The refactoring process

The refactoring process consists of 2 steps :

  1. Configure a xml rule repository: The first step is crucial. As we have seen in previous section, some rules need to be configured to be useful. However, it shouldn’t take more than half an hour.
  2. Run Scertify to perform the refactoring: The second step is just a command line invocation, where you specify the project to refactor and the rule repository to use.

For this project of 200K lines of code, the refactoring took 2 minute. You can check the process on a smaller project in this video tutorial.

 

Technical debt after refactoring

Screenshot #3 is the analysis of the refactored project by Scertify Refactoring Assessment. As you can see, 24 days of technical debt have been erased.

Screenshot #4 and #5 show the difference of violations in Sonar between the original and the refactored project.

Here’s the number of violations that have been corrected for each rule (*) :

  • AddEmptyStringToConvert: 232
  • AvoidPrintStackTrace: 70
  • InefficientConstructorCall: 43
  • IFElseStmtsMustUseBraces: 411
  • PositionLiteralsFirstInComparisons: 358
  • MethodArgumentCouldBeFinal: 8848
  • LocalVariableCouldBeFinal : 7622

To sum up, with Scertify we’ve been able to correct quickly a huge number of errors. Some of them are not critical (like MethodArgumentCouldBeFinal) but we’ve also been able to refactor more evolved errors like AvoidPrintStackTrace, AddEmptyStringToConvert,…

 

Download the source files

 

 

(*) if you do the math, you’ll see that more errors have been corrected. It’s due to side effects of the refactoring (correcting a rule can remove violations of other rules) and also because we manually corrected few things in the code.

Submit your project

If you’re interested in a demo of Scertify, want to submit your project to the next Debt Write-off, or just give some valuable feedback… Please contact us by filling the form below. We’ll contact you asap.

Fill the form

 

Verification