Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

Java tuning tutorial 4 - Tuning NPE.RET to detect additional issues (Advanced)

Java tuning tutorial 4 - Tuning NPE.RET to detect additional issues (Advanced)

Note: Tuning existing checkers to detect additional issues (handling "false negatives") is considered an advanced tuning function.

Assertion methods from the junit library throw runtime exceptions if the assertion was wrong. Getting a runtime exception in the Java code is undesirable, and here we will use the case to demonstrate the introduction of the @Sink annotation into a Java knowledge base.

Let's use the following snippet:

import static junit.framework.Assert.assertNotNull;


public class SinkSample {

   public static void main(final String[] args) {      
      final SinkSample s = new SinkSample();     
      final Object o = s.get();     
      assertNotNull(o);  
   }
   
   private Object get() {      
      if (hashCode() < 0) {       
         return new Object();     
      }     
      return null;   
   }
}

Method get() can return null, that will cause a runtime exception thrown by assertNotNull(o) call. We want to detect and prevent such situations using the NPE.RET checker.

Create a .jkb file and add assertNotNull as the sink

In the .jkb file, describe the assertNotNull as the sink:

package junit.framework;


class Assert {  
   public static void assertNotNull(@Sink Object object);
}

Bind the Sink record to the checker

After you add @Sink, bind the data to the issue, using @Bind("NPE.RET"):

package junit.framework;

@Bind("NPE.RET") class Assert {

public static void assertNotNull(@Sink Object object);

}

Test the knowledge base

To test your knowledge base:

  1. Import the knowledge base into your project using kwcheck:
    kwcheck import sink.jkb
    
  2. Run the analysis:
    kwcheck run
    

When the code is analyzed using this knowledge base, Klocwork now detects the NPE.RET issue.

Add assertNull as the source

While assertNotNull can work as a null check for NPE.RET, assertNull can be treated as a null source, since the method will continue its execution only if the parameter of the call is null. See below:

package com.klocwork.jdefects.checkers.dfa.binding_walkthrough;

import static junit.framework.Assert.assertNull;

public class SourceSample {
  

   private Object field;
   
   public void setField(Object field) {      
      this.field = field;
   }
   
   public String toString() {     
      StringBuilder sb = new StringBuilder();     
      assertNull(field);      
      sb.append('[');      
      sb.append(field.hashCode());      
      sb.append(']');     
      return sb.toString();   
   }
}

In the sample above, assertNull guarantees that field is null, however there is an attempt to dereference this null value at

sb.append(field.hashCode());

In order to detect this situation we have to add @Source to the knowledge base and bind it to the checker:

package junit.framework;


@Bind("NPE.RET")
class Assert {   
   public static void assertNull(@Source Object object);
}

To test your knowledge base:

  1. Import the knowledge base into your project using kwcheck:
    kwcheck import sink.jkb
    
  2. Run the analysis:
    kwcheck run
    

When you run kwcheck you will see that NPE.RET is detected.

Add a Prop record to the knowledge base

The junit framework has a set of methods for verifying the equality of two given objects. This means that if we know that if one object is null, then the other should be null after the method was executed. That means that NPE.RET should be reported for the following snippet:

import static junit.framework.Assert.assertEquals;


public class PropSample {


   private Object field;

   public void setField(Object field) {      
      this.field = field;  
   }
  
   public String toString() {      
      final Object o = get();      
      assertEquals(field, o);      
      return field.toString();   
   }
   
   private Object get() {      
      if (hashCode() > 0) {        
         return new Object();      
      }     
      return null;  
   }
}

NPE.RET is reported because get() can return null, and there is an assertion that the returned value equals to field, which is dereferenced at return field.toString();)

Note: assertEquals is reflective, meaning that if any parameter is null, then another one is null as well. So we need to introduce two @Prop methods in the .jkb file with different with the @In and @Out annotations.

To the Java knowledge base file add:

package junit.framework;
class Assert {  
   @Prop public static void assertEquals(@In Object objA, @Out Object objB);   
   @Prop public static void assertEquals(@Out Object objA, @In Object objB);
}

Test the knowledge base

To test your knowledge base:

  1. Import the knowledge base into your project using kwcheck:
    kwcheck import <file>.jkb
    
  2. Run the analysis:
    kwcheck run