JiveLint by Sureshot - Users manual

 

Table of contents
-----------------

1. Introduction
2. Install
3. Uninstall
4. Running the JiveLint
5. Disable rules
6. Command line reference
7. Final words
A1. Rule description
A2. References

A3. FAQ - Frequently Asked Questions


1. Introduction
---------------

JiveLint is a command line tool employing static analysis on your JAVA source code. Potential bugs and weak points are reported and the manual describes how the source code can be improved. JiveLint also checks that the source code follows a set of coding convention rules.

For example, JiveLint will find unused code and variables, switch blocks without a default case, if a class overrides "Object.equals()" but not "Object.hashCode()", if code use == to compare Strings instead of equals().

JiveLint's goals:
-Improve source code quality by pointing out a large number of dangerous source code constructs.
-Improve readability, maintainability and debugging by enforcing a carefully selected set of coding and naming conventions.
-Communicate knowledge how to write high quality code by an in-detail manual describing and reasoning why a rule will improve source code quality.

JiveLint is Windows 95/98/ME/2000/NT/XP compatible. JiveLint is a standalone Windows application, it doesn't require you to have Java installed.


2. Install
----------

Create a folder for the software. Unzip the files into this folder.


3. Uninstall
------------

Locate the folder where the software is installed. Delete the files.



4. Running JiveLint
-------------------

To get started right away, run JiveLint on your source files.

Example 1:
>jivelint.exe -files Test1.java Test2.java


You can use the -projects switch to specify one or more project files. The project file should contain paths to .java files. The paths should be separated with newline.

Example 2:
>jivelint.exe -projects project1.jnt


5. Disable rules
----------------

You can disable specific rules that JiveLint enforces. Rules can be disabled globally or for a specific .java file.
Example 1:
Using a configuration file to disable rules 1001 and 1005.

/**
 * myconfig.txt
 * My configuration file.
 */
disable(1001)
disable(1005)
Use the -config switch to specify the configuration file.
>jivelint.exe -config myconfig.txt -files Test1.java Test2.java

Example 2:
Rules can also be disabled for a specific .java file. Comments have been added in the Test.java file to disable rule 1001, 1005, 1009 and 1012. Both // and /* comments can be used.

/*
 * jivelint disable(1001)
 * jivelint disable(1005)
 */

 //jivelint disable(1009)
 //jivelint disable(1012)

 import java.util.Vector;

 public class Test
 {
	[..snip..]
 }
 

6. Command line reference

-------------------------

-help Display help and version information.
-files [file1.java .. filen.java] Specify the files to analyse.
-config [file.txt] Specify the location of your configuration file.
-projects [project1.jnt .. project2.jnt] Specify the project files containing paths to .java files to analyse.


7. Final words
--------------

Please mail your comments and suggestions. Please let us know if you would like a notification about new releases.


A1. Rules description
---------------------


Rule 1000 - Unused Import
Avoid importing types that are never used.


Rule 1001 - Explicit import of java.lang classes.
All types in the java.lang package are implicitly imported. There's no need to import them explicitly.

Example of violation:
import java.lang.Thread;

class Test
{
    void m()
    {
    }
}


Rule 1002 - Wildcard import.
Demand import declarations are not allowed in the compilation unit. Enumerating the imported types explicitly makes it very clear to the reader from what package a type come from when used in the compilation unit.

Example of violation:
import java.util.*;

interface Test
{
    Vector getData();
}


Rule 1003 - Duplicate import.
The imported type has already been imported.

Example of violation:
import java.util.Vector;
import java.util.Vector;

class Test
{
    void m()
    {
    }
}


Rule 1004 - No default case in switch block.
There was no "default:" case in the switch block. Is this the intention? It is probably better to include the default case with an accompanying comment. If the flow of control should never reach the default case, use an assertion for early error detection:
switch (i)
{
    case 1:
        ...
        break;
    default:
        //Should never happen.
        assert(false);
        break;
}
If the default case is used to ignore values, use an empty default case:
switch (i)
{
    case 1:
        ...
        break;
    default:
        //All other values are ignored.
        break;
}


Rule 1005 - Catched exception too general.
Exceptions should be handled as specific as possible. Exception, RuntimeException, Error and Throwable are too general [8]. RuntimeException is inappropriate to catch except at the top level of your program. RuntimeExceptions usually represents programming errors and indicate that something in your program is broken. Catching Exception or Throwable is therefore also inappropriate since that catch clause will also catch RuntimeException.


Rule 1006 - Empty catch block.
Exceptions should be handled in the catch block.

Example of violation:
try
{
    ...
}
catch (IOException e) 
{
}
Sometimes the programmer can prove that the exception is never thrown but has to satisfy the compiler with a catch block. For example:
try
{
    wait();
}
catch (InterruptedException e)
{
    //Can never happen since no one will interrupted the thread.
}
In such rare cases it is better to state this explicitly in the code by an assertion along with an accompanying comment. For example:
try
{
    wait();
}
catch (InterruptedException e)
{
    //Can never happen since no one will interrupted the thread.
    assert(false);
}


