Code Quality Assurance with PMD (2004)

1,410 views

Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Code Quality Assurance with PMD (2004)

  1. 1. Code QualityAssurance with PMD(ongoing cleanups)Herold Business Data2004 to 2006 Peter Kofler, ‘Code Cop’ @codecopkofler www.code-cop.org Copyright Peter Kofler, licensed under CC-BY.
  2. 2. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY Peter Kofler • Ph.D. in Applied Math • Professional Software Developer • Developer at Herold Business Data • “fanatic about code quality”
  3. 3. Agenda
  4. 4. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY Status Daily Build Static Code Analysis Rule Categorisation Rules to fix/obey ;-)
  5. 5. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY Daily Build • Since three months • Trunk is compiling (at least more often) – missing files  – shared subproject complexity  • Build history • JavaDoc • XML validation
  6. 6. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY Next Steps • Static code analysis – check the source • JUnit integration – of few existing tests • Initialise application – integration tests (that would be cool)
  7. 7. Static Analysis
  8. 8. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY PMD Static Code Analyser • http://pmd.sourceforge.net/ • Scans Java source • JavaCC-generated parser – Abstract Syntax Tree (AST) • Traverses AST • Reports violations
  9. 9. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY 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 pluginsnet.sourceforge.pmd.core_1.3.2lib • Customise rules: – delete all and import PMD20040427.xml
  10. 10. RuleCategorisation
  11. 11. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY “Error” • Really serious errors – e.g. bad practice – or correctness bugs • Currently (only ;-) 125 in whole code base
  12. 12. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY “Warning” • Other errors • Currently 4023
  13. 13. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY “Info” (Information) • Minor errors – e.g. performance problems • Currently 4091
  14. 14. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY “Format” • Formatting Problems – e.g. code style violations • Currently 6834
  15. 15. Fix It!
  16. 16. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY “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
  17. 17. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY Not Triggered Errors • BadComparison if (y == Double.NaN) • EmptyFinalizer • FinalizeOnlyCallsSuperFinalize • FinalizeOverloaded • ShortMethodName (<= 3) • SuspiciousHashcodeMethodName public int hashcode() // <-> hashCode
  18. 18. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY • EmptyWhileStmt while (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"); }
  19. 19. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY MethodWithSameName AsEnclosingClass public class MyClass { // bad because it is a method public void MyClass() { } // OK because it is a constructor public MyClass() { } }
  20. 20. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY • JumbledIncrementer for (int i = 0; i < 10; i++) { for (int k = 0; k < 20; i++) { System.out.println("Hello"); } } • NonCaseLabelInSwitchStatement switch (a) { case 1 : // do something break; mylabel : // legal but confusing break; }
  21. 21. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY Not Triggered Warnings • DefaultLabelNotLastInSwitchStmt • DontImportJavaLang • EmptyStaticInitializer • EmptySwitchStatements • EmptySynchronizedBlock • EmptyTryBlock & EmptyFinallyBlock • ImportFromSamePackage
  22. 22. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY • ForLoopShouldBeWhileLoop for (; true;) { // no init or update part // may as well be: while (true) } • SuspiciousOctalEscape public void foo() { System.out.println("suspicious: 128"); // interpreted as octal 12, // followed by character 8 }
  23. 23. Epic Evil
  24. 24. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY 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
  25. 25. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY 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; }
  26. 26. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITYOverrideBothEqualsAndHashcode • Override both boolean Object.equals(Object o) and int Object.hashCode(), or override neither. • HashMap uses first hashCode() method and then equals() method inside the hash-bucket...
  27. 27. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY Contract of hashCode • Same objects must return same integer • If two objects are equals(), the hashCode() method on each of them must produce the same integer. • It is not required that if two objects are unequal according to the equals(), the two objects must produce distinct results.
  28. 28. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY 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; }
  29. 29. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY ProperCloneImplementation • should be implemented with super.clone() public Object clone() { return new MyClass(); // wrong }
  30. 30. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY clone Implementation public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { // should not happen, we are Cloneable throw new InternalError(”error in clone"); } }
  31. 31. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY ReturnFromFinallyBlock public String bugga() { try { throw new Exception("My Exception"); } catch (Exception e) { throw e; } finally { return ”O.K."; // bad } }
  32. 32. Avoid!
  33. 33. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY More Warnings (to avoid) • AvoidCatchingThrowable – there will be some exceptions to this rule... • ExcessiveClass- & -MethodLength • ExcessiveParameterList • FinalizeOverloaded • SignatureDeclareThrowsException • SwitchStmtsShouldHaveDefault
  34. 34. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY 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...!!!"); }
  35. 35. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY ConstructorCalls OverridableMethodRule public class Senior { public Senior() { toString(); // may throw a NPE if overridden } public String toString() { return "IAmSenior"; } }
  36. 36. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY ConstructorCalls OverridableMethodRule #2 public class Junior extends Senior { private String name; public Junior() { super(); // inserted by compiler -> NPE name = "JuniorClass"; } public String toString() { return name.toUpperCase(); } }
  37. 37. Update
  38. 38. 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
  39. 39. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY 5 Errors (to fix) • AvoidCatchingNPE • AvoidThrowingCertainExceptionTypes • EmptyStatementNotInLoop if (false); { // will be executed } • ForLoopsMustUseBraces & WhileLoopsMustUseBraces
  40. 40. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY 3 Warnings (to fix) • BooleanInstantiation new Boolean(*)  Boolean.valueOf(*) • UnnecessaryReturn • UnusedImports – Eclipse warning
  41. 41. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY New and Not Triggered #1 • DontImportSun (not in HP’s JDK) • EqualsNull if (x.equals(null)) { // never true • BrokenNullCheck if (s!=null || !s.equals(””)) { // use && ! • JUnitTestsShouldIncludeAssert • TestClassWithoutTestCases
  42. 42. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY New and Not Triggered #2 • SimplifyStartsWith startsWith(”a”) charAt(0)==a • AppendCharacterWithChar b.append(”a”) b.append(a) • UseIndexOfChar s.indexOf(”a”) s.indexOf(a) • AvoidProtectedFieldInFinalClass
  43. 43. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY Thank You
  44. 44. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY Peter Kofler @codecopkofler www.code-cop.org
  45. 45. PETER KOFLER, CODE-COP.ORG FANATIC ABOUT CODE QUALITY CC Images • cleaning: http://www.flickr.com/photos/inf3ktion/4477642894/ • 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/

×