Gary Windham, Assistant Director, Integration Infrastructure & Architecture, UITS
Ed Murphy, Assistant Director, Applications Development, UITS
Zachary Naiman, Kuali Development Manager, UITS
Clinton Lee, Consultant, The Burgundy Group
Leo Przybylski, KITT Development, UITS
Overview
This document attempts to fill some of the gaps in the daily workflow surrounding the Kuali implementation at the University of Arizona. It is intended to be a set of proposed recommendations to be reviewed and adopted by the Kuali Program Managers on the Mosaic Project. Our goal was to fill those gaps by creating guidelines and processes where there currently are none. It is our hope that UITS development teams will adopt the processes and procedures described in this document. Having the same processes as Mosaic development teams will ease the transition of KFS and KC from Mosaic to UITS.
The Development Environment
Currently, Kuali Implementation Technical Team (KITT) members connect to a Windows terminal server, ts.mosaic, for their development area. Each developer has been responsible for setting up his or her development area. This includes installation of server applications, such as Tomcat, and desktop applications, such as Eclipse. In order to minimize the amount of time a KITT member spends doing environment management we recommend a standard desktop "template" be created for KITT. This would include any server and desktop tools needed. When a new KITT member joins the team the standard template could be quickly copied to create a complete, functioning environment. This template would also serve as a disaster recovery tool.
We strongly recommend that no databases exist on ts.mosaic. All KITT members should connect to the same Oracle development database. KITT members should have a high level of privileges in the development database. The development database will be backed up nightly with 7 days worth of backups kept as archives.
See Appendix A for a diagram of the KFS development and production environments.
Continuous Integration (CI)
We recommend the selection of a continuous integration tool, such as Continuum or AntHill Pro3. Each time a KITT member commits a configuration or customization change to the Subversion repository the CI tool will perform a full build on the code base. If there are any problems with the build the appropriate people will be notified. If the build is good the CI tool will deploy the new build to the main development environment. It is in the main development environment that all the individual developer's changes get rolled up into one common environment. This tool will also be used to migrate changes to configuration and conversion environments. Movement of the code base to the test and staging environments needs to be managed by the quality assurance and change management process.
Development Standards
UITS will configure and support certain tools for use by Mosaic and UITS technical staff. Jira will be used for issue tracking. Confluence will be used for a collaborative workspace, and possibly as a technical document library. Subversion (SVN) will be used for version control and as the source code repository.
Coding Standards
- Dependency injection should be favored over service lookup
- No duplicated code across the entire application
- Tabs set to 4, but no hard tabs in code
- Use Eclipse's Refactor functionality when needing to rename/move any methods or files
- Use Eclipse's code generation functionality whenever possible
Design and Implementation
- Always favor readability over complexity
- Favor the use of design patterns where appropriate, but not a panacea
- If following a design pattern, say so in comments
- Don't get too abstract; you may understand it, but will the maintainer?
Methods
- Methods should perform just one task
- Methods should not exceed 30 lines of code; shorter is better. (However, don't sacrifice readability; i.e. one statement per line)
- Lines of code should readable without horizontal scrolling on a screen with 1024x768 resolution using Eclipse default Java editor font
- Don't add tracing comments to method; favor AOP instead; i.e. log("Entering method..."); ... log("Exiting method ...")
- Don't nest if blocks more than 3 deep
- Don't make if/else trees with more than 2 else's; i.e. if/else if/else
- No "side-effect" logic in getters and setters
- One entry, one exit to a method; exception allowed for an immediate param checking/return
- Always refactor after getting it to work. Agile philosophy: Make the method work, then make it better
Constants
- Use constants, not literals, except for minor variables like 0, 1, loop indices, etc.
- If constants represent business values that might change per deployment, consider moving them into the database as system params
Favor Java 5 Features
- Enums versus constants, especially String constants
- Generics
- Autoboxing (watch for nulls!)
- For-each loop
- Annotations (JPA will dictate more annotations anyway)
- See also Rice Test Framework Annotations Guide
- Do not use annotations for items that affect the runtime (for example, use a marker interface instead)
- Do not use static imports; exception allowed for JUnit test cases
Struts and Views
- No business logic in Struts Actions
- No business logic in Struts Forms
- Avoid using Struts tags when corresponding JSTL tag available
- Do not use JSP scriptlets
- Never call services from JSP
- Keep JSPs very lean, one tag file per panel per page
- Use javatagdoc to document tags
- Make sure descriptions and attributes are documented for each custom tag
Business Objects
- Override equals() and hashCode() methods on all BOs
- Favor using Eclipse to generate the equals() and hashCode() methods
- JUnit Add-Ons Tools are being evaluated for inclusion in project to test equals/hashCode implementation
- When comparing persisted equality, use ObjectUtils method
Comments
- Include comments in the code on "why" in any case when "why" isn't readily apparent - for example, extra complexity
- Comment interfaces and abstract classes well as this forms basis for our Service APIs
- Comment interface and abstract class methods with JavaDoc, including a description of what the method does, why it does it and input parameters, return value, and anticipated exceptions that could be thrown (runtime or checked)
- Comment on the implementation anything interesting/special/complex about the way the interface is implemented
- JavaDoc comments should be included for all public, protected, and default visibility scopes
- Don't comment private with JavaDoc so we don't depend on interfaces that could be refactored
- Code should use descriptive names indicating what and how; comments should explain why
- If the method throws an unchecked exception, it should be manually added to the JavaDoc comments
- Internal method comments should be provided to explain necessary complexity, but not as crutch for poor names or overly complex code
- No "commented out" code should be committed
- If implementing a design pattern, say so in comments
Bug Fixes
- Don't include JIRA #s in comments (relate JIRAs to commits via SVN)
- Don't include specific bug fixes in comments, but keep comments up to date with any code changes
- No TODO comments in committed code
- Comment any deviation from our coding standards including an explanation for the deviation (non-commented deviations can be considered a mistake)
- SQL scripts should follow the same comment guidance
Committing Code Changes
- Update from the repository prior to committing code, review differences with the repository, and merge changes as necessary.
- Make sure commits have comments, including a short description and Jira #.
- Make sure all code compiles prior to committing code.
- Make sure the WebApp runs prior to committing code.
- Make sure the unit tests pass prior to committing code
- Broken Unit Tests are not permitted
- Unit tests for functionality that does not exist may. See Version Control with SVN Policy
- Consult with a Technical Lead on larger more complex commits (for example, commits that you've worked on for more than a day, affect more than a few files, etc). Basically, does it have an above average chance to break the build? If so, review it with a Technical Lead.
- Consult with a Technical Lead on creating separate branches to isolate complex or experimental work.
Jira
- Use JIRA to track issues and bugs.
- Create a JIRA task/bug for any work you are doing that is not already represented in JIRA, and discuss such work with your Technical Lead or Project Manager.
- Mark JIRA tasks complete when the work is done and tested in the daily build environment.
- Mark JIRA bugs resolved when the fix is done and tested in the daily build environment.
- Keep your "In Progress" flags up to date on JIRAs.
- Periodically review and close resolved JIRAs that you created.
- Triage issues for your assigned components
- Diligently watch Jira issues
- Check email/issues 2x/day
- Promptly respond to comments on issues
Unit Tests
- Use red/green unit testing methodology
- Unit tests start failing and progress to green as functionality is completed
- Create Unit Tests prior to considering a development task complete.
- Create Unit Tests that validate Service Implementation and Rule class functionality being developed.
- Create HTMLUnit Tests that validate the main success scenario and main alternate scenarios of the functionality being developed.
- Create Unit Tests for any bug that is reported. Make the test pass prior to resolving the JIRA for the bug.
Appendix A
Diagram of KFS development and production environments.