Rule 1007 - Mixed indentation.
Both spaces and tabs have been used to indent the source code. If the file is indented with one editor it might look unindented in another if the tab size is not exactly the same in both editors. Prefer spaces only.


Rule 1008 - Wrong order of modifiers.
The order of modifiers should according to [1] be:

Class modifiers:
public protected private abstract static final strictfp

Field modifiers:
public protected private static final transient volatile

Method modifiers:
public protected private abstract static final synchronized native strictfp


Rule 1009 - Equality operation on 'true' boolean literal.
Avoiding equality operations on the 'true' boolean literal saves some byte code instructions and in most cases it improves readability.

Example of violation:
boolean empty = ...;
if (empty == true) //Identity operation
{
    ...
}

//The above could have been written:
if (empty)
{
    ...
}


Rule 1010 - Broken Double-Checked Locking idiom.
Double-Checked Locking is widely cited and used as an efficient method for implementing lazy initialisation in a multithreaded environment. Unfortunately does this idiom not work in the presence of either optimising compilers or shared memory multiprocessors [2].

Example of violation:
// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo 
{ 
  private Helper helper = null;

  public Helper getHelper() 
  {
    if (helper == null) 
    {
      synchronized(this)
      {
        if (helper == null) 
          helper = new Helper();
      }
    }
    return helper;
  }
}


Rule 1011 - Output on System.out or System.err.
Some programmers debug code with a debugger, some use printouts on System.out and System.err. Some printouts may by mistake not be removed when the debug session is over. This rule flags output using System.out.XX() System.out.XX() and Exception.printStackTrace();


Rule 1012 - Return in finally block.
Avoid using the return statement in a finally block.

Example of violation:
try
{
    //Do something that does not throw any checked exceptions.
    return 1;
}
finally
{
    return 0;
}
This will always return 0. Also, the semantic of exceptions is not obvious in such code construct. In fact, the following code is equivalent:
try
{
   //Do something that does not throw any checked exceptions.
}
catch (RuntimeException e)
{
}
catch (Error e)
{
}

return 0;


Rule 1013 - String comparison using == or != operator.
Avoid using the == or != operator to compare strings. Use String.equals() or String.compareTo() when testing strings for equality. [1]

Example of violation:
String s = ...;
if (s == "test")
{
    ...
}

Rule 1014 - Override both Object.equals() and Object.hashCode()
Some containers depends on both hashCode and equals when storing objects [3].


Rule 1015 - Assert portability
assert is a reserved word in JDK 1.4 [4]. Prefer using another name to improve portability.


Rule 1016 - if statement with empty body.
If statements directly followed by a semicolon is usually an error.

Example of violation:
if (isEmpty);
{
	System.out.print("Empty");
}


Rule 1017 - while statement with empty body.
while statements directly followed by a semi-colon is usually an error.

Example of violation:
while (isEmpty);
{
	System.out.print("Empty");
	...
}


Rule 1018 - Type in throw statement too general.
Prefer throwing subclasses instead of the general exception classes. Exception, RuntimeException, Throwable and Error are considered too general.

Example of violation:
throw Exception("...");


Rule 1019 - Suspicious method name.
The method has almost the same name as Object.hashCode, Object.equals or Object.finalize. Maybe the intention is to override one of these?

Example of violation:
class Test
{
    //Should be hashCode, not hashcode
    public int hashcode()
    {
        [...]
    }
}


Rule 1020 - Use space only for indentation.
Proper indentation improves readability. Prefer using space only when formatting your source code in order to produce code that is readable in all editors. If you use tab when formatting your source code, it may look unformatted in another editor since the tab size may differ from editor to editor.



Rule 1021 - Empty finally block.
An empty finally block is useless. It can be removed without changing the sematics of the program.



Rule 1022 - Prefer lines no longer than 80 characters.
Avoid lines longer than 80 characters, since they're not handled well by many terminals and tools [5]. Printers usually have a 80 character line limit. The printed copy will be hard to read when lines are wrapped.



Rule 1023 - Unused local variable.
An unused local variable may indicate a flaw in the program.

Example of violation:
class Test
{
    public void test()
    {
        final int unused = 22;
    }
}


Rule 1024 - Unknown javadoc tag.
A javadoc tag not part of the standard tags [6] was found. Is this the purpose or a spelling mistake?

Example of violation:
/**
 * Tag below is not spelled correctly.
 * @auhtor James Smith
 */
class Test
{
    [..]
}


Rule 1025 - for statement with empty body.
for statements directly followed by a semi-colon is usually an error.

Example of violation:
for (int i = 0; i < 10; ++i);
{
	System.out.print("i: " + i);
	...
}


Rule 1026 - public boolean equals(Object o) overloaded.
Overloading Object.equals(Object o) can easily break the required equivalence relation [3] that equals should implement.

Example of violation:
public class OverloadedEquals
{
    public OverloadedEquals(int i)
    {
        this.i = i;
    }

