code quality assurance with pmd · contract of hashcode •same objects must return same integer...

44
Code Quality Assurance with PMD Peter Kofler, ‘Code Cop’ Herold Business Data, 2004

Upload: others

Post on 24-Jun-2020

11 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Code Quality Assurancewith PMD

Peter Kofler, ‘Code Cop’

Herold Business Data, 2004

Page 2: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Agenda

Page 3: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Status Daily Build

Static Code Analysis

Rule Categorisation

Rules to fix/obey ;-)

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 4: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Daily Build

• Since three months

• Trunk is compiling (at least more often)

–missing files �

– shared subproject complexity �

• Build history

• JavaDoc

• XML validation

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 5: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Next Steps

• Static code analysis

–check the source

• JUnit integration

–of few existing tests

• Initialise application

– integration tests (that would be cool)

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 6: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Static Analysis

Page 7: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

PMD Static Code Analyser

• http://pmd.sourceforge.net/

• Scans Java source

• JavaCC-generated parser

–Abstract Syntax Tree (AST)

• Traverses AST

• Reports violations

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 8: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Eclipse Plugin

• Install pmd-eclipse2-site-2.0RC3.zip

• Patch plugin with current PMD:

–extract pmd.jar from pmd-bin-1.5.zip

– rename to pmd-1.3.jar and replace in

plugins\net.sourceforge.pmd.core_1.3.2\lib

• Customise rules:

–delete all and import PMD20040427.xml

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 9: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

RuleCategorisation

Page 10: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

“Error”

• Really serious errors

–e.g. bad practice

– or correctness bugs

• Currently (only ;-) 125

in whole code base

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 11: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

“Warning”

• Other errors

• Currently 4023

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 12: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

“Info” (Information)

• Minor errors

–e.g. performance problems

• Currently 4091

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 13: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

“Format”

• Formatting Problems

–e.g. code style violations

• Currently 6834

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 14: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Fix It!

Page 15: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

“Fix” Process

• Activate not (yet) triggered rules

–make sure there are no new violations

• Fix few “bad guys” first

• Activate their rules

• Choose next error from list, repeat

• In the end only low priority bugs left

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 16: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Not Triggered Errors

• BadComparison if (y == Double.NaN)

• EmptyFinalizer

• FinalizeOnlyCallsSuperFinalize

• FinalizeOverloaded

• ShortMethodName (<= 3)

• SuspiciousHashcodeMethodNamepublic int hashcode() // <-> hashCode

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 17: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

