Tuning Java analysis through knowledge basesTuning Java analysis through knowledge basesThis is the main how-to for tuning Java analysis. You can find more information, including tutorials, at Tuning Java analysis. Diagnose the problem and 'declare' itDiagnose the problem Typically, the tuning process begins with an inconvenience in the form of a false positive. For example, you consistently notice that your analysis results list a specific issue type, for example, NPE.RET, that you don't consider to be an issue. The Klocwork traceback feature is a good place to start. The screenshot below is from Klocwork Desktop Java Plug-in for Eclipse: Note: With Klocwork Desktop Java Plug-in for Eclipse and IntelliJ IDEA, you can create and edit Java knowledge base (JKB) files directly from your IDE. See Tuning from Eclipse or IntelliJ IDEA.
When you examine the available Klocwork traceback information for the issue, you notice that there's a validation in the traceback or near it, but the issue is still being detected. Use traceback to help you determine the criteria by which code paths are to be added or eliminated from the NPE.RET checker's consideration. Other criteria to consider to reduce false positives are the identification of validation libraries, assertion libraries, termination libraries or exception libraries. Once you identify the criteria, then you must communicate them to the engine in the form of a Java knowledge base file (.jkb). Declare the criteria in a .jkb file Java knowledge base files are how you educate the checker about your data-flow criteria. A simple text file with the .jkb extension is where you 'declare' your criteria to the checker by including the methods of interest and then marking them up using specific Java knowledge base (JKB) annotations to indicate to the checker how they should be handled. The most common tuning annotations are @CheckTrue, @CheckFalse, and @Check for reducing false positives. The required tuning annotation, regardless of whether you are reducing false positives or detecting additional issues, is @Bind, which links the specified methods or all methods in a class (depending on where you place the binding in the file) to the specified checker. When creating .jkb files to tune analysis, there's a great deal of flexibility in the number of .jkb files you can create. You can create one .jkb per class, which is how the examples and tutorials in this guide are set up. You can create one .jkb just for validation, and one for security. You can also create a multi-sectional knowledge base for a whole project using a package statement as the transitional device. Tuning from Eclipse or IntelliJ IDEAKlocwork Desktop Java Plug-in for Eclipse and IntelliJ IDEA enables you to create a Java knowledge base file from the editor. The selected method is copied into the JKB file where you then add the appropriate JKB annotations. Once created, the JKB file is already contained in the project or workspace, thereby removing the need to import it. For Eclipse, you can select multiple methods for your JKB file in the Outline view. In IntelliJ IDEA, you select multiple methods from the Structure view. Java knowledge-base tuning overviewOnce you identify the issue (checker) and the criteria you need to communicate to the checker to prevent it, you:
Create a knowledge base fileBefore you create a knowledge base file, you need to decide if you're going to create one .jkb per class (which is the approach used in the tutorials and examples in this guide) or whether you want to create one .jkb for validation or security, etc. You can also use a multi-sectional .jkb for a whole project in a multi-sectional knowledge base file. For more information, see 'Using multi-sectional knowledge bases' below. To manually create (or edit) a knowledge base file:
Using multi-sectional knowledge basesYou can specify only one package declaration for a Java source file, and you cannot override imports after the imports block is finished. This works well for highly modular Java source code, but it does not fit well the purposes of the knowledge base, where sometimes you want to specify the knowledge base for a whole project or library. You can use more than one package declaration in a .jkb file. These package declarations split the .jkb file into multiple sections with independent package and import declarations. Example package java.util; import java.util.*; interface Entry<K,V> { @Source("return") K getKey(); } package java.io; // Here starts another section import java.net.URI; import java.net.URL; public class File { @Source("return") int getPrefixLength(); } import javax.swing.*; // Here starts another section class About @Source("return") JFrame getFrame(); } To describe classes which are not in any package, use "package;" as shown here: @BindAll("ERROR") class AKB { void a(@Sink String s); } package java.lang; public class String { @Source("return") java.lang.String trim(); } package; class BKB { void b(@Sink String s); } Using multi-sectional knowledge basesYou can specify only one package declaration for a Java source file, and you cannot override imports after the imports block is finished. This works well for highly modular Java source code, but it does not fit well the purposes of the knowledge base, where sometimes you want to specify the knowledge base for a whole project or library. You can use more than one package declaration in a .jkb file. These package declarations split the .jkb file into multiple sections with independent package and import declarations. Example package java.util; import java.util.*; interface Entry<K,V> { @Source("return") K getKey(); } package java.io; // Here starts another section import java.net.URI; import java.net.URL; public class File { @Source("return") int getPrefixLength(); } import javax.swing.*; // Here starts another section class About @Source("return") JFrame getFrame(); } To describe classes which are not in any package, use "package;" as shown here: @BindAll("ERROR") class AKB { void a(@Sink String s); } package java.lang; public class String { @Source("return") java.lang.String trim(); } package; class BKB { void b(@Sink String s); } Describe the method signatureTo describe the method signature that the checker should consider in its analysis, for example identity validation:
Example method signature descriptionLet's say we want to describe a few search methods from the javax.naming.directory DirContext. The method signature might look like the following: package javax.naming.directory; import javax.naming.*; public class DirContext { public NamingEnumeration<SearchResult> search(Name name, String filter, SearchControls cons) throws NamingException; public NamingEnumeration<SearchResult> search(String name, String filter, SearchControls cons) throws NamingException; } Example method signature descriptionLet's say we want to describe a few search methods from the javax.naming.directory DirContext. The method signature might look like the following: package javax.naming.directory; import javax.naming.*; public class DirContext { public NamingEnumeration<SearchResult> search(Name name, String filter, SearchControls cons) throws NamingException; public NamingEnumeration<SearchResult> search(String name, String filter, SearchControls cons) throws NamingException; } Knowledge base annotationsThe following annotations are those most commonly used to mark up your source for tuning Java analysis.
To make troubleshooting easier, it's best practice to:
Bind knowledge base records to specific checkersYou must use the @Bind (or @BindAll) annotation to bind knowledge base entries to specific checkers. Bindings are an integral part of tuning Java analysis with knowledge bases because they link the behavior you specify in the knowledge base with the checker you want to modify. Apply the knowledge base file to the analysisTo apply your new configuration file to the integration build analysis, import it into a project or the projects_root. The file will be synchronized to connected desktops. To apply your knowledge base file to a standalone desktop project, see Customizing your desktop analysis. |