    public boolean equals(OverloadedEquals o)
    {
        if (o == null || o.getClass() != getClass())
        {
            return false;
        }
        else
        {
            OverloadedEquals other = (OverloadedEquals) o;
            return i == other.i;
        }
    }

    private final int i;
}

OverloadedEquals o1 = new OverloadedEquals(1);
OverloadedEquals o2 = new OverloadedEquals(1);
Object o3 = o2;

//Prints true, which it should.
System.out.println(o1.equals(o2));

//Prints false!!! but o1 is equals o3.
//The equivalence relation is broken.
System.out.println(o1.equals(o3)); 


Rule 1027 - Inequality operation on 'false' boolean literal.
Rule 1009 flags any equality operation with the 'true' literal which is an identity operation and therefore useless. To be consistent, this rule flags inequality operations on the 'false' literal which is also an identity operation.

Example of violation:
boolean empty = ...;
if (empty != false) //Identity operation
{
    ...
}

//The above could have been written:
if (empty)
{
    ...
}


Rule 1028 - Dead code detected.
This rule flags dead code. Only 'if (false)', 'while (false)' and 'for(..;false;..)' are detected.

Example of violation:
if (false)
{
    ...
}

while (false)
{
    ...
}


Rule 1029 - Unnecessary if statement.
This rule flags unnecessary if statements.

Example of violation:
if (true)
{
    ...
}



Rule 1030 - public void run() not overridden when extending Thread.
The run method should be overridden when extending the Thread class [7]. This rule does not warn when the class is abstract.

Example of violation:
public class Test extends Thread
{
}


Rule 1031 - finalizer implements default behaviour.
A finalizer implementing only the default behaviour is unnecessary.

Example of violation:
public class T    
{                                               
    protected void finalize() throws Throwable      
    {                                               
        super.finalize();                       
    }                                               
}                                                  


Rule 1032 - finalizer does not call super.finalize().
A finalizer should always call the superclass' finalizer.

Example of violation:
public class T    
{                                               
    protected void finalize() throws Throwable      
    {                                               
    }                                               
}                                                  


Rule 1033 - Explicit finalizer call.
The general contract of finalize is that it is invoked if and when the virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died. Also, the finalize method is never invoked more than once by a Java virtual machine for any given object.

Example of violation:
public void m()
{
    finalize();                                               
}                                               


Rule 1034 - Compare classes using getClass() in non-final equals method.
When comparing object for equality use the .getClass() method to make sure that the object are of exactly the same type. Checking types with the instanceof operator only breaks the required equivalence relation [3] when a subclass has redefined the equals method.

Example of violation:
public class SomeClass
{
    ...

    public boolean equals(Object anObject)
    {
        if (anObject instanceof SomeClass) 
        {
            SomeClass sc = (SomeClass) anObject;
            ...
        }
        return false;
    }
}
Template for non-final equals using getClass() to check types:
public class SomeClass
{
    ...

    public boolean equals(Object o)
    {
        if (o != null || o.getClass() == getClass())
        {
            SomeClass sc = (SomeClass) o;
            ...
        }
        return false;
    }
}


Rule 1035 - No package declaration found.
Try to structure your classes in packages.

Example of violation:
import test.SomeClass;

public class Test
{
}                                               


Rule 1036 - Importing classes from current package.
Classes from the same package are imported by default. There's no need to import them explicitly.

Example of violation:
package test;

import test.SomeClass;


Rule 1037 - No @author javadoc tag found.
Each compilation unit should have an @author javadoc tag.

Example of violation:
/**
 * @since 2002-02-14
 */
public class Test
{
}


Rule 1038 - Declare parameters final.
Assigning a value to the formal parameters can confuse many programmers because the formal parameter may be associated with the actual value passed to the method. Confusion might also arise if the method is long and the value of the parameter is changed.
If you do not intend to assign any value to the formal parameters you can state this explicitly by declaring them final.

Example of violation:
/**
 *
 */
public class Test
{
    public Test(Object o)
    {
        ...   
    }
}
Rule 1039 - No break statement found.
The flow of control fall into the case of default statement below. Is this the intention or is there a break statement missing? If this was deliberate then place a comment immediately before the next case of default statement. Add a comment containing the substring: "fall through" or "falls through".


Example of violation:
case 1:  i = 0;
case 2:  i--;
This rule will not warn when the case block is empty. For example:
case 1:  //Will not warn here.
case 2:  i--;




A2. References
--------------


[1] The Java Language Specification Second Edition, James Gosling, Bill Joy, Guy Steele, Gilad Bracha
[2] The "Double-Checked Locking is Broken" Declaration, Douglas Schmidt and Tim Harrison. 3rd annual Pattern Languages of Program Design conference, 1996
[3] Java Object 1.3 API, Sun Microsystems
[4] Assertion Facility, Sun Microsystems
[5] Code Conventions for the JavaTM Programming Language, Sun Microsystems
[6] javadoc - The Java API Documentation Generator, Sun Microsystems
[7] Java Thread 1.3 API, Sun Microsystems
[8] Complete Java 2 Certification Study Guide, Simon Roberts, Philip Heller, Michael Ernest, Roberts et al.