code quality in ruby and java

173
Code Quality What is this s**t? Steve Hayes - Cogent Consulting Pty Ltd http://www.cogentconsulting.com.au [email protected] 1 Friday, 28 August 2009

Upload: steve-hayes

Post on 10-May-2015

3.080 views

Category:

Technology


1 download

DESCRIPTION

This presentation was originally given at the Agile 2009 conference in Chicago

TRANSCRIPT

Page 1: Code Quality in Ruby and Java

Code QualityWhat is this s**t?

Steve Hayes - Cogent Consulting Pty Ltdhttp://www.cogentconsulting.com.au

[email protected]

1Friday, 28 August 2009

Page 2: Code Quality in Ruby and Java

In 1990 there were 120 billion lines of code

2Friday, 28 August 2009

Page 3: Code Quality in Ruby and Java

In 2000 there were 250 billion lines of code

3Friday, 28 August 2009

Page 4: Code Quality in Ruby and Java

In 2010 there will be 500 billion lines of code

4Friday, 28 August 2009

Page 5: Code Quality in Ruby and Java

Printed in a font 1mm high the code listing would stretch from the Earth to the Moon and beyond

5Friday, 28 August 2009

Page 6: Code Quality in Ruby and Java

Code Quality

6Friday, 28 August 2009

Page 7: Code Quality in Ruby and Java

Code quality is subjective - it requires human judgment

7Friday, 28 August 2009

Page 8: Code Quality in Ruby and Java

There have been, and always will be, arguments about code quality

8Friday, 28 August 2009

Page 9: Code Quality in Ruby and Java

9Friday, 28 August 2009

Page 10: Code Quality in Ruby and Java

WTF implies lack of clarity

10Friday, 28 August 2009

Page 11: Code Quality in Ruby and Java

“Simplicity, clarity, singleness: These are the attributes that give our lives power and vividness and joy as they are also the marks of great art.

The seem to be the purpose of God for his whole creation.”

Richard Holloway

11Friday, 28 August 2009

Page 12: Code Quality in Ruby and Java

Clear code is easier to understand, easier to maintain, and easier to extend

12Friday, 28 August 2009

Page 13: Code Quality in Ruby and Java

• inconsistent style• long methods• lots of methods in a single class• repeated code• methods with many alternative paths

There are many things that can reduce the clarity of code, including:

13Friday, 28 August 2009

Page 14: Code Quality in Ruby and Java

Your particular bugbears may be different

14Friday, 28 August 2009

Page 15: Code Quality in Ruby and Java

Why metrics?

15Friday, 28 August 2009

Page 16: Code Quality in Ruby and Java

We substitute metrics for human judgement

16Friday, 28 August 2009

Page 17: Code Quality in Ruby and Java

17Friday, 28 August 2009

Page 18: Code Quality in Ruby and Java

People are expensive, CPU time is cheap

18Friday, 28 August 2009

Page 19: Code Quality in Ruby and Java

• inconsistent style• long methods• lots of methods in a single class• repeated code• methods with many alternative paths

Use automation to detect clarity problems, such as:

19Friday, 28 August 2009

Page 20: Code Quality in Ruby and Java

Use exception based reporting so that people can focus their energy

20Friday, 28 August 2009

Page 21: Code Quality in Ruby and Java

on the quality exceptions

21Friday, 28 August 2009

Page 22: Code Quality in Ruby and Java

or on completely different things

22Friday, 28 August 2009

Page 23: Code Quality in Ruby and Java

23Friday, 28 August 2009

Page 24: Code Quality in Ruby and Java

Code Analysis

24Friday, 28 August 2009

Page 25: Code Quality in Ruby and Java

Let’s start with some Ruby

Formtastic by Justin French

25Friday, 28 August 2009

Page 26: Code Quality in Ruby and Java

Then we’ll move on to some Java

26Friday, 28 August 2009

Page 27: Code Quality in Ruby and Java

Duplication

27Friday, 28 August 2009

Page 28: Code Quality in Ruby and Java

28Friday, 28 August 2009

Page 29: Code Quality in Ruby and Java

Duplication makes everything else worse

29Friday, 28 August 2009

Page 30: Code Quality in Ruby and Java

30Friday, 28 August 2009

Page 31: Code Quality in Ruby and Java

Initial analysis of Formtastic

31Friday, 28 August 2009

Page 32: Code Quality in Ruby and Java

37 Roodi problems

95 Flog problems

32Friday, 28 August 2009

Page 33: Code Quality in Ruby and Java

Simian

http://www.redhillconsulting.com.au/products/simian/

33Friday, 28 August 2009

Page 34: Code Quality in Ruby and Java

14/08/09 3:41 AMSimian - Similarity Analyser | Duplicate Code Detection for the Enterprise

Page 1 of 2http://www.redhillconsulting.com.au/products/simian/

Simian - Similarity Analyser

Purpose

Simian (Similarity Analyser) identifies duplication in Java, C#, C, C++, COBOL, Ruby, JSP, ASP,HTML, XML, Visual Basic, Groovy source code and even plain text files. In fact, simian can be used onany human readable files such as ini files, deployment descriptors, you name it.

Especially on large enterprise projects, it can be difficult for any one developer to keep track of all thefeatures (classes, methods, etc.) of the system.

Simian runs natively in any .NET 1.1 or higher supported environment and on any Java 1.4 or highervirtual machine, meaning Simian can be run on just about any hardware and any operating system youcan hope for. Both the Java and .NET runtimes are included as part of the distribution.

Simian can be used as part of the build process during development or as a guide when re-factoring.Think of Simian as an independent pair of eyes that will assist in raising the quality of your software.

Within minutes, Simian can save you literally thousands of dollars in time spent performing maintenence,debugging and re-factoring.

With licensing available to suite personal, project and enterprise use, simian is ideally suited for use onyour project.

Why do I need Simian?

Imagine for example that a bug is discovered in a method somewhere in a project. The developer dulywrites a test case, makes the necessary code changes, ensures the test passes, checks the code in andconsiders the job finished!

Right?

Wrong!

Unknown to the developer, some weeks earlier, a fellow team mate discovered the same piece of codeand realised that it did almost everything they needed to solve a problem thye were working on at thetime. So they copied the 15 lines of code into their new method, added some more code to do the extrafunctionality required and checked in the changes.

Of course what they didn't know at the time was that the code they were copying had a bug in it! In factat the time no one knew this. So now the original bug has been fixed but unfortunately none of thecopies were fixed because no one knew they even existed.

Copying and pasting isn't the only way for this to occur. Duplicate code can also creep into throughdevelopers independently implementing similar features.

Simian catches these and other instances of duplication and can be configured to either flag them aswarnings or even "break the build", ensuring that copy and pasting never again causes you or yourproject problems.

34Friday, 28 August 2009

Page 35: Code Quality in Ruby and Java

Simian highlights obvious duplication

35Friday, 28 August 2009

Page 36: Code Quality in Ruby and Java

Similarity Analyser 2.2.24 - http://www.redhillconsulting.com.au/products/simian/index.htmlCopyright (c) 2003-08 RedHill Consulting Pty. Ltd. All rights reserved.Simian is not free unless used solely for non-commercial or evaluation purposes.{failOnDuplication=true, ignoreCharacterCase=true, ignoreCurlyBraces=true, ignoreIdentifierCase=true, ignoreModifiers=true, ignoreStringCase=true, threshold=6}Found 7 duplicate lines in the following files: Between lines 949 and 962 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rb Between lines 969 and 982 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rbFound 7 duplicate lines in the following files: Between lines 2552 and 2562 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rb Between lines 2752 and 2762 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rbFound 11 duplicate lines in the following files: Between lines 1429 and 1446 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rb Between lines 1758 and 1775 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rbFound 50 duplicate lines in 6 blocks in 1 filesProcessed a total of 2066 significant (4341 raw) lines in 6 filesProcessing time: 0.144sec

36Friday, 28 August 2009

Page 37: Code Quality in Ruby and Java

Flay

http://ruby.sadi.st/Flay.html

37Friday, 28 August 2009

Page 38: Code Quality in Ruby and Java

14/08/09 3:46 AMConfessions of a Ruby Sadist sudo gem install flay

Page 1 of 2http://ruby.sadi.st/Flay.html

Ruby Sadist Flog Flay Heckle Kittens About Us

Flay analyzes ruby code for

structural similarities. Differences

in literal values, names,

whitespace, and programming

style are all ignored.

Code that flay reports as similar

is a good candidate for

refactoring.

Try this:

% sudo gem install% sudo gem install

flayflay