• EmptyWhileStmtwhile (a == b) { // maybe here was some code before}

• NonStaticInitializer// public void doSomething(){ // this block gets run before any // call to any constructor System.out.println("construct myself");}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 18: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

MethodWithSameNameAsEnclosingClass

public class MyClass

{

// bad because it is a method

public void MyClass() { }

// OK because it is a constructor

public MyClass() { }

}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 19: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

• JumbledIncrementerfor (int i = 0; i < 10; i++) { for (int k = 0; k < 20; i++) { System.out.println("Hello"); }}

• NonCaseLabelInSwitchStatementswitch (a) { case 1 : // do something break; mylabel : // legal but confusing break;}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 20: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Not Triggered Warnings

• DefaultLabelNotLastInSwitchStmt

• DontImportJavaLang

• EmptyStaticInitializer

• EmptySwitchStatements

• EmptySynchronizedBlock

• EmptyTryBlock &EmptyFinallyBlock

• ImportFromSamePackage

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 21: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

• ForLoopShouldBeWhileLoopfor (; true;) { // no init or update part // may as well be: while (true)}

• SuspiciousOctalEscapepublic void foo() { System.out.println("suspicious: \128"); // interpreted as octal 12, // followed by character '8'}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 22: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Epic Evil

Page 23: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

10 Serious Errors (to fix)

• EmptyCatchBlock

• ExplicitCallToFinalize

• FinalizeDoesNotCallSuperFinalize

• FinalizeShouldBeProtected

• JUnitSpelling– framework methods are easy to misspell

• JUnitStaticSuite– suite() method needs to be public and static

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 24: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

DoubleCheckedLocking (is broken)

public Object getInstance() {

if (inst == null) { // may be non-null

synchronized (this) { // yet not fully created

if (inst == null)

inst = new Object();

}

}

return inst;

}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 25: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

OverrideBothEqualsAndHashcode

• Override bothboolean Object.equals(Object o) andint Object.hashCode(),or override neither.

• HashMap uses first hashCode() methodand then equals() method inside thehash-bucket...

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 26: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Contract of hashCode

• Same objects must return same integer

• If two objects are equals(), thehashCode() method on each of themmust produce the same integer.

• It is not required that if two objects areunequal according to the equals(), thetwo objects must produce distinctresults.

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 27: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

hashCode Implementation

private String member;

public int hashCode() {

// calculate hashCode from int-values

// of all members and sum them up

int result = 17;

result = 37*result+member.hashCode();

return result;

}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 28: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

ProperCloneImplementation

• should be implemented withsuper.clone()

public Object clone() {

return new MyClass(); // wrong

}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 29: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

clone Implementation

public Object clone() {

try {

return super.clone();

} catch (CloneNotSupportedException e) {

// should not happen, we are Cloneable

throw new InternalError(”error in clone");

}

}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 30: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

ReturnFromFinallyBlock

public String bugga() {

try {

throw new Exception("My Exception");

} catch (Exception e) {

throw e;

} finally {

return ”O.K."; // bad

}

}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 31: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Avoid!

Page 32: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

More Warnings (to avoid)

• AvoidCatchingThrowable

– there will be some exceptions to this rule...

• ExcessiveClass- & -MethodLength

• ExcessiveParameterList

• FinalizeOverloaded

• SignatureDeclareThrowsException

• SwitchStmtsShouldHaveDefault

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 33: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

ExceptionTypeChecking

try {

returnString = sdf.format(value);

} catch (Exception e) {

/* BAD STUFF */

if (e instanceof NumberFormatException)

System.out.println("NumberFormat!!!");

if (ex instanceof IllegalArgumentException)

System.out.println("illegal argument...!!!");

}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 34: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

ConstructorCallsOverridableMethodRule

public class Senior {

public Senior() {

toString(); // may throw a NPE if overridden

}

public String toString() {

return "IAmSenior";

}

}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 35: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

ConstructorCallsOverridableMethodRule #2

public class Junior extends Senior {

private String name;

public Junior() {

super(); // inserted by compiler -> NPE

name = "JuniorClass";

}

public String toString() {

return name.toUpperCase();

}

}

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 36: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Update

Page 37: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Second Iteration (November)

• Improve quality �

• 1st iteration removed all 125 errors �

– 100 seems to be a good work package �

• In the meantime ...–PMD has been updated

–New rules are available (and in use ;-)

• Now let’s fix another 8 rules–With approx. 100 violations

Page 38: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

5 Errors (to fix)

• AvoidCatchingNPE

• AvoidThrowingCertainExceptionTypes

• EmptyStatementNotInLoop if (false);

{

// will be executed

}

• ForLoopsMustUseBraces &WhileLoopsMustUseBraces

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 39: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

3 Warnings (to fix)

• BooleanInstantiationnew Boolean(*) � Boolean.valueOf(*)

• UnnecessaryReturn

• UnusedImports – Eclipse warning

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 40: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

New and Not Triggered #1

• DontImportSun (not in HP’s JDK)

• EqualsNullif (x.equals(x.equals(x.equals(x.equals(null)) { // never true

• BrokenNullCheckif (s!=null || !s.equals(""))!s.equals(""))!s.equals(""))!s.equals("")) { // use && !

• JUnitTestsShouldIncludeAssert

• TestClassWithoutTestCases

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 41: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

New and Not Triggered #2

• SimplifyStartsWithstartsWithstartsWithstartsWithstartsWith("a")("a")("a")("a") � charAtcharAtcharAtcharAt(0)==(0)==(0)==(0)==‘‘‘‘aaaa‘‘‘‘

• AppendCharacterWithCharb.append("a")b.append("a")b.append("a")b.append("a") � b.append(b.append(b.append(b.append('a''a''a''a'))))

• UseIndexOfChars.s.s.s.indexOfindexOfindexOfindexOf("a")("a")("a")("a") � s.s.s.s.indexOfindexOfindexOfindexOf(((('a''a''a''a'))))

• AvoidProtectedFieldInFinalClass

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 42: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

Questions

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 43: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

www.code-cop.org

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY

Page 44: Code Quality Assurance with PMD · Contract of hashCode •Same objects must return same integer •If two objects are equals() , the hashCode() method on each of them must produce

CC Images

• agenda: http://www.flickr.com/photos/24293932@N00/2752221871/

• micro: http://www.flickr.com/photos/wessexarchaeology/183177852/

• trash: http://www.flickr.com/photos/togr/244902037/

• building: http://www.flickr.com/photos/stephen_rees/440201126/

• evil: http://www.flickr.com/photos/legofenris/4476593087/

• avoid: http://www.flickr.com/photos/howardlake/4850758742/

• repeat: http://www.flickr.com/photos/cyanocorax/288232991/

• questions: http://www.flickr.com/photos/seandreilinger/2326448445/

PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY