Static Code Analysis With Eclipse


Static Code Analysis with Eclipse

Taking Warnings Seriously

Elliotte Rusty Harold

Wednesday, August 31, 2005

elharo@metalab.unc.edu

http://www.cafeaulait.org/


There's a bug in this class

package com.elharo.security;

import java.io.*;
import java.security.*;

public class EasyDigestOutputStream extends FilterOutputStream {

  private boolean on = true;
  private boolean closed = false;
  protected byte[] result = null;
  protected MessageDigest digest;

  public EasyDigestOutputStream(OutputStream out, String algorithm)
   throws NoSuchAlgorithmException {
    super(out);
    digest = MessageDigest.getInstance(algorithm);
  }

  public EasyDigestOutputStream(OutputStream out, String algorithm,                                 
   String provider) throws NoSuchAlgorithmException, NoSuchProviderException {
    super(out);
    digest = MessageDigest.getInstance(algorithm, provider);
  }

  public void write(int b) throws IOException {
    if (on) digest.update((byte)b);
    out.write(b);
  }

  public void write(byte[] data, int offset, int length) throws IOException {
    if (on) digest.update(data, offset, length);
    out.write(data, offset, length);
  }

  public void on(boolean on) {
    this.on = on;
  }
  
  public void close() throws IOException {
    out.close();
    result = digest.digest();
    closed = true;
  }
  
  public byte[] getDigest() {
    return result;
  }
}

Here's the bug


Corrected program

package com.elharo.security;

import java.io.*;
import java.security.*;

public class EasyDigestOutputStream extends FilterOutputStream {

  private boolean on = true;
  protected byte[] result = null;
  protected MessageDigest digest;

  public EasyDigestOutputStream(OutputStream out, String algorithm)
   throws NoSuchAlgorithmException {
    super(out);
    digest = MessageDigest.getInstance(algorithm);
  }

  public EasyDigestOutputStream(OutputStream out, String algorithm,                                 
   String provider) throws NoSuchAlgorithmException, NoSuchProviderException {
    super(out);
    digest = MessageDigest.getInstance(algorithm, provider);
  }

  public void write(int b) throws IOException {
    out.write(b);
    if (on) digest.update((byte)b);
  }

  public void write(byte[] data, int offset, int length) throws IOException {
    out.write(data, offset, length);
    if (on) digest.update(data, offset, length);
  }

  public void on(boolean on) {
    this.on = on;
  }
  
  public void close() throws IOException {
    out.close();
    result = digest.digest();
  }
  
  public byte[] getDigest() {
    return result;
  }
}

Severity vs. Effort


What is Static Code Analysis?


Turning on Static Code Analysis in Eclipse


Error Levels


Problems Eclipse can find


Methods with a constructor name


Methods overridden but not package visible


Non-static access to a static member


Possible accidental boolean assignment


Empty statement


Undocumented Empty Block


finally does not complete normally


Interface method conflicts with protected 'Object' method


Access to a non-accessible member of an enclosing type


Advanced


Assignment has no effect


Local variable declaration hides another field or variable


Field declaration hides another field or variable


Using a char array in string concatenation


Usage of deprecated API


Unused Code


Unused Code Problems


Unused Code Example

import java.util.ArrayList;
import java.util.List;
import java.util.Date;

public class UnusedCode {

    private int value = 7;
    
    public static void main(String[] args) {

        Object o = (Object) "Hello World!";
        
        ArrayList a = new ArrayList();
        if (a instanceof List) {
            return;
        }
        else {
            System.out.println("Bye Bye!");
        }

    }
    
    private double getFoo() {
        return 5.6;
    }

}

Thornier Problems


Hidden catch blocks


JavaDoc

If you use JavaDoc at all, turn on Process JavaDoc comments. By default this detects:


Checking for undocumented code


Spell checking


Java 5 Checks


Unchecked Generic type operation


Generic type parameter declared with a final type bound


Inexact type match for varargs arguments


Boxing and unboxing conversions


Missing @Override annotation


Annotation is used as a superinterface


Not all enum constants covered on switch


Unhandled warning tokens in @SuppressWarnings


Lint Comments


Plug-Ins


PMD



Checkstyle


FindBugs



Java PathFinder


Thanks To


To Learn More


Index | Cafe con Leche

Copyright 2005 Elliotte Rusty Harold
elharo@metalab.unc.edu
Last Modified September 7, 2005