Friday, July 25, 2008

Java Coding Standards:Exception Handling,Logging,JUnits

At enterprise level writing robust code is essential and test driven development technique is helping one in achieving that. So while you code your business components then writing JUnits in parallel is an essential exercise. This helps in checking all positive and negative scenarios which your code can get exposed to. While putting erroneous conditions, your code will behave erroneously,throwing relevant exceptions at right levels with messages making correct sense where and what went wrong. Besides correct exception handling,ensuring right way of logging errors,debug information and general information is significant from testing your code correctly.This post will focus on exception handling,logging and JUnits related coding standards.

In this post focus is writing/compiling standards required for Exception handling,logging and JUnits coding. I am sure these tips will give you some practical insight to achieve

Exception Handling
- Use runtime exception or extensions of this type. Checked exceptions should be avoided unless they make semantic sense for the interface/method. If not all clients of that component have to handle the checked exception even if there is nothing they can do without other than re throw it. These leads to a lot of messy try catch re throw code.
- Log all exceptions at the boundaries of the application. Exceptions should not be logged at every level they are caught and re-thrown. This can cause a lot of noise in the log files. Exceptions should be caught and logged at the boundaries of the application. E.g Middletier/service delegate level, webservice component level etc. The fact that a sub component throws an exception may not be a critical situation for the calling component. As such exceptions should be "bubbled" up to the top most layer of the application and logged just before the application loses programmatic control e.g to the application server or some other invocation framework (webservices, messaging systems etc).
-If rethrowing an exception ensure that the stack trace from the original exception is propagated to the new exception. E.g. converting from a checked to a runtime exception.

try {
} catch (RealException realException){
throw new RuntimeException(message,realException);
}

Logging
This section lists the practices, which should be followed while using Logging. Following these practices make bug fixing easy.

- Logger variable should always be declared as private static variable. For example
private static final Logger logger = Logger.getLogger(Main.class);
- Use the appropriate message level.
* INFO - For logging successful completion of a process.
* DEBUG - For logging the input and output parameters and understanding the behavior in detail.
* ERROR - For logging the failure messages from exceptions.
- Check whether the logging has been enabled for that severity. E.g

if (logger.isDebugEnabled()){
//log something;
}

- All Exception should be logged in the catch block with ERROR as the message level.

JUnit
This section lists the practices, which should be followed for coding Junit test cases as well as execution of Junits.

- All classes should have a reasonable Junit coverage. To the extent possible all public methods in the class should have one or more corresponding Junit methods. E.g. one positive test method and another negative test method corresponding to a public method. This is just a thumb rule, the no of test methods could even be more. The only exceptions to this rule are getters and setters methods.
- How easy a class is to test depends on how good the underlying design is. Difficult classes to test, which have too many dependencies that need to be resolved or have poor interfaces, may need to be refactored accordingly.
- If the assertEquals () requires a comparison of two Objects, then make a customized assert<ObjectName>Equals() method which carries the assertEquals() on each property of the object with appropriate message.
- When writing a negative test case use the following convention:

try{
class.method();
fail(<appropriate message>);
}
catch(SpecificException ex){
// Successful condition
}

- For any bug reported during onsite or offshore system/unit testing, new unit test cases must be added Bottom line the test cases must be expanded to test the resolution to a given bug. So I would see at a minimum for each bug raised there should be a test case to replicate the conditions and validate the resolution.

0 comments :

 

Disclaimer
Interview Questions On Java,Java EE Copyright © 2016. Reads: best tracker