Ensuring high code quality in Java development : tools and procedures Presented by Mikhail Vladimirov (Leximera, Inc. http://www.leximera.com) June, 2010
The overall goal of IT governance is to avoid project failures, minimize the number of situations requiring “remediation” initiatives and maximize ROI in IT. With the existing trend to outsource (inshore and outshore) the IT development function, corporations are adopting more strict IT governance and compliance policies. Promotion of efficient and effective IT controls in design and development help achieve some of the IT governance goals. The need for strict IT governance
Enforcing SDLC standard’s provisions IT governance is ensured, among other things, by enforcing the Corporate Software Development Life Cycle (SDLC) standard. The Build phase of the SDLC standard includes such activities as code reviews and unit testing.
Software quality & human factor <ul><li>“ Everybody wants to do a good job, and they work much better if they feel they are doing good work. If you deliberately downgrade quality, your team might go faster at first, but soon the demoralization of producing crap will overwhelm any gains you temporarily made from not testing, or not reviewing, or not sticking to standards.” </li></ul><ul><li>[Kent Beck. Extreme Programming Explained. 1999] </li></ul>
Broken Window Theory (and human factor) <ul><li>“ One broken window, left unrepaired for any substantial length of time, instills in the inhabitants [ developers ] of the building [ project code ] a sense of abandonment - a sense that the powers that be [ tech leads, stakeholders ] don't care about the building. So another window gets broken. People start littering. Graffiti appears. Serious structural damage begins. In a relatively short space of time, the building becomes damaged beyond the owner's desire to fix it. and the sense of abandonment becomes reality. Don't leave ‘broken windows’ unrepaired. Fix each one as soon as it is discovered.” </li></ul><ul><li>[Andrew Hunt and David Thomas. The Pragmatic Programmer: From Journeyman to Master , 1999] </li></ul>
How we measure software quality? [controversial topic] <ul><li>Hallmarks of quality software are, among many other things, the ease of testing, maintenance, fixing bugs, modification and portability which directly affect its TCO parameter. </li></ul><ul><li>For practical purpose, the fewer “stupid”, “@#$%^” and similar adjectives are used at every step of the software life-cycle, the better the software is. </li></ul><ul><li>One simple way to ensure quality is to </li></ul>
Unit testing is an integral part of SDLC Unit tests are written contracts that individual units of new or modified/re-factored code must satisfy (work as per software design specification). Creating unit tests in parallel with code (or even ahead of it) leads to the creation of more maintainable and functional code. It also helps reduce uncertainty of the code correctness early in the Build phase of the SDLC. Unit tests document the behaviour of the system by showing the inputs/outputs and the API in action.
Unit testing: extending scope JUnit is the standard automated testing framework used in Java development. This system is normally supplemented by such testing toolkits as JMockit and EasyMock which can be used to augment simple unit tests and build a solid platform for Test-Driven Development.
Multithreaded unit tests One of the areas JUnit doesn't cover is that of multithreaded unit tests, which are absolutely needed, for instance, to verify thread-safety of the new piece of code or a 3 rd party module / library.
Adding more value: code coverage tools <ul><li>The benefits of unit/integration testing toolkits can be further enhanced by integrating them with Java code coverage tools, e.g. Cobertura, EMMA, IBM RAD-based toolkit, et al. </li></ul>
Code coverage activity Code coverage tools report the percentage of code accessed during testing and provide code metrics at the class , method , line or basic block level that can help identify un-used/unreachable code. Un-used (e.g. legacy) code (normally shown in red in reports) can be potentially safely removed (if the complete test suites were run against it) or additional tests be created. The “greener” are the code coverage reports, the better code coverage is provided by the existing tests.
Code Coverage Activity (cont’d) Cobertura generated HTML report
Code Coverage Activity (cont’d) Eclipsed-based EMMA generated report (can also be exported into the HTML format)
Code review and analysis objectives <ul><li>Code review/analysis should: </li></ul><ul><li>Assess conformity with the business requirements / low level design document (software design spec) </li></ul><ul><li>Check compliance with the Company’s relevant standards </li></ul><ul><li>Identify possible code defects (bugs) </li></ul><ul><li>Give recommendations on ensuring compliance </li></ul><ul><li>Normally, there is one formal code review/analysis session conducted when code is [nearly?] 100% complete (or before QA takes over) . The formal review is preceded and followed by an arbitrary number of informal (e.g. peer-to-peer) code reviews to ensure code quality continuity. </li></ul>
Extreme Programming practice <ul><li>Some developers claim that the Pair Programming practice can be an excellent alternative to a formal code review (it stands to reason that partners should be compatible with each other in disposition, sharing the love to same IDE, etc.). </li></ul>
Roles and responsibilities in code review exercise <ul><li>The formal code review process requires identification and assignment of the following roles: </li></ul><ul><ul><li>Reviewer (senior team developer(s) or outside expert(s)) </li></ul></ul><ul><ul><li>Developer (code creator(s)) </li></ul></ul><ul><ul><li>[Optional] Tech Lead (a.k.a. Arbitrator), should the need for </li></ul></ul><ul><ul><li>this role arises </li></ul></ul>
Code review feedback document <ul><li>The code review is conducted and feedback/comments are supplied by the Reviewer. Feedback must be documented in a (free-text format) document which includes the following fields (optional fields are listed in brackets): </li></ul><ul><li> Project name </li></ul><ul><li> Work package name </li></ul><ul><li> Code review date </li></ul><ul><li> Reviewer(s)’s name(s) </li></ul><ul><li> Developer(s)’s name(s) </li></ul><ul><li> Comments/suggestions </li></ul><ul><li> [Priority] </li></ul><ul><li> [Target resolution date] / [Follow-up review date] </li></ul>
Manual code review (cont’d) <ul><li>Secure code practices (which is a huge topic on its own) are listed in the OWASP Java Project ( http://www.owasp.org/index.php/Category:OWASP_Java_Project ) . </li></ul>
Code management in modern IDEs Modern Integrated Development Environments (IDE), e.g. Eclipse, IntelliJ, NetBeans used for development on Java™ platform offer a powerful code management toolset that can do real-time syntax checking, on-demand re-factoring, formatting and more. For example, IDEs will generate visual clues to help developer see some code defects right away as they are typing. Eclipse, for instance, will underline the code that declares a variables but never uses it: Or even identify a possible null pointer situation that may happen at run-time:
Enforcing coding standard and guidelines: Code Formatting Template The compliance with coding standards is, in part, ensured by using a uniform code formatting template (which meets formatting guidelines, e.g. line length, size/type of the indent, comments, java statements layout, etc.) by all developers on the project. First, the template file meeting the standard’s criteria is created end exported (a one-time exercise), then the template file is cascaded to project developers who import and use it in their IDEs.
Automated code inspection and analysis This exercise is mostly done via static code analysis tools that inspect program’s source code or generated byte-code and compare extracted elements against the repository of known defective code patterns. Static analysis solutions not only detect but in many cases offer corrective actions to fix coding problems. A good analyzer should have a good ratio of real issues count to the number of (usually harmless) warnings. Many tools provide means to create user-specific rule sets. The grouping by defect categories, ranking and setting priorities help with defect systematization.
Commercial tools <ul><li>Klocwork </li></ul><ul><li>Parasoft </li></ul><ul><li>IBM Rational Software Analyzer (RSA) </li></ul><ul><li>RSA is offered as a stand-alone product (Developer & Enterprise editions) and a version of it is also embedded into the Rational Application Developer (RAD) IDE. </li></ul>
RSA editions <ul><li>Developer edition offers more features and rules options compared to RAD’s Analyzer (e.g. it offers support for C/C++, more rule sets and more options in each rule set). </li></ul>
Free automated code analysis tools <ul><li>There are many free static code analyzers in the area: </li></ul><ul><li>FindBugs ( http://findbugs.sourceforge.net/ ) </li></ul><ul><li>CheckStyle ( http://checkstyle.sourceforge.net ) </li></ul><ul><li>PMD ( http://pmd.sourceforge.net ) </li></ul><ul><li>A viable alternative to proprietary (and expensive?) products can be FindBugs. </li></ul>
FindBugs: sample diagnostics report <ul><li>Class <name> defines non-transient non-serializable instance field <name> </li></ul><ul><li>Class <name> may fail to close PreparedStatement </li></ul><ul><li>Class <name> defines equals and uses Object.hashCode() </li></ul><ul><li>Method <name> uses the same code for two branches </li></ul><ul><li>Nullcheck of <name> at line <#> of value previously dereferenced </li></ul><ul><li>Possible null pointer dereference of <object name> </li></ul><ul><li>... Inconsistent synchronization of <method name> </li></ul><ul><li>Concatenation of strings using + in a loop </li></ul><ul><li>Invocation of substring(0) (which returns the original value) </li></ul><ul><li>Inefficient invocation of new Integer(int) constructor (use Integer.valueOf(int) instead) </li></ul><ul><li>Potentially dangerous use of non-short-circuit logic (e.g. : </li></ul><ul><li>if (dList != null & dList () > 0) ) </li></ul>
Stacking up FindBugs to IBM Software Analyzer In comparison with IBM Software Analyzer, FindBugs, out of the box, definitely lacks such features as Visual Summary and PDF reports as well as some additional features. Some developers would argue that FindBugs offers plenty of information in a way that lends itself to report generation in any imaginable format. RSA offers an array of features that have their own specific audiences, e.g. the Java Architectural Discovery feature helps identify design patterns used in the project (e.g. Singleton or Factory method).
Stacking up FindBugs to IBM Software Analyzer (cont’d) Extensive Java metrics section of RSA offers a wide range of various heuristic-based ratios (e.g. lack of cohesion) the usefulness of some of which remains to be seen:
Stacking up FindBugs to IBM Software Analyzer (cont’d) When it comes to the hard-core functionality, FindBugs provides better diagnostics and easier result extraction (e.g. copying the results in the flat text format in the clipboard). For example, the following sub-optimal creation of an instance of a Long number: Long longWeekEndDays = new Long (3); was identified by both products. IBM’s RSA gives the following recommendation: Avoid instantiating a Number using new FindBugs goes farther by advising on action required: inefficient new Long(long) constructor; use Long.valueOf(long) instead
Runtime metrics check: Window’s perfmon <ul><li>If the deployment platform of choice is Windows , the built-in performance monitoring tool, perfmon , can help capture critical performance metrics of your running application. </li></ul>
Runtime metrics check: JDK’s JConsole <ul><li>Java 5+ comes with a run-time metrics monitoring tool JConsole featuring a great dashboard. </li></ul>
JDK’s VisualVM <ul><li>Later versions of Java 6 come with an award-wining monitoring tool jvisualvm (sort of JConsole++). </li></ul>