% flay lib/*.rb% flay lib/*.rb

and see what you find.

Confessions of a Ruby Sadistsudo gem install flay

38Friday, 28 August 2009

Page 39: Code Quality in Ruby and Java

Flay detects more subtle duplication

39Friday, 28 August 2009

Page 40: Code Quality in Ruby and Java

Total score (lower is better) = 2637

1) Similar code found in :iter (mass = 342) spec/formtastic_spec.rb:1570 spec/formtastic_spec.rb:1616

2) Similar code found in :iter (mass = 136) spec/formtastic_spec.rb:1183 spec/formtastic_spec.rb:2147 spec/formtastic_spec.rb:2313 spec/formtastic_spec.rb:2368

3) IDENTICAL code found in :iter (mass*2 = 136) spec/formtastic_spec.rb:1458 spec/formtastic_spec.rb:1787

4) IDENTICAL code found in :iter (mass*2 = 120) spec/formtastic_spec.rb:1069 spec/formtastic_spec.rb:1133

5) IDENTICAL code found in :iter (mass*2 = 104) spec/formtastic_spec.rb:232 spec/formtastic_spec.rb:392

6) Similar code found in :iter (mass = 100) spec/formtastic_spec.rb:2572 spec/formtastic_spec.rb:2771

7) Similar code found in :iter (mass = 98) spec/formtastic_spec.rb:408 spec/formtastic_spec.rb:419

8) Similar code found in :iter (mass = 96) spec/formtastic_spec.rb:1825 spec/formtastic_spec.rb:1831 spec/formtastic_spec.rb:1844 spec/formtastic_spec.rb:1877 spec/formtastic_spec.rb:1895 spec/formtastic_spec.rb:1914

9) Similar code found in :iter (mass = 92) spec/formtastic_spec.rb:2235 spec/formtastic_spec.rb:2245

10) Similar code found in :block (mass = 84) spec/formtastic_spec.rb:1900 spec/formtastic_spec.rb:1919

11) IDENTICAL code found in :block (mass*2 = 84) spec/formtastic_spec.rb:187 spec/formtastic_spec.rb:194

12) Similar code found in :iter (mass = 84) spec/formtastic_spec.rb:774 spec/formtastic_spec.rb:830

13) Similar code found in :iter (mass = 78) spec/formtastic_spec.rb:1208 spec/formtastic_spec.rb:1239 spec/formtastic_spec.rb:1265

14) Similar code found in :iter (mass = 75) spec/formtastic_spec.rb:596 spec/formtastic_spec.rb:602 spec/formtastic_spec.rb:608

40Friday, 28 August 2009

Page 41: Code Quality in Ruby and Java

So what did I do?

41Friday, 28 August 2009

Page 42: Code Quality in Ruby and Java

move lines around

change similar code to be the same

changed in-line constants to variables

42Friday, 28 August 2009

Page 43: Code Quality in Ruby and Java

these are often non-trivial changes

43Friday, 28 August 2009

Page 44: Code Quality in Ruby and Java

very little change in overall file length

(3013 => 2897 lines)

44Friday, 28 August 2009

Page 45: Code Quality in Ruby and Java

How did that change complexity?

45Friday, 28 August 2009

Page 46: Code Quality in Ruby and Java

37 => 37 Roodi problems

95 => 38 Flog problems

46Friday, 28 August 2009

Page 47: Code Quality in Ruby and Java

Flog change indicates that methods have become simpler

47Friday, 28 August 2009

Page 48: Code Quality in Ruby and Java

Exacerbation

48Friday, 28 August 2009

Page 49: Code Quality in Ruby and Java

49Friday, 28 August 2009

Page 50: Code Quality in Ruby and Java

What else exacerbates problems?

50Friday, 28 August 2009

Page 51: Code Quality in Ruby and Java

Long classes and methods

51Friday, 28 August 2009

Page 52: Code Quality in Ruby and Java

http://farm4.static.flickr.com/3060/2426522019_7e696fb9af.jpg

52Friday, 28 August 2009

Page 53: Code Quality in Ruby and Java

Tools that detect long classes and methods are simple but useful

53Friday, 28 August 2009

Page 54: Code Quality in Ruby and Java

Roodi

Ruby Object Oriented Design Inferometer http://github.com/martinjandrews/roodi/tree/master

54Friday, 28 August 2009

Page 55: Code Quality in Ruby and Java

General Purpose Code Quality

55Friday, 28 August 2009

Page 56: Code Quality in Ruby and Java

AssignmentInConditionalCheck

CaseMissingElseCheck

ClassLineCountCheck

ClassNameCheck

CyclomaticComplexityBlockCheck

CyclomaticComplexityMethodCheck

EmptyRescueBodyCheck

ForLoopCheck

MethodLineCountCheck

MethodNameCheck

ModuleLineCountCheck

ModuleNameCheck

ParameterNumberCheck

Check for an assignment inside a conditional. It‘s probably a mistaken equality comparison.

Check that case statements have an else statement so that all cases are covered.

Check that the number of lines in a class is below the threshold.

Check that class names match convention.

Check that the cyclomatic complexity of all blocks is below the threshold.

Check that the cyclomatic complexity of all methods is below the threshold.

Check that there are no empty rescue blocks.

Check that for loops aren‘t used (Use Enumerable.each instead)

Check that the number of lines in a method is below the threshold.

Check that method names match convention.

Check that the number of lines in a module is below the threshold.

Check that module names match convention.

Check that the number of parameters on a method is below the threshold.

Roodi checks

56Friday, 28 August 2009

Page 57: Code Quality in Ruby and Java

AssignmentInConditionalCheck

CaseMissingElseCheck

ClassLineCountCheck

ClassNameCheck

CyclomaticComplexityBlockCheck

CyclomaticComplexityMethodCheck

EmptyRescueBodyCheck

ForLoopCheck

MethodLineCountCheck

MethodNameCheck

ModuleLineCountCheck

ModuleNameCheck

ParameterNumberCheck

300

pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/

4

8

20

pattern: !ruby/regexp /^[_a-z<>=\[\]|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/

300

pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/

5

Roodi parameters

57Friday, 28 August 2009

Page 58: Code Quality in Ruby and Java

lib/formtastic.rb:8 - Module "Formtastic" has 1272 lines. It should have 300 or less.lib/formtastic.rb:10 - Class "SemanticFormBuilder" has 1196 lines. It should have 300 or less.lib/formtastic.rb:742 - Method "date_or_datetime_input" has 33 lines. It should have 20 or less.lib/formtastic.rb:835 - Method "check_boxes_input" has 24 lines. It should have 20 or less.lib/formtastic.rb:1008 - Method "default_input_type" has 24 lines. It should have 20 or less.lib/formtastic.rb:1046 - Method "find_collection_for_column" has 27 lines. It should have 20 or less.lib/formtastic.rb:1180 - Method "localized_attribute_string" has 24 lines. It should have 20 or less.lib/formtastic.rb:742 - Method name "date_or_datetime_input" cyclomatic complexity is 10. It should be 8 or less.lib/formtastic.rb:1008 - Method name "default_input_type" cyclomatic complexity is 19. It should be 8 or less.lib/formtastic.rb:1046 - Method name "find_collection_for_column" cyclomatic complexity is 10. It should be 8 or less.lib/formtastic.rb:756 - Block cyclomatic complexity is 5. It should be 4 or less.lib/formtastic.rb:1027 - Found = in conditional. It should probably be an ==lib/formtastic.rb:1103 - Found = in conditional. It should probably be an ==lib/formtastic.rb:1188 - Rescue block should not be empty.lib/formtastic.rb:103 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:378 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:381 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:427 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:455 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:883 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:948 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:950 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1027 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1080 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1128 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1130 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1176 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1184 - Don't use class variables. You might want to try a different design.

58Friday, 28 August 2009

Page 59: Code Quality in Ruby and Java

spec/formtastic_spec.rb:38 - Block cyclomatic complexity is 5. It should be 4 or less.spec/formtastic_spec.rb:1728 - Block cyclomatic complexity is 5. It should be 4 or less.spec/formtastic_spec.rb:1899 - Block cyclomatic complexity is 5. It should be 4 or less.spec/formtastic_spec.rb:1900 - Block cyclomatic complexity is 5. It should be 4 or less.spec/formtastic_spec.rb:2006 - Block cyclomatic complexity is 6. It should be 4 or less.spec/formtastic_spec.rb:2300 - Block cyclomatic complexity is 9. It should be 4 or less.spec/formtastic_spec.rb:2895 - Block cyclomatic complexity is 9. It should be 4 or less.spec/formtastic_spec.rb:2897 - Block cyclomatic complexity is 14. It should be 4 or less.spec/formtastic_spec.rb:109 - Case statement is missing an else clause.

59Friday, 28 August 2009

Page 60: Code Quality in Ruby and Java

Let’s work through the spec first

60Friday, 28 August 2009

Page 61: Code Quality in Ruby and Java

spec/formtastic_spec.rb:38 - Block cyclomatic complexity is 5. It should be 4 or less.

61Friday, 28 August 2009

Page 62: Code Quality in Ruby and Java

spec/formtastic_spec.rb:109 - Case statement is missing an else clause.

62Friday, 28 August 2009

Page 63: Code Quality in Ruby and Java

Post.stub!(:reflect_on_association).and_return do |column_name| case column_name when :author, :author_status mock('reflection', :options => {}, :klass => Author, :macro => :belongs_to) when :authors mock('reflection', :options => {}, :klass => Author, :macro => :has_and_belongs_to_many) end end

Existing code

63Friday, 28 August 2009

Page 64: Code Quality in Ruby and Java

def mock_post_association(column_name) return mock_association(Author, :belongs_to) if column_name.is_post_belongs_to? return mock_association(Author, :has_and_belongs_to_many) if column_name.is_post_habtm? end def mock_association(klass, multiplicity) mock('reflection', :options => {}, :klass => klass, :macro => multiplicity) end

... Post.stub!(:reflect_on_association).and_return { |column_name|mock_post_association(column_name) }

New code

64Friday, 28 August 2009

Page 65: Code Quality in Ruby and Java

spec/formtastic_spec.rb:1744 - Block cyclomatic complexity is 5. It should be 4 or less.spec/formtastic_spec.rb:1915 - Block cyclomatic complexity is 5. It should be 4 or less.spec/formtastic_spec.rb:1916 - Block cyclomatic complexity is 5. It should be 4 or less.spec/formtastic_spec.rb:2022 - Block cyclomatic complexity is 6. It should be 4 or less.spec/formtastic_spec.rb:2316 - Block cyclomatic complexity is 9. It should be 4 or less.spec/formtastic_spec.rb:2911 - Block cyclomatic complexity is 9. It should be 4 or less.spec/formtastic_spec.rb:2913 - Block cyclomatic complexity is 14. It should be 4 or less.

65Friday, 28 August 2009

Page 66: Code Quality in Ruby and Java

Not worth addressing these

66Friday, 28 August 2009

Page 67: Code Quality in Ruby and Java

Back to the non-test code

67Friday, 28 August 2009

Page 68: Code Quality in Ruby and Java

lib/formtastic.rb:8 - Module "Formtastic" has 1272 lines. It should have 300 or less.lib/formtastic.rb:10 - Class "SemanticFormBuilder" has 1196 lines. It should have 300 or less.lib/formtastic.rb:742 - Method "date_or_datetime_input" has 33 lines. It should have 20 or less.lib/formtastic.rb:835 - Method "check_boxes_input" has 24 lines. It should have 20 or less.lib/formtastic.rb:1008 - Method "default_input_type" has 24 lines. It should have 20 or less.lib/formtastic.rb:1046 - Method "find_collection_for_column" has 27 lines. It should have 20 or less.lib/formtastic.rb:1180 - Method "localized_attribute_string" has 24 lines. It should have 20 or less.lib/formtastic.rb:742 - Method name "date_or_datetime_input" cyclomatic complexity is 10. It should be 8 or less.lib/formtastic.rb:1008 - Method name "default_input_type" cyclomatic complexity is 19. It should be 8 or less.lib/formtastic.rb:1046 - Method name "find_collection_for_column" cyclomatic complexity is 10. It should be 8 or less.lib/formtastic.rb:756 - Block cyclomatic complexity is 5. It should be 4 or less.lib/formtastic.rb:1027 - Found = in conditional. It should probably be an ==lib/formtastic.rb:1103 - Found = in conditional. It should probably be an ==lib/formtastic.rb:1188 - Rescue block should not be empty.lib/formtastic.rb:103 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:378 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:381 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:427 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:455 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:883 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:948 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:950 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1027 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1080 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1128 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1130 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1176 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1184 - Don't use class variables. You might want to try a different design.

68Friday, 28 August 2009

Page 69: Code Quality in Ruby and Java

(and now I make lots of code changes)

69Friday, 28 August 2009

Page 70: Code Quality in Ruby and Java

lib/formtastic.rb:115 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:390 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:393 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:439 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:467 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:926 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:991 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:993 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1045 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1126 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1175 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1177 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1223 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:1240 - Don't use class variables. You might want to try a different design.lib/formtastic.rb:20 - Module "Formtastic" has 1311 lines. It should have 300 or less.lib/formtastic.rb:22 - Class "SemanticFormBuilder" has 1235 lines. It should have 300 or less.lib/formtastic.rb:1244 - Rescue block should not be empty.

70Friday, 28 August 2009

Page 71: Code Quality in Ruby and Java

and I decide that’s enough for now

71Friday, 28 August 2009

Page 72: Code Quality in Ruby and Java

How does this change flog?

72Friday, 28 August 2009

Page 73: Code Quality in Ruby and Java

>88.1: SemanticFormBuilder#date_or_datetime_input 60.4: SemanticFormBuilder#inputs 58.4: SemanticFormBuilder#input>57.7: SemanticFormBuilder#find_collection_for_column-56.9: SemanticFormBuilder#default_input_type>48.3: SemanticFormBuilder#localized_attribute_string-44.3: SemanticFormBuilder#check_boxes_input 43.3: SemanticFormBuilder#field_set_and_list_wrapping 40.2: SemanticFormBuilder#radio_input 31.2: SemanticFormBuilder#inputs_for_nested_attributes 24.0: SemanticFormBuilder#label 22.7: SemanticFormBuilder#method_required? 20.0: SemanticFormBuilder#none

60.4: SemanticFormBuilder#inputs58.4: SemanticFormBuilder#input45.3: SemanticFormBuilder#database_column_input_type43.3: SemanticFormBuilder#field_set_and_list_wrapping40.2: SemanticFormBuilder#radio_input38.4: SemanticFormBuilder#localized_attribute_string31.4: SemanticFormBuilder#find_collection_for_column_explicit_or_association_or_boolean31.2: SemanticFormBuilder#inputs_for_nested_attributes29.5: SemanticFormBuilder#datetime_content_tag28.1: SemanticFormBuilder#find_collection_for_column26.0: SemanticFormBuilder#single_list_item_content_from24.0: SemanticFormBuilder#label22.7: SemanticFormBuilder#method_required?20.2: SemanticFormBuilder#date_or_datetime_input20.0: SemanticFormBuilder#none

Old and new flog warnings

73Friday, 28 August 2009

Page 74: Code Quality in Ruby and Java

>88.1: SemanticFormBuilder#date_or_datetime_input>57.7: SemanticFormBuilder#find_collection_for_column-56.9: SemanticFormBuilder#default_input_type>48.3: SemanticFormBuilder#localized_attribute_string-44.3: SemanticFormBuilder#check_boxes_input

45.3: SemanticFormBuilder#database_column_input_type 38.4: SemanticFormBuilder#localized_attribute_string 31.4: SemanticFormBuilder#find_collection_for_column_explicit_or_association_or_boolean 29.5: SemanticFormBuilder#datetime_content_tag 28.1: SemanticFormBuilder#find_collection_for_column 26.0: SemanticFormBuilder#single_list_item_content_from 20.2: SemanticFormBuilder#date_or_datetime_input

Changes

74Friday, 28 August 2009

Page 75: Code Quality in Ruby and Java

So what’s Flog?

75Friday, 28 August 2009

Page 76: Code Quality in Ruby and Java

So what’s Flog?

14/08/09 3:34 AMConfessions of a Ruby Sadist sudo gem install flog

Page 1 of 2http://ruby.sadi.st/Flog.html

Ruby Sadist Flog Flay Heckle Kittens About Us

Flog shows you the most

torturous code you wrote.

The more painful the code,

the higher the score. The

higher the score, the

harder it is to test.

Run it against your best

stuff. I double-dog dare you.

Flog essentially scores an

ABC metric: Assignments,

Branches, Calls, with

particular attention placed

on calls.

Run flog on all your code.

Try this:

find lib -name \*.rb | xargs flog

Whatever is at the top of the

report is worth looking at.

This is how it works:

Confessions of a Ruby Sadistsudo gem install flog

76Friday, 28 August 2009

Page 77: Code Quality in Ruby and Java

14/08/09 3:34 AMConfessions of a Ruby Sadist sudo gem install flog

Page 2 of 2http://ruby.sadi.st/Flog.html

class Test

def blah

a = eval "1+1"

if a == 2 then

puts "yay"

end

end

end

Is seen by

flog as:

Test#blah: (11.2)

6.0: eval

1.2: branch

1.2: ==

1.2: puts

1.2: assignment

0.4: lit_fixnum

and reported

as:

class Test

def blah # 11.2 =

a = eval "1+1" # 1.2 + 6.0 +

if a == 2 then # 1.2 + 1.2 +

0.4 +

puts "yay" # 1.2

end

end

end

77Friday, 28 August 2009

Page 78: Code Quality in Ruby and Java

THRESHOLD = 0.60 SCORES = Hash.new 1 BRANCHING = [ :and, :case, :else, :if, :or, :rescue, :until, :when, :while ]

# various non-call constructs OTHER_SCORES = { :alias => 2, :assignment => 1, :block => 1, :block_pass => 1, :branch => 1, :lit_fixnum => 0.25, :sclass => 5, :super => 1, :to_proc_icky! => 10, :to_proc_normal => 5, :yield => 1, }

# eval forms SCORES.merge!(:define_method => 5, :eval => 5, :module_eval => 5, :class_eval => 5, :instance_eval => 5)

# various "magic" usually used for "clever code" SCORES.merge!(:alias_method => 2, :extend => 2, :include => 2, :instance_method => 2, :instance_methods => 2, :method_added => 2, :method_defined? => 2, :method_removed => 2, :method_undefined => 2, :private_class_method => 2, :private_instance_methods => 2, :private_method_defined? => 2, :protected_instance_methods => 2, :protected_method_defined? => 2, :public_class_method => 2, :public_instance_methods => 2, :public_method_defined? => 2, :remove_method => 2, :send => 3, :undef_method => 2)

# calls I don't like and usually see being abused

SCORES.merge!(:inject => 2)

Flog weights

78Friday, 28 August 2009

Page 79: Code Quality in Ruby and Java

flog -d lib/formtastic.rb

79Friday, 28 August 2009

Page 80: Code Quality in Ruby and Java

Flog details for worst method

60.4: SemanticFormBuilder#inputs 16.6: assignment 11.9: branch 11.5: to_proc_normal 5.8: block_pass 5.7: map 4.8: class 3.3: field_set_and_list_wrapping 2.3: content_columns 2.2: macro 2.1: reflections 2.0: == 2.0: to_sym 1.9: compact! 1.9: + 1.9: - 1.8: empty? 1.8: input 1.5: block_given? 1.5: inputs_for_nested_attributes 1.4: extract_options! 1.4: []

80Friday, 28 August 2009

Page 81: Code Quality in Ruby and Java

def inputs(*args, &block) html_options = args.extract_options! html_options[:class] ||= "inputs"

if html_options[:for] inputs_for_nested_attributes(args, html_options, &block) elsif block_given? field_set_and_list_wrapping(html_options, &block) else if @object && args.empty? args = @object.class.reflections.map { |n,_| n if _.macro == :belongs_to } args += @object.class.content_columns.map(&:name) args -= %w[created_at updated_at created_on updated_on lock_version] args.compact! end contents = args.map { |method| input(method.to_sym) }

field_set_and_list_wrapping(html_options, contents) end end

Original code

81Friday, 28 August 2009

Page 82: Code Quality in Ruby and Java

def inputs(*args, &block) html_options = args.extract_options! html_options[:class] ||= "inputs"

if html_options[:for] inputs_for_nested_attributes(args, html_options, &block) elsif block_given? field_set_and_list_wrapping(html_options, &block) else if @object && args.empty? args = build_default_inputs_args end contents = args.map { |method| input(method.to_sym) } field_set_and_list_wrapping(html_options, contents) end end def build_default_inputs_args() args = @object.class.reflections.map { |n,_| n if _.macro == :belongs_to } args += @object.class.content_columns.map(&:name) args -= %w[created_at updated_at created_on updated_on lock_version] args.compact! end

First change

82Friday, 28 August 2009

Page 83: Code Quality in Ruby and Java

Flog details29.8: SemanticFormBuilder#build_default_inputs_args 9.0: to_proc_normal 8.7: assignment 3.8: class 3.0: map 2.9: branch 1.8: block_pass 1.8: content_columns 1.7: macro 1.6: reflections 1.5: == 1.4: compact! 1.4: - 1.4: +

24.1: SemanticFormBuilder#inputs 8.0: branch 6.7: assignment 3.5: block_pass 3.3: field_set_and_list_wrapping 2.0: to_sym 1.8: empty? 1.8: build_default_inputs_args 1.8: input 1.7: map 1.5: inputs_for_nested_attributes 1.5: block_given? 1.4: extract_options! 1.4: []

83Friday, 28 August 2009

Page 84: Code Quality in Ruby and Java

def inputs(*args, &block) html_options = args.extract_options! html_options[:class] ||= "inputs"

if html_options[:for] inputs_for_nested_attributes(args, html_options, &block) elsif block_given? field_set_and_list_wrapping(html_options, &block) else contents = inputs_contents(args) field_set_and_list_wrapping(html_options, contents) end end

def inputs_contents(args) if @object && args.empty? args = build_default_inputs_args end return args.map { |method| input(method.to_sym) } end def build_default_inputs_args() args = @object.class.reflections.map { |n,_| n if _.macro == :belongs_to } args += @object.class.content_columns.map(&:name) args -= %w[created_at updated_at created_on updated_on lock_version] args.compact! end

Next change

84Friday, 28 August 2009

Page 85: Code Quality in Ruby and Java

Flog details - only one significant method

29.8: SemanticFormBuilder#build_default_inputs_args 9.0: to_proc_normal 8.7: assignment 3.8: class 3.0: map 2.9: branch 1.8: block_pass 1.8: content_columns 1.7: macro 1.6: reflections 1.5: == 1.4: compact! 1.4: - 1.4: +

85Friday, 28 August 2009

Page 86: Code Quality in Ruby and Java

def build_default_inputs_args() args = @object.class.reflections.map { |n,_| n if _.macro == :belongs_to } args += @object.class.content_columns.map {|c| c.name} args -= %w[created_at updated_at created_on updated_on lock_version] args.compact! end

Inline to_proc

86Friday, 28 August 2009

Page 87: Code Quality in Ruby and Java

Flog details

22.4: SemanticFormBuilder#build_default_inputs_args 10.4: assignment 4.5: branch 3.8: class 3.0: map 1.8: content_columns 1.7: name 1.7: macro 1.6: reflections 1.5: == 1.4: compact! 1.4: -

87Friday, 28 August 2009

Page 88: Code Quality in Ruby and Java

def build_default_inputs_args() args = @object.class.reflections.map { |n,_| n if _.macro == :belongs_to } args += content_column_names args -= %w[created_at updated_at created_on updated_on lock_version] args.compact! end def content_column_names return @object.class.content_columns.map {|c| c.name} end

Extract method

88Friday, 28 August 2009

Page 89: Code Quality in Ruby and Java

Flog details

16.6: SemanticFormBuilder#build_default_inputs_args 8.7: assignment 2.9: branch 1.8: class 1.7: macro 1.6: content_column_names 1.6: reflections 1.5: == 1.4: compact! 1.4: map 1.4: - 1.4: +

89Friday, 28 August 2009

Page 90: Code Quality in Ruby and Java

and so forth...

90Friday, 28 August 2009

Page 91: Code Quality in Ruby and Java

Other Ruby code quality tools

91Friday, 28 August 2009

Page 92: Code Quality in Ruby and Java

Code churn metric

92Friday, 28 August 2009

Page 93: Code Quality in Ruby and Java

14/08/09 5:05 AMSaikuro : A Cyclomatic Complexity Analyzer

Page 1 of 3http://saikuro.rubyforge.org/

Saikuro is a Ruby cyclomatic complexity analyzer. When given

Ruby source code Saikuro will generate a report listing the

cyclomatic complexity of each method found. In addition,

Saikuro counts the number of lines per method and can

generate a listing of the number of tokens on each line of code.

Version:0.2

LicenseSaikuro uses the BSD license.

Example OutputHere are examples of the output generated by Saikuro.

Cyclomatic complexity summary page

Token count summary page

Installation

As root run:

# ruby setup.rb all

UsageSaikuro is a command line program. Running "saikuro.rb -h" will

output a usage statement describing all the various arguments

you can pass to it.

"saikuro -c -p tests/samples.rb"

The above command is a simple example that generates a

cyclomatic complexity report on the samples.rb file, using the

default filter, warning and error settings. The report is saved in

the current directory.

A more detailed example is :

"saikuro -c -t -i tests -y 0 -w 11 -e 16 -o out/"

This will analyze all Ruby files found in the "tests/" directory.

Saikuro will generate a token count report and a cyclomatic

complexity report in the "out" directory . The "-y 0" command

will turn off filtering and thus show the complexity of all

methods. The "-w 11" will mark all methods with a complexity of

11 or higher with a warning. Finally, "-e 16" will flag all methods

with a complexity of 16 or higher with an error.

About Cyclomatic ComplexityThe following document provides a very good and detailed

description by the author of cyclomatic complexity.

NIST Special Publication 500-235

Structured Testing: A Testing Methodology Using the Cyclomatic

Complexity Metric

By Arthur H. Watson and Thomas J. McCabe

HTML

PDF

How and what Saikuro counts to calculatethe cyclomatic complexity

Saikuro uses the Simplified Complexity Calculation, which is just

SaikuroA Cyclomatic Complexity Analyzer

Download Saikuro

93Friday, 28 August 2009

Page 94: Code Quality in Ruby and Java

14/08/09 5:06 AMreek, a code smells detector for ruby « silk and spinach

Page 1 of 10http://silkandspinach.net/2008/09/23/reek-a-code-smells-detector-for-ruby/

silk and spinach

development, by example

reek, a code smells detector for ruby

with 23 comments

To complement the imminent (ie. sometime next year) publication of the Ruby Refactoring WorkbookI’ve been working on a little software tool called ‘reek’. Reek scans ruby code — either source files orin-memory Class objects — looking for some of the code smells discussed in the book. Right now it candetect (certain forms of):

Long MethodLarge ClassFeature EnvyUncommunicative NameLong Parameter ListUtility FunctionNested Iterators

As time goes by I’ll be adding checks for more smells, and I hope to make the current checks a bit moresophisticated. But in the agile spirit of going ugly early, the current very early version is available foryou to experiment with. To get the tool:

gem install reek

To run it:

reek file1.rb file2.rb ...

If you try it, please let me know what you think and what you’d like the next version to do!

You can browse the reek project’s code repository at http://github.com/kevinrutherford/reek/tree/masteror http://rubyforge.org/projects/reek/, both of which are clones of the same Git repository.

Other Ruby tools operating in this same space include Marty Andrews’ Roodi, and flay and flog fromthe seattle.rb folks. All of these tools have been made possible by the excellent ParseTree gem from theamazingly productive folks at seattle.rb. Looks like Ruby code quality is a hot topic right now, which Ithink is great news.

Possibly related posts: (automatically generated)

reek 0.3.0 releasedreek and feature envyreek included in metric_fuRailsconf 2009 – Code quality analysis

Ads by Google

94Friday, 28 August 2009

Page 95: Code Quality in Ruby and Java

15/08/09 12:11 PMRCov - Ruby C0 Code Coverage

Page 1 of 1http://relevance.github.com/rcov/

RCov

RCov - Ruby C0 Code Coverage

Source

Install

$ gem install relevance-rcov

Usage

See the README on GitHub for the most-up to date usage of RCov.

Maintained by Relevance

95Friday, 28 August 2009

Page 96: Code Quality in Ruby and Java

metric fu

96Friday, 28 August 2009

Page 97: Code Quality in Ruby and Java

rake metrics:all

97Friday, 28 August 2009

Page 98: Code Quality in Ruby and Java

results at

file:///Users/stevehayes/projects/third-party/formtastic/tmp/metric_fu/output/index.html

98Friday, 28 August 2009

Page 99: Code Quality in Ruby and Java

Java time

99Friday, 28 August 2009

Page 100: Code Quality in Ruby and Java

Example code is from Apache Commons Collections 3.2.1

100Friday, 28 August 2009

Page 101: Code Quality in Ruby and Java

Simian for duplication detection

101Friday, 28 August 2009

Page 102: Code Quality in Ruby and Java

java -jar simian-2.2.24.jar src/**/*.java

102Friday, 28 August 2009

Page 103: Code Quality in Ruby and Java

Found 11527 duplicate lines in 871 blocks in 239 files

Processed a total of 41324 significant (109875 raw) lines in 467 files

Processing time: 2.404sec

103Friday, 28 August 2009

Page 104: Code Quality in Ruby and Java

27.9% of the code is duplicated

104Friday, 28 August 2009

Page 105: Code Quality in Ruby and Java

Simian can also be language sensitive

105Friday, 28 August 2009

Page 106: Code Quality in Ruby and Java

java -jar simian-2.2.24.jar -language=java src/**/*.java

106Friday, 28 August 2009

Page 107: Code Quality in Ruby and Java

PMD for duplication detection

107Friday, 28 August 2009

Page 108: Code Quality in Ruby and Java

Android Rules: These rules deal with the Android SDK, mostly related to best practices. To get better results, make sure that the auxclasspath is defined for type resolution to work.

• Basic JSF rules: Rules concerning basic JSF guidelines.• Basic JSP rules: Rules concerning basic JSP guidelines.• Basic Rules: The Basic Ruleset contains a collection of good practices which everyone should follow.• Braces Rules: The Braces Ruleset contains a collection of braces rules.• Clone Implementation Rules: The Clone Implementation ruleset contains a collection of rules that find questionable usages

of the clone() method.• Code Size Rules: The Code Size Ruleset contains a collection of rules that find code size related problems.• Controversial Rules: The Controversial Ruleset contains rules that, for whatever reason, are considered controversial. They

are separated out here to allow people to include as they see fit via custom rulesets. This ruleset was initially created in response to discussions over UnnecessaryConstructorRule which Tom likes but most people really dislike :-)

• Coupling Rules: These are rules which find instances of high or inappropriate coupling between objects and packages.• Design Rules: The Design Ruleset contains a collection of rules that find questionable designs.• Finalizer Rules: These rules deal with different problems that can occur with finalizers.• Import Statement Rules: These rules deal with different problems that can occur with a class' import statements.• J2EE Rules: These are rules for J2EE• JavaBean Rules: The JavaBeans Ruleset catches instances of bean rules not being followed.• JUnit Rules: These rules deal with different problems that can occur with JUnit tests.• Jakarta Commons Logging Rules: The Jakarta Commons Logging ruleset contains a collection of rules that find questionable

usages of that framework.• Java Logging Rules: The Java Logging ruleset contains a collection of rules that find questionable usages of the logger.• Migration Rules: Contains rules about migrating from one JDK version to another. Don't use these rules directly, rather, use

a wrapper ruleset such as migrating_to_13.xml.• Migration13: Contains rules for migrating to JDK 1.3• Migration14: Contains rules for migrating to JDK 1.4• Migration15: Contains rules for migrating to JDK 1.5• MigratingToJava4: Contains rules for migrating to JDK 1.5• Naming Rules: The Naming Ruleset contains a collection of rules about names - too long, too short, and so forth.• Optimization Rules: These rules deal with different optimizations that generally apply to performance best practices.• Strict Exception Rules: These rules provide some strict guidelines about throwing and catching exceptions.• String and StringBuffer Rules: These rules deal with different problems that can occur with manipulation of the class String

or StringBuffer.• Security Code Guidelines: These rules check the security guidelines from Sun, published at http://java.sun.com/security/

seccodeguide.html#gcg• Type Resolution Rules: These are rules which resolve java Class files for comparisson, as opposed to a String

108Friday, 28 August 2009

Page 109: Code Quality in Ruby and Java

Basic Rules: The Basic Ruleset contains a collection of good practices which everyone should follow.• Braces Rules: The Braces Ruleset contains a collection of braces rules.• Clone Implementation Rules: The Clone Implementation ruleset contains a collection of rules that find questionable usages

of the clone() method.• Code Size Rules: The Code Size Ruleset contains a collection of rules that find code size related problems.• Coupling Rules: These are rules which find instances of high or inappropriate coupling between objects and packages.• Design Rules: The Design Ruleset contains a collection of rules that find questionable designs.• Import Statement Rules: These rules deal with different problems that can occur with a class' import statements.• JUnit Rules: These rules deal with different problems that can occur with JUnit tests.• Naming Rules: The Naming Ruleset contains a collection of rules about names - too long, too short, and so forth.• Optimization Rules: These rules deal with different optimizations that generally apply to performance best practices.• Strict Exception Rules: These rules provide some strict guidelines about throwing and catching exceptions.• String and StringBuffer Rules: These rules deal with different problems that can occur with manipulation of the class String

or StringBuffer.• Type Resolution Rules: These are rules which resolve java Class files for comparisson, as opposed to a String• Unused Code Rules: The Unused Code Ruleset contains a collection of rules that find unused code.

109Friday, 28 August 2009

Page 110: Code Quality in Ruby and Java

Basic Rules

• Empty catch block

• Empty if Statement

• Empty while statement

• Empty try block

• Empty finally block

• Empty switch statements

• Jumbled incrementer

• For loop should be while loop

• Unnecessary conversion temporary

• Override both equals and hashcode

• Double checked locking

• Return from finally block

• Empty synchronized block

• Unnecessary return

• Empty static initializer

• Unconditional if statement

• Empty statement not in loop

• Boolean instantiation

• Unnecessary final modifier

• Collapsible if statements

• Useless overriding method

• Class cast exception with toArray

• Avoid decimal literals in BigDecimal constructor

• Useless operation on immutable

• Misplaced null check

• Unused null check in equals

• Avoid thread group

• Broken null check

• BigInteger instantiation

• Avoid using octal values

• Avoid using hardcoded IP

• Check result set

• Avoid multiple unary operators

• Empty initializer

110Friday, 28 August 2009

Page 111: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:308 Overriding method merely calls super/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:410 Overriding method merely calls super/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:476 Avoid empty catch blocks/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:536 Avoid empty catch blocks/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:616 These nested if statements could be combined/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1157 Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1179 Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:907 Avoid empty catch blocks/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/LRUMap.java:120 These nested if statements could be combined/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/MapUtils.java:170 Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/MultiHashMap.java:138 Avoid empty catch blocks/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:598 Avoid empty while statements/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:936 Ensure you override both equals() and hashCode()/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:952 Ensure you override both equals() and hashCode()/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:159 Unnecessary final modifier in final class/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:393 Unnecessary final modifier in final class/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:401 Unnecessary final modifier in final class/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:416 Unnecessary final modifier in final class/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:431 Unnecessary final modifier in final class/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/functors/PrototypeFactory.java:195 Avoid empty catch blocks/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/functors/PrototypeFactory.java:202 Avoid empty catch blocks/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/FilterIterator.java:108 These nested if statements could be combined/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/FilterListIterator.java:140 These nested if statements could be combined/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/FilterListIterator.java:156 These nested if statements could be combined/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/ObjectGraphIterator.java:141 Avoid empty if statements/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/ObjectGraphIterator.java:193 Avoid empty if statements/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/ObjectGraphIterator.java:195 Avoid empty if statements/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/list/CursorableLinkedList.java:428 Avoid empty if statements/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractReferenceMap.java:278 Avoid empty while statements/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractReferenceMap.java:889 Ensure you override both equals() and hashCode()/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractReferenceMap.java:906 Ensure you override both equals() and hashCode()/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/CaseInsensitiveMap.java:133 Overriding method merely calls super/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/HashedMap.java:96 Overriding method merely calls super/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/IdentityMap.java:175 Overriding method merely calls super/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/LRUMap.java:395 Overriding method merely calls super/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/LinkedMap.java:117 Overriding method merely calls super/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/StaticBucketMap.java:160 Unnecessary final modifier in final class

Basic Rules - 725

111Friday, 28 August 2009

Page 112: Code Quality in Ruby and Java

Braces Rules

• If statements must use braces• While loops must use braces• If else statements must use braces• For loops must use braces

112Friday, 28 August 2009

Page 113: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:268 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:600 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:476 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:272 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:280 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:370 Avoid using if...else statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:371 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:382 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:393 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:876 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:894 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:912 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:987 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:1012 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:1029 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:1063 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastHashMap.java:592 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastTreeMap.java:700 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/LRUMap.java:92 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:289 Avoid using while statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:378 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:464 Avoid using if...else statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:465 Avoid using if...else statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:506 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:520 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:537 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:538 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:541 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:571 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:579 Avoid using if...else statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:580 Avoid using if...else statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:598 Avoid using while statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:621 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:622 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:665 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:711 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:771 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:778 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:779 Avoid using if statements without curly braces/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:780 Avoid using if statements without curly braces

Braces Rules - 210

113Friday, 28 August 2009

Page 114: Code Quality in Ruby and Java

Clone Rules

• Proper clone implementation (should include super.clone())• Clone throws CloneNotSupportedException• Clone method must implement cloneable

114Friday, 28 August 2009

Page 115: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:281 Object clone() should be implemented with super.clone()/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:281 clone() method should be implemented only if implementing Cloneable interface/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:281 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastHashMap.java:419 Object clone() should be implemented with super.clone()/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastHashMap.java:419 clone() method should be implemented only if implementing Cloneable interface/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastHashMap.java:419 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastTreeMap.java:470 Object clone() should be implemented with super.clone()/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastTreeMap.java:470 clone() method should be implemented only if implementing Cloneable interface/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastTreeMap.java:470 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/MultiHashMap.java:464 clone() method should be implemented only if implementing Cloneable interface/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/MultiHashMap.java:464 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractHashedMap.java:1227 clone() method should be implemented only if implementing Cloneable interface/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractHashedMap.java:1227 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/CaseInsensitiveMap.java:133 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/Flat3Map.java:1014 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/HashedMap.java:96 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/IdentityMap.java:175 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/LRUMap.java:395 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/LinkedMap.java:117 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/MultiKeyMap.java:818 Object clone() should be implemented with super.clone()/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/MultiKeyMap.java:818 clone() method should be implemented only if implementing Cloneable interface/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/MultiKeyMap.java:818 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/SingletonMap.java:538 clone() method should throw CloneNotSupportedException/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/BulkTest.java:177 clone() method should throw CloneNotSupportedException

Clone Rules - 25

115Friday, 28 August 2009

Page 116: Code Quality in Ruby and Java

Code Size Rules

• NPath complexity (200)• Excessive method length (100)• Excessive parameter list (10)• Excessive class length (1000)• Cyclomatic complexity (10)• Excessive public count (45)• Too many fields (15)• NCSS method count (100)• NCSS type count (1500)• NCSS constructor count (100)• Too many methods (10)

116Friday, 28 August 2009

Page 117: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:55 This class has too many methods, consider refactoring it./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:63 The class 'BinaryHeap' has a Cyclomatic Complexity of 2 (Highest = 14)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:64 This class has too many methods, consider refactoring it./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:465 The method 'iterator' has a Cyclomatic Complexity of 14./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:482 The method 'remove' has a Cyclomatic Complexity of 10./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:56 This class has too many methods, consider refactoring it./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ClosureUtils.java:57 This class has too many methods, consider refactoring it./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:17 This class has a bunch of public methods and attributes/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:58 Avoid really long classes./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:58 The class 'CollectionUtils' has a Cyclomatic Complexity of 3 (Highest = 14)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:58 This class has too many methods, consider refactoring it./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:741 The method 'index' has a Cyclomatic Complexity of 13./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:829 The method 'get' has a Cyclomatic Complexity of 14./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:894 The method 'size' has a Cyclomatic Complexity of 10./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ComparatorUtils.java:44 This class has too many methods, consider refactoring it./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:17 This class has a bunch of public methods and attributes/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:55 Avoid really long classes./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:55 This class has too many methods, consider refactoring it./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:1202 This class has too many methods, consider refactoring it./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:1405 The method insertListable() has an NPath complexity of 200/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DefaultMapBag.java:48 This class has too many methods, consider refactoring it./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:17 This class has a bunch of public methods and attributes/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:107 Avoid really long classes./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:107 The class 'DoubleOrderedMap' has a Cyclomatic Complexity of 4 (Highest = 15)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:107 This class has too many methods, consider refactoring it./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:202 The method 'entrySetByValue' has a Cyclomatic Complexity of 12./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:341 The method 'valuesByValue' has a Cyclomatic Complexity of 11./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:804 The method 'doRedBlackInsert' has a Cyclomatic Complexity of 11./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:875 The method 'doRedBlackDelete' has a Cyclomatic Complexity of 13./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:952 The method 'doRedBlackDeleteFixup' has a Cyclomatic Complexity of 12./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:1044 The method 'swapPosition' has a Cyclomatic Complexity of

Code Size Rules - 338

117Friday, 28 August 2009

Page 118: Code Quality in Ruby and Java

Coupling Rules

• Coupling between objects (attributes, local variables, return types) (20)

• Excessive imports (30)• Loose coupling (avoid using implementation types, use

interface instead)

118Friday, 28 August 2009

Page 119: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:59 Avoid using implementation types like 'HashMap'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:60 Avoid using implementation types like 'HashMap'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:61 Avoid using implementation types like 'HashMap'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:72 Avoid using implementation types like 'HashMap'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:187 Avoid using implementation types like 'ArrayList'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1037 Avoid using implementation types like 'Vector'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1053 Avoid using implementation types like 'Vector'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1053 Avoid using implementation types like 'Vector'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:117 Avoid using implementation types like 'ArrayList'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastHashMap.java:71 Avoid using implementation types like 'HashMap'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastTreeMap.java:73 Avoid using implementation types like 'TreeMap'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:17 A high number of imports can indicate a high degree of coupling within an object./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/SequencedHashMap.java:154 Avoid using implementation types like 'HashMap'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:508 Avoid using implementation types like 'ArrayList'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/CollatingIterator.java:49 Avoid using implementation types like 'ArrayList'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/CollatingIterator.java:52 Avoid using implementation types like 'ArrayList'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/CollatingIterator.java:361 Avoid using implementation types like 'ArrayList'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/MultiValueMap.java:78 Avoid using implementation types like 'ArrayList'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/MultiValueMap.java:109 Avoid using implementation types like 'ArrayList'; use the interface instead/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/StaticBucketMap.java:499 Avoid using implementation types like 'ArrayList'; use the interface instead

Coupling Rules - 63

119Friday, 28 August 2009

Page 120: Code Quality in Ruby and Java

Design Rules• Use singleton (class has nothing but static methods)

• Simplify boolean returns

• Simplify boolean expressions

• Switch statements should have a default

• Avoid deeply nested if statements

• Avoid reassigning parameters

• Switch density (statements to labels)

• Constructor calls overridable method

• Accessor class generation

• Final field should be static

• Close resource

• Non static initializer

• Default label not last in switch statement

• Non case label in switch statement

• Optimizable toArray call

• Bad comparison

• Equals null

• Confusing ternary

• Instantiation to get class

• Idempotent operations

• Simple date format needs locale

• Immutable field

• Use locale with case conversions

• Avoid protected field in final class

• Assignment to non final static

• Missing static method in non-instantiable class

• Avoid synchronized at method level

• Missing break in switch

• Use notifyAll() instead of notify()

• Avoid instanceOf checks in catch clause

• Abstract class without abstract method

• Simplify conditional

• Compare objects with equals

• Position literals first in comparisons

• Unnecessary local before return

• Non threadsafe singleton

• Uncommented empty method

• Uncommented empty constructor

• Avoid constants interface

• Unsynchronized static date formatter

• Preserve stack trace

• Use collection isEmpty()

• Class with only private constructors should be final

• Empty method in abstract class should be abstract

• Singular field

• Return empty array rather than null

• Abstract class without any method

• Too few branches for a switch statement

120Friday, 28 August 2009

Page 121: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:44 All methods are static. Consider using Singleton instead. Alternatively, you could add a private constructor or make the class abstract to silence this warning./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:60 Document empty constructor/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:59 Private field 'readMethods' could be made final; it is only initialized in the declaration or constructor./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:60 Private field 'writeMethods' could be made final; it is only initialized in the declaration or constructor./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:61 Private field 'types' could be made final; it is only initialized in the declaration or constructor./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:148 Document empty constructor/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:160 Overridable method 'getBean' called during object construction/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:276 New exception is thrown in catch block, original stack trace may be lost/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:379 New exception is thrown in catch block, original stack trace may be lost/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:383 New exception is thrown in catch block, original stack trace may be lost/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:616 Deeply nested if..then statements are hard to read/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:619 Deeply nested if..then statements are hard to read/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:641 Document empty method/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:651 Private field 'owner' could be made final; it is only initialized in the declaration or constructor./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:696 Avoid reassigning parameters such as 'value'/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:702 Deeply nested if..then statements are hard to read/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:708 Consider simply returning the value vs storing it in local variable 'answer'/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:712 New exception is thrown in catch block, original stack trace may be lost/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:716 New exception is thrown in catch block, original stack trace may be lost/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:420 Avoid if (x != y) ..; else ..;/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:538 New exception is thrown in catch block, original stack trace may be lost/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:552 New exception is thrown in catch block, original stack trace may be lost/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:232 Avoid reassigning parameters such as 'index'/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:232 Avoid reassigning parameters such as 'index'/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:246 Avoid reassigning parameters such as 'index'/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:246 Avoid reassigning parameters such as 'index'/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BufferUtils.java:36 All methods are static. Consider using Singleton instead.

Design Rules - 903

121Friday, 28 August 2009

Page 122: Code Quality in Ruby and Java

Imports Rules

• Duplicate imports• Don’t import java.lang• Unused imports• Import from same package• Too many static imports

122Friday, 28 August 2009

Page 123: Code Quality in Ruby and Java

No problems found!

Imports Rules - 0

123Friday, 28 August 2009

Page 124: Code Quality in Ruby and Java

JUnit Rules

• JUnit static suite• JUnit spelling• JUnit assertions should include messages• JUnit tests should include assert• TestClass without test cases• Unnecessary boolean assertion• Use assertEquals instead of assertTrue• Use assertSame instead of assertTrue• Use assertNull instead of assertTrue• Simplify boolean assertion

124Friday, 28 August 2009

Page 125: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/BulkTest.java:139 This class name ends with 'Test' but contains no test cases/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/BulkTest.java:265 This class name ends with 'Test' but contains no test cases/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestAll.java:31 This class name ends with 'Test' but contains no test cases/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestAllPackages.java:30 This class name ends with 'Test' but contains no test cases/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:97 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:98 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:117 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:119 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:128 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:131 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:140 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:141 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:142 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:143 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:144 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:145 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:154 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:158 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:180 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:184 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:199 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:200 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:205 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:206 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:215 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:216 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:218 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:219 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:253 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:257 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:262 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:263 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:268 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:269 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:281 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:282 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:289 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:290 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:298 JUnit assertions should include a message/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestClosureUtils.java:299 JUnit assertions should include a message

JUnit Rules - 1320

125Friday, 28 August 2009

Page 126: Code Quality in Ruby and Java

Naming Rules

• Short variable (3)

• Long variable (17)

• Short method name (3)

• Variable naming conventions

• Method naming conventions

• Class naming conventions

• Abstract naming

• Avoid dollar signs

• Method with same name as enclosing class

• Suspicious hashCode() method name

• Suspicious constant field name

• Suspicious equals method name

• Avoid field name matching type name

• Avoid field name matching method name

• No package

• Package case

• Misleading variable name

• Boolean get method name

126Friday, 28 August 2009

Page 127: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:88 Avoid variables with short names like n/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:105 Avoid variables with short names like n/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:106 Avoid variables with short names like m/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:121 Avoid variables with short names like n/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:153 Avoid variables with short names like i/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:154 Avoid variables with short names like n/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:72 Avoid excessively long variable names like defaultTransformers/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:606 Avoid excessively long variable names like propertyDescriptors/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:609 Avoid excessively long variable names like propertyDescriptor/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:788 Avoid variables with short names like ex/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:799 Avoid variables with short names like ex/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:73 Variables that are not final should not contain underscores (except for underscores in standard prefix/suffix)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:77 Variables that are not final should not contain underscores (except for underscores in standard prefix/suffix)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:83 Variables that are not final should not contain underscores (except for underscores in standard prefix/suffix)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:87 Variables that are not final should not contain underscores (except for underscores in standard prefix/suffix)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:419 Avoid variables with short names like a/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:419 Avoid variables with short names like b/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:443 Avoid variables with short names like sb/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:59 Variables that are not final should not contain underscores (except for underscores in standard prefix/suffix)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:60 Variables that are not final should not contain underscores (except for underscores in standard prefix/suffix)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:61 Variables that are not final should not contain underscores (except for underscores in standard prefix/suffix)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:290 Avoid variables with short names like i/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ClosureUtils.java:329 Avoid excessively long variable names like predicatesAndClosures/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ClosureUtils.java:350 Avoid excessively long variable names like objectsAndClosures/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ClosureUtils.java:360 Avoid variables with short names like i/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:61 The field name indicates a constant but its modifiers do not/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:61 Variables should start with a lowercase character/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:61 Variables that are not final should not contain underscores (except for underscores in standard prefix/suffix)./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:90 Avoid variables with short names like a/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:90 Avoid variables with short names like b/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:96 Avoid variables with short names like it/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:120 Avoid variables with short names like a

Naming Rules - 1433

127Friday, 28 August 2009

Page 128: Code Quality in Ruby and Java

Optimizations Rules

• Local variable could be final• Method argument could be final• Avoid instantiating objects in loops• Use ArrayList instead of vector• Simplify startsWith()• Use StringBuffer for string appends• Use arrays asList()• Avoid array loops• Unnecessary wrapper object creation• Add empty string

128Friday, 28 August 2009

Page 129: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:65 Parameter 'initialSize' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:88 Local variable 'n' could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:105 Parameter 'n' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:106 Local variable 'm' could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:121 Local variable 'n' could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:136 Parameter 'item' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:152 Parameter 'object' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:156 Local variable 'current' could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:174 Local variable 'size' could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ArrayStack.java:188 Local variable 'size' could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:90 Parameter 'bag' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:103 Parameter 'bag' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:120 Parameter 'bag' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:120 Parameter 'predicate' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:133 Parameter 'bag' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:133 Parameter 'type' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:149 Parameter 'bag' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:149 Parameter 'transformer' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:181 Parameter 'bag' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:194 Parameter 'bag' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:211 Parameter 'bag' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:211 Parameter 'predicate' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:224 Parameter 'bag' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:224 Parameter 'type' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:240 Parameter 'bag' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BagUtils.java:240 Parameter 'transformer' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:78 Parameter 'input' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:86 Parameter 'input' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:94 Parameter 'input' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:102 Parameter 'input' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:110 Parameter 'input' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:118 Parameter 'input' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:126 Parameter 'input' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:134 Parameter 'input' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:158 Parameter 'bean' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:194 Local variable 'newMap' could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:226 Local variable 'readableKeys' could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:228 Local variable 'key' could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:248 Parameter 'map' is not assigned and could be declared final/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:249 Local variable 'readableKeys' could be declared final

Optimizations Rules - 7192

129Friday, 28 August 2009

Page 130: Code Quality in Ruby and Java

Strict Exceptions Rules

• Avoid catching Throwable• Signature declares throws Exception• Exceptions as flow control• Avoid catching NullPointerException• Avoid throwing raw exception types• Avoid throwing NulllPointerException• Avoid rethrowing exception• Do not extend java.lang.Error• Do not throw exception in finally• Avoid throwing new instances of the same exception

130Friday, 28 August 2009

Page 131: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:344 Avoid catching NullPointerException; consider removing the cause of the NPE./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:166 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:1040 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:1071 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ComparatorUtils.java:96 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:348 Avoid catching NullPointerException; consider removing the cause of the NPE./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:359 Avoid catching NullPointerException; consider removing the cause of the NPE./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:1065 Avoid catching NullPointerException; consider removing the cause of the NPE./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:1153 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:618 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:621 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:641 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:644 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:662 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:665 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:685 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:703 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:718 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:733 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:736 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:750 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:767 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:784 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:805 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:808 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:842 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:365 Avoid throwing raw exception types./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:537 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:538 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/SequencedHashMap.java:777 Avoid throwing raw exception types./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:696 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/UnboundedFifoBuffer.java:125 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java:1263 Avoid throwing null pointer exceptions./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java:1406 Avoid catching NullPointerException; consider removing the cause of the NPE./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/buffer/BoundedFifoBuffer.java:233 Avoid throwing null pointer exceptions.

Strict Exception Rules - 125

131Friday, 28 August 2009

Page 132: Code Quality in Ruby and Java

Strings Rules

• Avoid duplicate literals• String instantiation• String toString()• Inefficient string buffering• Unnecessary case change• Use StringBuffer.length()• Append character with char• Consecutive literal appends• Use indexOf(char)• Inefficient empty string check• Insufficient StringBuffer declaration• Useless String.valueOf()• StringBuffer instantiation with char• Use equals() to compare strings• Avoid StringBuffer field

132Friday, 28 August 2009

Page 133: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:167 No need to call String.valueOf to append to a string./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:92 No need to call String.valueOf to append to a string./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:92 No need to call String.valueOf to append to a string./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:692 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:699 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:779 No need to call String.valueOf to append to a string./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:779 No need to call String.valueOf to append to a string./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DefaultMapBag.java:439 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DefaultMapBag.java:445 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DefaultMapBag.java:448 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DefaultMapBag.java:451 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:753 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:763 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1143 The String literal "' doesn't map to an existing object" appears 6 times in this file; the first occurrence is on line 1,143/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:806 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:618 The String literal "Iterator must not be null" appears 7 times in this file; the first occurrence is on line 618/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java:450 The String literal "Iterator remove() can only be called once after next()" appears 4 times in this file; the first occurrence is on line 450/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java:291 The String literal "Map is empty" appears 4 times in this file; the first occurrence is on line 291/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/buffer/BlockingBuffer.java:143 The String literal "Caused by InterruptedException: " appears 4 times in this file; the first occurrence is on line 143/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/functors/FunctorUtils.java:68 The String literal " was null" appears 4 times in this file; the first occurrence is on line 68/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/AbstractEmptyIterator.java:43 The String literal "Iterator contains no elements" appears 7 times in this file; the first occurrence is on line 43/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/LoopingListIterator.java:90 The String literal "There are no elements for this iterator to loop on" appears 4 times in this file; the first occurrence is on line 90/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/list/AbstractLinkedList.java:364 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/list/AbstractLinkedList.java:376 Avoid appending characters as strings in StringBuffer.append./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/list/FixedSizeList.java:72 The String literal "List is fixed size" appears 11 times in this file; the first occurrence is on line 72/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractHashedMap.java:1322 StringBuffer.append is called 2 consecutive times with literal Strings. Use a single append with a single String./Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/Flat3Map.java:629 The String literal "Invalid map index" appears 4 times in this file; the first occurrence is on line 629/Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/Flat3Map.java:1115 The String literal "(this Map)" appears 6 times in this file; the first occurrence is on line 1,115

Strings Rules - 214

133Friday, 28 August 2009

Page 134: Code Quality in Ruby and Java

Unused Code Rules

• Unused private field• Unused local variable• Unused private variable• Unused formal parameter

134Friday, 28 August 2009

Page 135: Code Quality in Ruby and Java

/Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/AbstractTestObject.java:170 Avoid unused local variables such as 'p'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/MapPerformance.java:54 Avoid unused local variables such as 'unmodHashMap'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/MapPerformance.java:55 Avoid unused local variables such as 'fastHashMap'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/MapPerformance.java:56 Avoid unused local variables such as 'treeMap'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/MapPerformance.java:57 Avoid unused local variables such as 'seqMap'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/MapPerformance.java:115 Avoid unused local variables such as 'total'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestBinaryHeap.java:313 Avoid unused local variables such as 'fail'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestCursorableLinkedList.java:975 Avoid unused local variables such as 'cursor'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestFactoryUtils.java:146 Avoid unused local variables such as 'dest'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestFactoryUtils.java:172 Avoid unused local variables such as 'dest'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestFactoryUtils.java:190 Avoid unused local variables such as 'dest'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestFactoryUtils.java:199 Avoid unused local variables such as 'created'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestFactoryUtils.java:211 Avoid unused local variables such as 'factory'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestFactoryUtils.java:268 Avoid unused local variables such as 'factory'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestFactoryUtils.java:287 Avoid unused local variables such as 'factory'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestFactoryUtils.java:297 Avoid unused local variables such as 'factory'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestIteratorUtils.java:250 Avoid unused local variables such as 'x'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestListUtils.java:154 Avoid unused local variables such as 'list'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestListUtils.java:171 Avoid unused local variables such as 'list'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestReferenceMap.java:203 Avoid unused private methods such as 'gc()'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestTransformerUtils.java:422 Avoid unused local variables such as 'trans'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/TestTransformerUtils.java:426 Avoid unused local variables such as 'trans'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bag/TestPredicatedBag.java:115 Avoid unused local variables such as 'bag'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bag/TestPredicatedBag.java:121 Avoid unused local variables such as 'bag'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bag/TestPredicatedSortedBag.java:83 Avoid unused local variables such as 'bag2'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bag/TestPredicatedSortedBag.java:85 Avoid unused local variables such as 'bag3'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bag/TestPredicatedSortedBag.java:89 Avoid unused local variables such as 'bag4'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bag/TestTypedBag.java:107 Avoid unused local variables such as 'bag'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bag/TestTypedBag.java:113 Avoid unused local variables such as 'bag'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bag/TestTypedSortedBag.java:73 Avoid unused local variables such as 'bag'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bag/TestTypedSortedBag.java:75 Avoid unused local variables such as 'bag3'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bag/TestTypedSortedBag.java:79 Avoid unused local variables such as 'bag4'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bidimap/AbstractTestSortedBidiMap.java:391 Avoid unused local variables such as 'fromEntry'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/bidimap/AbstractTestSortedBidiMap.java:580 Avoid unused local variables such as 'fromEntry'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/buffer/TestPredicatedBuffer.java:83 Avoid unused local variables such as 'o'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/iterators/AbstractTestMapIterator.java:138 Avoid unused local variables such as 'map'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/iterators/AbstractTestMapIterator.java:291 Avoid unused local variables such as 'map'./Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/iterators/AbstractTestMapIterator.java:315 Avoid unused local variables such as 'map'.

Unused Code Rules - 68

135Friday, 28 August 2009

Page 136: Code Quality in Ruby and Java

FindBugs

http://findbugs.sourceforge.net/

136Friday, 28 August 2009

Page 137: Code Quality in Ruby and Java

Implements 370 checks

137Friday, 28 August 2009

Page 138: Code Quality in Ruby and Java

DescriptionAM: Creates an empty jar file entryAM: Creates an empty zip file entryBC: Equals method should not assume anything about the type of its argumentBC: Random object created and used only onceBIT: Check for sign of bitwise operationCN: Class implements Cloneable but does not define or use clone methodCN: clone method does not call super.clone()CN: Class defines clone() but doesn't implement CloneableCo: Abstract class defines covariant compareTo() methodCo: Covariant compareTo() method definedDE: Method might drop exceptionDE: Method might ignore exceptionDMI: Don't use removeAll to clear a collectionDP: Classloaders should only be created inside doPrivileged blockDP: Method invoked that should be only be invoked inside a doPrivileged blockDm: Method invokes System.exit(...)Dm: Method invokes dangerous method runFinalizersOnExitES: Comparison of String parameter using == or !=ES: Comparison of String objects using == or !=Eq: Abstract class defines covariant equals() methodEq: Equals checks for noncompatible operandEq: Class defines compareTo(...) and uses Object.equals()Eq: equals method fails for subtypesEq: Covariant equals() method definedFI: Empty finalizer should be deletedFI: Explicit invocation of finalizerFI: Finalizer nulls fieldsFI: Finalizer only nulls fieldsFI: Finalizer does not call superclass finalizerFI: Finalizer nullifies superclass finalizerFI: Finalizer does nothing but call superclass finalizerGC: Unchecked type in generic callHE: Class defines equals() but not hashCode()HE: Class defines equals() and uses Object.hashCode()HE: Class defines hashCode() but not equals()HE: Class defines hashCode() and uses Object.equals()HE: Class inherits equals() and uses Object.hashCode()IC: Superclass uses subclass during initializationIMSE: Dubious catching of IllegalMonitorStateExceptionISC: Needless instantiation of class that only supplies static methodsIt: Iterator next() method can't throw NoSuchElementExceptionJ2EE: Store of non serializable object into HttpSessionJCIP: Fields of immutable classes should be finalNP: Method with Boolean return type returns explicit nullNP: Clone method may return nullNP: equals() method does not check for null argumentNP: toString method may return nullNm: Class names should start with an upper case letterNm: Class is not derived from an Exception, even though it is named as suchNm: Confusing method namesNm: Field names should start with a lower case letterNm: Use of identifier that is a keyword in later versions of JavaNm: Use of identifier that is a keyword in later versions of JavaNm: Method names should start with a lower case letterNm: Class names shouldn't shadow simple name of implemented interfaceNm: Class names shouldn't shadow simple name of superclassNm: Very confusing method names (but perhaps intentional)Nm: Method doesn't override method in superclass due to wrong package for parameterODR: Method may fail to close database resourceODR: Method may fail to close database resource on exceptionOS: Method may fail to close streamOS: Method may fail to close stream on exceptionRC: Suspicious reference comparison to constantRC: Suspicious reference comparison of Boolean valuesRR: Method ignores results of InputStream.read()RR: Method ignores results of InputStream.skip()RV: Method ignores exceptional return valueSI: Static initializer creates instance before all static final fields assignedSW: Certain swing methods needs to be invoked in Swing threadSe: Non-transient non-serializable instance field in serializable classSe: Non-serializable class has a serializable inner classSe: Non-serializable value stored into instance field of a serializable classSe: Comparator doesn't implement SerializableSe: Serializable inner classSe: serialVersionUID isn't finalSe: serialVersionUID isn't longSe: serialVersionUID isn't staticSe: Class is Serializable but its superclass doesn't define a void constructorSe: Class is Externalizable but doesn't define a void constructorSe: The readResolve method must be declared with a return type of Object.Se: Transient field that isn't set by deserialization.SnVI: Class is Serializable, but doesn't define serialVersionUIDUI: Usage of GetResource may be unsafe if class is extendedBC: Impossible castBC: Impossible downcastBC: Impossible downcast of toArray() resultBC: instanceof will always return falseBIT: Bitwise add of signed byte valueBIT: Incompatible bit masksBIT: Check to see if ((...) & 0) == 0BIT: Incompatible bit masksBIT: Bitwise OR of signed byte valueBIT: Check for sign of bitwise operationBOA: Class overrides a method implemented in super class Adapter wronglyBSHIFT: 32 bit int shifted by an amount not in the range 0..31Bx: Primitive value is unboxed and coerced for ternary operatorDLS: Dead store of class literalDLS: Overwritten incrementDMI: Bad constant value for monthDMI: hasNext method invokes nextDMI: Collections should not contain themselvesDMI: Invocation of hashCode on an arrayDMI: Double.longBitsToDouble invoked on an intDMI: Vacuous call to collectionsDm: Can't use reflection to check for presence of annotation without runtime retentionDm: Futile attempt to change max pool size of ScheduledThreadPoolExecutorDm: Creation of ScheduledThreadPoolExecutor with zero core threadsDm: Useless/vacuous call to EasyMock methodEC: equals() used to compare array and nonarrayEC: Invocation of equals() on an array, which is equivalent to ==EC: equals(...) used to compare incompatible arraysEC: Call to equals() with null argumentEC: Call to equals() comparing unrelated class and interfaceEC: Call to equals() comparing different interface typesEC: Call to equals() comparing different typesEC: Using pointer equality to compare different typesEq: equals method always returns falseEq: equals method always returns trueEq: equals method compares class names rather than class objectsEq: Covariant equals() method defined for enumEq: equals() method defined that doesn't override equals(Object)Eq: equals() method defined that doesn't override Object.equals(Object)Eq: equals method overrides equals in superclass and may not be symmetricEq: Covariant equals() method defined, Object.equals(Object) inheritedFE: Doomed test for equality to NaNFS: Format string placeholder incompatible with passed argumentFS: The type of a supplied argument doesn't match format specifierFS: MessageFormat supplied where printf style format expectedFS: More arguments are passed than are actually used in the format stringFS: Illegal format stringFS: Format string references missing argumentFS: No previous argument for format stringGC: No relationship between generic parameter and method argumentHE: Signature declares use of unhashable class in hashed constructHE: Use of class without a hashCode() method in a hashed data structureICAST: integral value cast to double and then passed to Math.ceilICAST: int value cast to float and then passed to Math.roundIJU: JUnit assertion in run method will not be noticed by JUnitIJU: TestCase declares a bad suite methodIJU: TestCase has no testsIJU: TestCase defines setUp that doesn't call super.setUp()IJU: TestCase implements a non-static suite methodIJU: TestCase defines tearDown that doesn't call super.tearDown()IL: A collection is added to itselfIL: An apparent infinite loopIL: An apparent infinite recursive loopIM: Integer multiply of result of integer remainderINT: Bad comparison of nonnegative value with negative constantINT: Bad comparison of signed byteIO: Doomed attempt to append to an object output streamIP: A parameter is dead upon entry to a method but overwrittenMF: Class defines field that masks a superclass fieldMF: Method defines a variable that obscures a fieldNP: Null pointer dereferenceNP: Null pointer dereference in method on exception pathNP: Method does not check for null argumentNP: close() invoked on a value that is always nullNP: Null value is guaranteed to be dereferencedNP: Value is null and guaranteed to be dereferenced on exception pathNP: Method call passes null to a nonnull parameterNP: Method may return null, but is declared @NonNullNP: A known null value is checked to see if it is an instance of a typeNP: Possible null pointer dereferenceNP: Possible null pointer dereference in method on exception pathNP: Method call passes null for nonnull parameterNP: Method call passes null for nonnull parameterNP: Non-virtual method call passes null for nonnull parameterNP: Store of null value into field annotated NonNullNP: Read of unwritten fieldNm: Class defines equal(Object); should it be equals(Object)?Nm: Class defines hashcode(); should it be hashCode()?Nm: Class defines tostring(); should it be toString()?Nm: Apparent method/constructor confusionNm: Very confusing method namesNm: Method doesn't override method in superclass due to wrong package for parameterQBA: Method assigns boolean literal in boolean expressionRC: Suspicious reference comparisonRCN: Nullcheck of value previously dereferencedRE: Invalid syntax for regular expressionRE: File.separator used for regular expressionRE: "." used for regular expressionRV: Random value from 0 to 1 is coerced to the integer 0RV: Bad attempt to compute absolute value of signed 32-bit hashcodeRV: Bad attempt to compute absolute value of signed 32-bit random integerRV: Exception created and dropped rather than thrownRV: Method ignores return valueRpC: Repeated conditional testsSA: Double assignment of fieldSA: Self assignment of fieldSA: Self comparison of field with itselfSA: Nonsensical self computation involving a field (e.g., x & x)SA: Self comparison of value with itselfSA: Nonsensical self computation involving a variable (e.g., x & x)SF: Dead store due to switch statement fall throughSF: Dead store due to switch statement fall through to throwSIC: Deadly embrace of non-static inner class and thread localSIO: Unnecessary type check done using instanceof operatorSQL: Method attempts to access a prepared statement parameter with index 0SQL: Method attempts to access a result set field with index 0STI: Unneeded use of currentThread() call, to call interrupted()STI: Static Thread.interrupted() method invoked on thread instanceSe: Method must be private in order for serialization to workSe: The readResolve method must not be declared as a static method.TQ: Value annotated as carrying a type qualifier used where a value that must not carry that qualifier is requiredTQ: Value that might not carry a type qualifier is always used in a way requires that type qualifierTQ: Value that might carry a type qualifier is always used in a way prohibits it from having that type qualifierTQ: Value annotated as never carrying a type qualifier used where value carrying that qualifier is requiredUMAC: Uncallable method defined in anonymous classUR: Uninitialized read of field in constructorUR: Uninitialized read of field method called from constructor of superclassUSELESS_STRING: Invocation of toString on an arrayUSELESS_STRING: Invocation of toString on an arrayUSELESS_STRING: Array formatted in useless way using format stringUwF: Field only ever set to nullUwF: Unwritten fieldVA: Primitive array passed to function expecting a variable number of object argumentsLG: Potential lost logger changes due to weak reference in OpenJDKOBL: Method may fail to clean up stream or resourceDm: Consider using Locale parameterized version of invoked methodEI: May expose internal representation by returning reference to mutable object

EI2: May expose internal representation by incorporating reference to mutable object

FI: Finalizer should be protected, not public

MS: May expose internal static state by storing a mutable object into a static field

MS: Field isn't final and can't be protected from malicious code

MS: Public static method may expose internal representation by returning array

MS: Field should be both final and package protected

MS: Field is a mutable array

MS: Field is a mutable Hashtable

MS: Field should be moved out of an interface and made package protected

MS: Field should be package protected

MS: Field isn't final but should be

DC: Possible double check of fieldDL: Synchronization on Boolean could lead to deadlockDL: Synchronization on boxed primitive could lead to deadlockDL: Synchronization on interned String could lead to deadlockDL: Synchronization on boxed primitive valuesDm: Monitor wait() called on ConditionDm: A thread was created using the default empty run methodESync: Empty synchronized blockIS: Inconsistent synchronizationIS: Field not guarded against concurrent accessJLM: Synchronization performed on LockLI: Incorrect lazy initialization of static fieldLI: Incorrect lazy initialization and update of static fieldML: Synchronization on field in futile attempt to guard that fieldML: Method synchronizes on an updated fieldMSF: Mutable servlet fieldMWN: Mismatched notify()MWN: Mismatched wait()NN: Naked notifyNP: Synchronize and null check on the same field.No: Using notify() rather than notifyAll()RS: Class's readObject() method is synchronizedRV: Return value of putIfAbsent ignored, value passed to putIfAbsent reusedRu: Invokes run on a thread (did you mean to start it instead?)SC: Constructor invokes Thread.start()SP: Method spins on fieldSTCAL: Call to static CalendarSTCAL: Call to static DateFormatSTCAL: Static CalendarSTCAL: Static DateFormatSWL: Method calls Thread.sleep() with a lock heldTLW: Wait with two locks heldUG: Unsynchronized get method, synchronized set methodUL: Method does not release lock on all pathsUL: Method does not release lock on all exception pathsUW: Unconditional waitVO: A volatile reference to an array doesn't treat the array elements as volatileWL: Sychronization on getClass rather than class literalWS: Class's writeObject() method is synchronized but nothing else isWa: Condition.await() not in loopWa: Wait not in loopBx: Primitive value is boxed and then immediately unboxedBx: Primitive value is boxed then unboxed to perform primitive coercionBx: Method allocates a boxed primitive just to call toStringBx: Method invokes inefficient floating-point Number constructor; use static valueOf insteadBx: Method invokes inefficient Number constructor; use static valueOf insteadDm: The equals and hashCode methods of URL are blockingDm: Maps and sets of URLs can be performance hogsDm: Method invokes inefficient Boolean constructor; use Boolean.valueOf(...) insteadDm: Explicit garbage collection; extremely dubious except in benchmarking codeDm: Method allocates an object, only to get the class objectDm: Use the nextInt method of Random rather than nextDouble to generate a random integerDm: Method invokes inefficient new String(String) constructorDm: Method invokes toString() method on a StringDm: Method invokes inefficient new String() constructorHSC: Huge string constants is duplicated across multiple class filesITA: Method uses toArray() with zero-length array argumentSBSC: Method concatenates strings using + in a loopSIC: Should be a static inner classSIC: Could be refactored into a named static inner classSIC: Could be refactored into a static inner classSS: Unread field: should this field be static?UM: Method calls static Math class method on a constant valueUPM: Private method is never calledUrF: Unread fieldUuF: Unused fieldWMI: Inefficient use of keySet iterator instead of entrySet iteratorDm: Hardcoded constant database passwordDm: Empty database passwordHRS: HTTP cookie formed from untrusted inputHRS: HTTP Response splitting vulnerabilitySQL: Nonconstant string passed to execute method on an SQL statementSQL: A prepared statement is generated from a nonconstant StringXSS: JSP reflected cross site scripting vulnerabilityXSS: Servlet reflected cross site scripting vulnerabilityXSS: Servlet reflected cross site scripting vulnerabilityBC: Questionable cast to abstract collectionBC: Questionable cast to concrete collectionBC: Unchecked/unconfirmed castBC: instanceof will always return trueBSHIFT: Unsigned right shift cast to short/byteCI: Class is final but declares protected fieldDB: Method uses the same code for two branchesDB: Method uses the same code for two switch clausesDLS: Dead store to local variableDLS: Useless assignment in return statementDLS: Dead store of null to local variableDMI: Code contains a hard coded reference to an absolute pathnameDMI: Non serializable object written to ObjectOutputDMI: Invocation of substring(0), which returns the original valueDm: Thread passed where Runnable expectedEq: Class doesn't override equals in superclassEq: Unusual equals methodFE: Test for floating point equalityFS: Non-Boolean argument formatted using %b format specifierIA: Ambiguous invocation of either an inherited or outer methodIC: Initialization circularityICAST: integral division result cast to double or floatICAST: Result of integer multiplication cast to longIM: Computation of average could overflowIM: Check for oddness that won't work for negative numbersINT: Integer remainder modulo 1INT: Vacuous comparison of integer valueMTIA: Class extends Servlet class and uses instance variablesMTIA: Class extends Struts Action class and uses instance variablesNP: Dereference of the result of readLine() without nullcheckNP: Immediate dereference of the result of readLine()NP: Load of known null valueNP: Possible null pointer dereference due to return value of called methodNP: Possible null pointer dereference on path that might be infeasibleNP: Parameter must be nonnull but is marked as nullableNS: Potentially dangerous use of non-short-circuit logicNS: Questionable use of non-short-circuit logicPZLA: Consider returning a zero length array rather than nullQF: Complicated, subtle or wrong increment in for-loopRCN: Redundant comparison of non-null value to nullRCN: Redundant comparison of two null valuesRCN: Redundant nullcheck of value known to be non-nullRCN: Redundant nullcheck of value known to be nullREC: Exception is caught when Exception is not thrownRI: Class implements same interface as superclassRV: Method checks to see if result of String.indexOf is positiveRV: Method discards result of readLine after checking if it is nonnullRV: Remainder of hashCode could be negativeRV: Remainder of 32-bit signed random integerSA: Double assignment of local variableSA: Self assignment of local variableSF: Switch statement found where one case falls through to the next caseSF: Switch statement found where default case is missingST: Write to static field from instance methodSe: private readResolve method not inherited by subclassesSe: Transient field of class that isn't Serializable.TQ: Explicit annotation inconsistent with useTQ: Explicit annotation inconsistent with useUCF: Useless control flowUCF: Useless control flow to next lineUwF: Field not initialized in constructorXFB: Method directly allocates a specific implementation of xml interfaces

CategoryBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practice

Bad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceBad practiceCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectness

CorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectness

CorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectness

Correctness

Correctness

Correctness

CorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectnessCorrectness

ExperimentalExperimentalInternationalizationMalicious code vulnerabilityMalicious code vulnerabilityMalicious code vulnerabilityMalicious code vulnerabilityMalicious code vulnerabilityMalicious code vulnerabilityMalicious code vulnerabilityMalicious code vulnerabilityMalicious code vulnerabilityMalicious code vulnerabilityMalicious code vulnerabilityMalicious code vulnerabilityMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessMultithreaded correctnessPerformancePerformancePerformancePerformance

PerformancePerformancePerformancePerformancePerformancePerformancePerformance

PerformancePerformancePerformancePerformancePerformancePerformancePerformancePerformancePerformancePerformancePerformancePerformancePerformancePerformancePerformanceSecuritySecuritySecuritySecuritySecuritySecuritySecuritySecuritySecurityDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgyDodgy

138Friday, 28 August 2009

Page 139: Code Quality in Ruby and Java

Some are the same as checks in PMD,

some are different

139Friday, 28 August 2009

Page 140: Code Quality in Ruby and Java

Checkstyle

http://checkstyle.sourceforge.net/

140Friday, 28 August 2009

Page 141: Code Quality in Ruby and Java

Implements 128 checks

141Friday, 28 August 2009

Page 142: Code Quality in Ruby and Java

AbstractClassNameAnnotationUseStyleAnonInnerLengthArrayTrailingCommaArrayTypeStyleAvoidInlineConditionalsAvoidNestedBlocksAvoidStarImportAvoidStaticImportBooleanExpressionComplexityClassDataAbstractionCouplingClassFanOutComplexityClassTypeParameterNameConstantNameCovariantEqualsCyclomaticComplexityDeclarationOrder

DefaultComesLastDescendantTokenDesignForExtensionDoubleCheckedLocking

EmptyBlockEmptyForInitializerPad

EmptyForIteratorPad

EmptyStatementEqualsAvoidNull

EqualsHashCodeExecutableStatementCountExplicitInitialization

FallThrough

FileLengthFileTabCharacterFinalClassFinalLocalVariableFinalParametersGenericWhitespaceHeaderHiddenFieldHideUtilityClassConstructorIllegalCatchIllegalImportIllegalInstantiationIllegalThrowsIllegalTokenIllegalTokenTextIllegalTypeImportControlImportOrderIndentationInnerAssignmentInterfaceIsTypeJUnitTestCase

JavaNCSS

JavadocMethodJavadocPackageJavadocStyleJavadocTypeJavadocVariableLeftCurlyLineLengthLocalFinalVariableNameLocalVariableNameMagicNumberMemberNameMethodLengthMethodNameMethodParamPad

MethodTypeParameterNameMissingCtorMissingDeprecatedMissingOverrideMissingSwitchDefaultModifiedControlVariableModifierOrder

MultipleStringLiteralsMultipleVariableDeclarationsMutableException

NPathComplexityNeedBracesNestedIfDepthNestedTryDepthNewlineAtEndOfFileNoCloneNoFinalizerNoWhitespaceAfterNoWhitespaceBeforeOperatorWrapOuterTypeNumberPackageAnnotationPackageDeclarationPackageNameParameterAssignmentParameterNameParameterNumberParenPad

RedundantImportRedundantModifierRedundantThrows

RegexpRegexpHeaderRegexpMultilineRegexpSinglelineRegexpSinglelineJavaRequireThisReturnCountRightCurlySimplifyBooleanExpressionSimplifyBooleanReturnStaticVariableNameStrictDuplicateCode

StringLiteralEqualitySuperCloneSuperFinalizeSuppressWarningsThrowsCountTodoCommentTrailingCommentTranslation

TypeNameTypecastParenPadUncommentedMainUnnecessaryParenthesesUnusedImportsUpperEllVisibilityModifierWhitespaceAfter

WhitespaceAroundWriteTag

Ensures that the names of abstract classes conforming to some regular expression.This check controls the style with the usage of annotations.Checks for long anonymous inner classes.Checks if array initialization contains optional trailing comma.Checks the style of array type definitions.Detects inline conditionals.Finds nested blocks.Check that finds import statements that use the * notation.Check that finds static imports.Restricts nested boolean operators (&&, ||, &, | and ^) to a specified depth (default = 3).This metric measures the number of instantiations of other classes within the given class.The number of other classes a given class relies on.Checks that class type parameter names conform to a format specified by the format property.Checks that constant names conform to a format specified by the format property.Checks that if a class defines a covariant method equals, then it defines method equals(java.lang.Object).Checks cyclomatic complexity against a specified limit.Checks that the parts of a class or interface declaration appear in the order suggested by the Code Conventions for the Java Programming Language.Check that the default is after all the cases in a switch statement.Checks for restricted tokens beneath other tokens.Checks that classes are designed for inheritance.Detect the double-checked locking idiom, a technique that tries to avoid synchronization overhead but is incorrect because of subtle artifacts of the java memory model.Checks for empty blocks.Checks the padding of an empty for initializer; that is whether a space is required at an empty for initializer, or such spaces are forbidden.Checks the padding of an empty for iterator; that is whether a space is required at an empty for iterator, or such spaces are forbidden.Detects empty statements (standalone ';').Checks that any combination of String literals with optional assignment is on the left side of an equals() comparison.Checks that classes that override equals() also override hashCode().Restricts the number of executable statements to a specified limit (default = 30).Checks if any class or object member explicitly initialized to default for its type value (null for object references, zero for numeric types and char and false for boolean.Checks for fall through in switch statements Finds locations where a case contains Java code - but lacks a break, return, throw or continue statement.Checks for long source files.Checks to see if a file contains a tab character.Checks that class which has only private ctors is declared as final.Ensures that local variables that never get their values changed, must be declared final.Check that method/constructor/catch/foreach parameters are final.Checks that the whitespace around the Generic tokens < and > are correct to the typical convention.Checks the header of the source against a fixed header file.Checks that a local variable or a parameter does not shadow a field that is defined in the same class.Make sure that utility classes (classes that contain only static methods) do not have a public constructor.Catching java.lang.Exception, java.lang.Error or java.lang.RuntimeException is almost never acceptable.Checks for imports from a set of illegal packages.Checks for illegal instantiations where a factory method is preferred.Throwing java.lang.Error or java.lang.RuntimeException is almost never acceptable.Checks for illegal tokens.Checks for illegal token text.Checks that particular class are never used as types in variable declarations, return values or parameters.Check that controls what packages can be imported in each package.Class to check the ordering/grouping of imports.Checks correct indentation of Java Code.Checks for assignments in subexpressions, such as in String s = Integer.toString(i = 2);.Implements Bloch, Effective Java, Item 17 - Use Interfaces only to define types.Ensures that the setUp(), tearDown()methods are named correctly, have no arguments, return void and are either public or protected.This check calculates the Non Commenting Source Statements (NCSS) metric for java source files and methods.Checks the Javadoc of a method or constructor.Checks that all packages have a package documentation.Custom Checkstyle Check to validate Javadoc.Checks the Javadoc of a type.Checks that a variable has Javadoc comment.Checks the placement of left curly braces on types, methods and other blocks:Checks for long lines.Checks that local final variable names conform to a format specified by the format property.Checks that local, non-final variable names conform to a format specified by the format property.Checks for magic numbers.Checks that instance variable names conform to a format specified by the format property.Checks for long methods.Checks that method names conform to a format specified by the format property.Checks the padding between the identifier of a method definition, constructor definition, method call, or constructor invocation; and the left parenthesis of the parameter list.Checks that class type parameter names conform to a format specified by the format property.Checks that classes (except abstract one) define a ctor and don't rely on the default one.This class is used to verify that both theThis class is used to verify that theChecks that switch statement has "default" clause.Check for ensuring that for loop control variables are not modified inside the for block.Checks that the order of modifiers conforms to the suggestions in the Java Language specification, sections 8.1.1, 8.3.1 and 8.4.3.Checks for multiple occurrences of the same string literal within a single file.Checks that each variable declaration is in its own statement and on its own line.Ensures that exceptions (defined as any class name conforming to some regular expression) are immutable.Checks the npath complexity against a specified limit (default = 200).Checks for braces around code blocks.Restricts nested if-else blocks to a specified depth (default = 1).Restricts nested try-catch-finally blocks to a specified depth (default = 1).Checks that there is a newline at the end of each file.Checks that the clone method is not overridden from the Object class.Checks that no method having zero parameters is defined using the name finalize.Checks that there is no whitespace after a token.Checks that there is no whitespace before a token.Checks line wrapping for operators.Checks for the number of defined types at the "outer" level.This check makes sure that all package annotations are in the package-info.java file.Ensures there is a package declaration.Checks that package names conform to a format specified by the format property.Disallow assignment of parameters.Checks that parameter names conform to a format specified by the format property.Checks the number of parameters that a method or constructor has.Checks the padding of parentheses; that is whether a space is required after a left parenthesis and before a right parenthesis, or such spaces are forbidden, with the exception that it does not check for padding of the right parenthesis at an empty for iterator.Checks for imports that are redundant.Checks for redundant modifiers in interface and annotation definitions.Checks for redundant exceptions declared in throws clause such as duplicates, unchecked exceptions or subclasses of another declared exception.A check that makes sure that a specified pattern exists (or not) in the file.Checks the header of the source against a header file that contains aImplementation of a check that looks that matches across multiple lines in any file type.Implementation of a check that looks for a single line in any file type.Implementation of a check that looks for a single line in Java files.Checks that code doesn't rely on the "this" default.Restricts return statements to a specified count (default = 2).Checks the placement of right curly braces.Checks for overly complicated boolean expressions.Checks for overly complicated boolean return statements.Checks that static, non-final variable names conform to a format specified by the format property.Performs a line-by-line comparison of all code lines and reports duplicate code if a sequence of lines differs only in indentation.Checks that string literals are not used with == or !=.Checks that an overriding clone() method invokes super.clone().Checks that an overriding finalize() method invokes super.finalize().This check allows you to specify what warnings thatRestricts throws statements to a specified count (default = 1).A check for TODO comments.The check to ensure that requires that comments be the only thing on a line.The TranslationCheck class helps to ensure the correct translation of code by checking property files for consistency regarding their keys.Checks that type names conform to a format specified by the format property.Checks the padding of parentheses for typecasts.Detects uncommented main methods.Checks if unnecessary parentheses are used in a statement or expression.Checks for unused import statements.Checks that long constants are defined with an upper ell.Checks visibility of class members.Checks that a token is followed by whitespace, with the exception that it does not check for whitespace after the semicolon of an empty for iterator.Checks that a token is surrounded by whitespace.Outputs a JavaDoc tag as information.

142Friday, 28 August 2009

Page 143: Code Quality in Ruby and Java

Some are the same as checks in PMD and Findbugs, some are different

143Friday, 28 August 2009

Page 144: Code Quality in Ruby and Java

All these tools allow filtering

144Friday, 28 August 2009

Page 145: Code Quality in Ruby and Java

PMD at the file level

145Friday, 28 August 2009

Page 146: Code Quality in Ruby and Java

Findbugs and Checkstyle at the file + check level

146Friday, 28 August 2009

Page 147: Code Quality in Ruby and Java

You can add your own checks to any of these, all are open source

147Friday, 28 August 2009

Page 148: Code Quality in Ruby and Java

You can use them at the command line, from Ant, or from Maven

148Friday, 28 August 2009

Page 149: Code Quality in Ruby and Java

There’s probably a plugin for your IDE as well

149Friday, 28 August 2009

Page 150: Code Quality in Ruby and Java

Many people use these in combination

150Friday, 28 August 2009

Page 151: Code Quality in Ruby and Java

151Friday, 28 August 2009

Page 152: Code Quality in Ruby and Java

Sonar

http://sonar.codehaus.org/

152Friday, 28 August 2009

Page 153: Code Quality in Ruby and Java

17/08/09 7:11 AMSonar

Page 1 of 1http://sonar.codehaus.org/

Monitoring metrics

Projects at risk are quickly and visually detected through the dashboard

that combines collected measures and calculated metrics on all your

projects

Time machine

Time machine highlights trends of the main metrics in real time : agile teams

can react rapidly. In case of outsourced projects, SONAR enables to set

contractual quality objectives

Market standards

Metrics related to coding conventions integrate more than 300 market

best-practice rules. Those rules are grouped into families to offer a

synthetic view (maintainability, reliability …)

Open source components

SONAR leverages the existing ecosystem of quality open source tools (ex. Checkstyle,

PMD, Maven, Cobertura …), to offer a fully integrated solution to development

environments and continuous integration tools

Easy navigation

SONAR enables to navigate seamlessly through various

granularity levels, from projects portfolio to source code level. This

gives transparency at all level (project, component, package …)

and enables the developer to take immediate and targeted actions

Download Features Screencasts Roadmap Documentation Community Blog

Code quality management platform

Sonar enables you to collect, analyze and report metrics on

source code. Sonar not only offers consolidated reporting on and

across projects throughout time, but it becomes the central place

to manage code quality

What is Sonar? Why use Sonar? Java & more

Powered by SonarSource

Visit Nemo, the live instance of Sonar

Get Sonar

Download the latest version,1.10, on August 14, 2009

Get Support

Choose what fits best yourneeds, Professional orCommunity support

Plugins

Extend the functionality withopen source andcommercial plugins

Sonar in action

To find out more, watch ascreencast or visit our publicinstance

Blog

Subscribe to our blog by email or

directly through the feed

Sonar 1.10 in screenshots

Source code analysis is not anend in itself, but a means to anend

Sonar TV : configuring codingrules

153Friday, 28 August 2009

Page 154: Code Quality in Ruby and Java

Sonar integrates easily into projects that use Maven2

154Friday, 28 August 2009

Page 155: Code Quality in Ruby and Java

155Friday, 28 August 2009

Page 156: Code Quality in Ruby and Java

156Friday, 28 August 2009

Page 157: Code Quality in Ruby and Java

157Friday, 28 August 2009

Page 158: Code Quality in Ruby and Java

158Friday, 28 August 2009

Page 159: Code Quality in Ruby and Java

It also provides trend graphs once it has been installed

159Friday, 28 August 2009

Page 160: Code Quality in Ruby and Java

Java code coverage

160Friday, 28 August 2009

Page 161: Code Quality in Ruby and Java

Emma (http://emma.sourceforge.net/)

Cobertura (http://cobertura.sourceforge.net/)

Clover (http://www.atlassian.com/software/clover/)

161Friday, 28 August 2009

Page 162: Code Quality in Ruby and Java

Differ in the mechanics of how code coverage is implemented

162Friday, 28 August 2009

Page 163: Code Quality in Ruby and Java

Cobertura and Clover let you fail a build if a coverage threshold is not met

163Friday, 28 August 2009

Page 164: Code Quality in Ruby and Java

Clover is commercial-ware with extra functionality:

- run last-failed tests first

- distribute test execution

164Friday, 28 August 2009

Page 165: Code Quality in Ruby and Java

Macker

http://www.innig.net/macker/index.html

165Friday, 28 August 2009

Page 166: Code Quality in Ruby and Java

Check for architectural layering by defining access rules between classes and packages

166Friday, 28 August 2009

Page 167: Code Quality in Ruby and Java

<?xml version="1.0"?><macker> <ruleset name="Simple example"> <access-rule> <deny> <from class="**Print*" /> <to class="java.**" /> </deny> </access-rule> </ruleset></macker>

167Friday, 28 August 2009

Page 168: Code Quality in Ruby and Java

public class PrintHelloWorld { public static void main(String[] args) { System.out.println("Hello world, as they say!"); } }

Checking ruleset: Simple example ...

Illegal reference from PrintHelloWorld to java.io.PrintStream

Illegal reference from PrintHelloWorld to java.lang.Object

Illegal reference from PrintHelloWorld to java.lang.System

168Friday, 28 August 2009

Page 169: Code Quality in Ruby and Java

<?xml version="1.0"?>

<macker> <ruleset name="Layering rules"> <var name="base" value="net.innig.macker.example.layering" /> <pattern name="gui" class="${base}.gui.**" /> <pattern name="model" class="${base}.model.**" /> <pattern name="persist" class="${base}.persistence.**" /> <access-rule> <message>Only the model can talk to the persistence layer</message> <deny> <to pattern="persist" /> <allow> <from pattern="persist"/> </allow> <allow> <from pattern="model"/> </allow> </deny> </access-rule> <access-rule> <message>The persistence layer can't access the model</message> <deny> <to pattern="model" /> <from pattern="persist" /> </deny> </access-rule> <access-rule> <message>The model and persistence layers can't access the GUI</message> <deny> <to pattern="gui" /> <from> <include pattern="model" /> <include pattern="persist" /> </from> </deny> </access-rule> <access-rule> <message>Persistence belongs in the persistence layer</message>

<deny> <to> <include class="java.sql.**" /> <include class="javax.sql.**" /> <include class="javax.jdo.**" /> </to> </deny> <allow> <from pattern="persist" /> </allow> </access-rule> <access-rule> <message>Swing and AWT calls belong in the GUI layer</message> <deny> <to> <include class="java.awt.**" /> <include class="javax.swing.**" /> </to> </deny> <allow> <from pattern="gui" /> </allow> </access-rule> </ruleset></macker>

169Friday, 28 August 2009

Page 170: Code Quality in Ruby and Java

Programmers are inherently human

170Friday, 28 August 2009

Page 171: Code Quality in Ruby and Java

They inevitably make mistakes

171Friday, 28 August 2009

Page 172: Code Quality in Ruby and Java

Automation helps reduce the cost of human mistakes

172Friday, 28 August 2009

Page 173: Code Quality in Ruby and Java

173Friday, 28 August 2009