Showing posts with label effective java. Show all posts
Showing posts with label effective java. Show all posts

Friday, 13 January 2012

Exception Wrapping for persistence

Data can be stored in various ways, for example:
  • a relational database
  • text files
  • on the web (for example, fetching the weather forecast from a web site)
If the storage method changes, then the low level Exception objects thrown by the data access layer can also change. For example, when the data store is moved from text files to a relational database, IOException is replaced with SQLException. Otherwise there will be compilation errors throughout the code.

Removing the compilation point of view, lets look at the design point. Then consider a typical J2EE application that has a simple web layer, a business layer and a database layer. If some SQL query in the database layer goes completely wrong I will get an SQLException of some sort. In your point of view the web application (being the topmost layer) will catch this exception in the end.

This defeats the entire purpose of having a multitier (3+) architecture. I'm now dependent on the database layer in the web layer, because all exceptions are thrown all the way upwards.

The point of the PersistenceException is that it keeps the tiers independent from each other, except for the tier beneath it. The web layer doesn't care if it's an SQLException. It only needs to know something went wrong with the business logic, and more specifically with the persistence of business data objects.

In any case, the 'business code' knows more of what to do than the layers above it. If it can't do anything meaningful with it, you can either log it or perform some other action. The question is: what would a layer above it (eg. the web layer) know more of what to do than the business layer?

Effective Java Exception handling

1. Use checked exceptions when you know that or you can recover  from the exception without any side affects.
2. The best use of exceptions is to translate exception in the calling method to the exception which is more appropriate for it and you should let the cause of the exception flow from the called methods to the calling methods.
For this you should have one of the constructors of your Exception classes like
 1: // Exception with chaining-aware constructor
 2:   class HigherLevelException extends Exception {
 3:       HigherLevelException(Throwable cause) {
 4:           super(cause);
 5:       }
 6:   }
You can also use the Throwable.initCause method for this if you don’t have the constructor like the one above.
3. Don’t use the 2nd point too much if the lower level method can get away with the exception, then you should do that. Don’t overload the calling methods too much to handle the exceptions thrown by the lower methods.
4. If you are declaring your own exception class you can always include some methods or attributes which can be used to convey more about the exception when it occurs.
5. Try to reuse exceptions (comes generally when you are creating your own API). The most reusabel exceptions are
IllegalArgumentException, IllegalStateException, NullPointerException, IndexArrayOutOfBounds and some more.
6. Most importantly, use Exceptions only for Exceptional conditions. Don’t write your logic which is based on exceptions. For example, don’t do like this
 1: // wrong usage of exception handling
 2: try {
 3:     someObject.someMethod();
 4: } catch (NullPointerException npe)
 5: {
 6:     // other code
 7: }
7. If rather than Exception you can have state testing method before actually using a state-dependent method like checking iterator.hasNext() before executing the iterator.next() method is more appropriate.
8. All of the unchecked throwables you implement should subclass  RuntimeException (directly or indirectly).
9. Use runtime exceptions to indicate programming errors. The great majority of runtime exceptions indicate precondition violations. A precondition violation is simply a failure by the client of an API to adhere to the contract established by the API specification. For example, the contract for array access specifies that the array index must be between zero and the array length minus one. ArrayIndexOutOfBoundsException indicates that this precondition was violated.
10. Always declare checked exceptions individually, and document precisely the conditions under which each one is thrown using the Javadoc @throws tag. Don’t take the shortcut of declaring that a method throws some superclass of multiple exception classes that it can throw. As an extreme example, never declare that a method “throws Exception” or, worse yet, “throws Throwable.”
11.Use the Javadoc @throws tag to document each unchecked exception that a method can throw, but do not use the throws keyword to include unchecked exceptions in the method declaration.  It is important that the programmers using your API be aware of which exceptions are checked and which are unchecked, as their responsibilities differ in these two cases. The documentation    generated by the Javadoc @throws tag in the absence of the method header generated by the throws declaration provides a strong visual clue to help the programmer distinguish checked exceptions from unchecked.
12. If an exception is thrown by many methods in a class for the same reason, it is acceptable to document the exception in the class’s documentation comment rather than documenting it individually for each method. A common example is NullPointerException. It is fine for a class’s documentation comment to say, “All methods in this class throw a NullPointerException if a null object reference is passed in any parameter,” or words to that effect.
13. To capture the failure, the detail message of an exception should contain the values of all parameters and fields that “contributed to the exception. You must write the toString() method of your exception carefully.
14. Failure Atomicity(Object remains in consistence state after a failure)-
ways to achieve failure atomicity:
a. A closely related approach to achieving failure atomicity is to order the computation so that any part that may fail takes place before any part that modifies the object.
b. This approach is a natural extension of the previous one when arguments cannot be checked without performing a part of the computation.
c. A third and far less common approach to achieving failure atomicity is to write recovery code that intercepts a failure that occurs in the midst of an operation and causes the object to roll back its state to the point before the operation began. This approach is used mainly for durable (disk-based) data structures.
d.A final approach to achieving failure atomicity is to perform the operation on a temporary copy of the object and to replace the contents of the object with the temporary copy once the operation is complete. This approach occurs naturally when the computation can be performed more quickly  once the data has been stored in a temporary data structure. For example, Collections.sort dumps its
input list into an array prior to sorting to reduce the cost of accessing elements in the inner loop of the sort. This is done for performance, but as an added benefit, it ensures that the input list will be untouched if the sort fails.
As a rule, any generated exception that is part of a method’s specification should leave the object in the same state it was in prior to the method invocation. Where this rule is violated, the API documentation should clearly indicate what state the object will be left in.
15. An empty catch block defeats the purpose of exceptions, which is to force you to handle exceptional conditions. At the very
least, the catch block should contain a comment explaining why it is appropriate to ignore the exception.

Thursday, 14 July 2011

Effective Java : How to Avoid NPE / Null Pointer Exception in java?

It doesn't take much Java development experience to learn firsthand what the NullPointerException is about. In fact, one person has highlighted dealing with this as the number one mistake Java developers make. I blogged previously on use of String.value(Object) to reduce unwanted NullPointerExceptions. There are several other simple techniques one can use to reduce or eliminate the occurrences of this common type of RuntimeException that has been with us since JDK 1.0. This blog post collects and summarizes some of the most popular of these techniques.

Check Each Object For Null Before Using

The most sure way to avoid a NullPointerException is to check all object references to ensure that they are not null before accessing one of the object's fields or methods. As the following example indicates, this is a very simple technique.

final String causeStr = "adding String to Deque that is set to null.";
final String elementStr = "Fudd";
Deque<String> deque = null;

try
{
deque.push(elementStr);
log("Successful at " + causeStr, System.out);
}
catch (NullPointerException nullPointer)
{
log(causeStr, nullPointer, System.out);
}

try
{
if (deque == null)
{
deque = new LinkedList<String>();
}
deque.push(elementStr);
log( "Successful at " + causeStr
+ " (by checking first for null and instantiating Deque implementation)",
System.out);
}
catch (NullPointerException nullPointer)
{
log(causeStr, nullPointer, System.out);
}

In the code above, the Deque used is intentionally initialized to null to facilitate the example. The code in the first try block does not check for null before trying to access a Deque method. The code in the second try block does check for null and instantiates an implementation of the Deque (LinkedList) if it is null. The output from both examples looks like this:

ERROR: NullPointerException encountered while trying to adding 
String to Deque that is set to null.
java.lang.NullPointerException
INFO: Successful at adding String to Deque that is set to null.
(by checking first for null and instantiating Deque implementation)

The message following ERROR in the output above indicates that a NullPointerException is thrown when a method call is attempted on the null Deque. The message following INFO in the output above indicates that by checking Deque for null first and then instantiating a new implementation for it when it is null, the exception was avoided altogether.

This approach is often used and, as shown above, can be very useful in avoiding unwanted (unexpected) NullPointerException instances. However, it is not without its costs. Checking for null before using every object can bloat the code, can be tedious to write, and opens more room for problems with development and maintenance of the additional code. For this reason, there has been talk of introducing Java language support for built-in null detection, automatic adding of these checks for null after the initial coding, null-safe types, use of Aspect-Oriented Programming (AOP) to add null checking to byte code, and other null-detection tools.

Groovy already provides a convenient mechanism for dealing with object references that are potentially null. Groovy's safe navigation operator (?.) returns null rather than throwing a NullPointerException when a null object reference is accessed.

Because checking null for every object reference can be tedious and does bloat the code, many developers choose to judiciously select which objects to check for null. This typically leads to checking of null on all objects of potentially unknown origins. The idea here is that objects can be checked at exposed interfaces and then be assumed to be safe after the initial check.

This is a situation where the ternary operator can be particularly useful. Instead of
// retrieved a BigDecimal called someObject
String returnString;
if (someObject != null)
{
returnString = someObject.toEngineeringString();
}
else
{
returnString = "";
}

the ternary operator supports this more concise syntax

// retrieved a BigDecimal called someObject
final String returnString = (someObject != null)
? someObject.toEngineeringString()
: "";
}

Check Method Arguments for Null

The technique just discussed can be used on all objects. As stated in that technique's description, many developers choose to only check objects for null when they come from "untrusted" sources. This often means testing for null first thing in methods exposed to external callers. For example, in a particular class, the developer might choose to check for null on all objects passed to public methods, but not check for null in private methods.

The following code demonstrates this checking for null on method entry. It includes a single method as the demonstrative method that turns around and calls two methods, passing each method a single null argument. One of the methods receiving a null argument checks that argument for null first, but the other just assumes the passed-in parameter is not null.

/**
    * Append predefined text String to the provided StringBuilder.
    *
    * @param builder The StringBuilder that will have text appended to it; should
    * be non-null.
    * @throws IllegalArgumentException Thrown if the provided StringBuilder is
    * null.
    */
private void appendPredefinedTextToProvidedBuilderCheckForNull(
final StringBuilder builder)
{
if (builder == null)
{
throw new IllegalArgumentException(
"The provided StringBuilder was null; non-null value must be provided.");
}
builder.append("Thanks for supplying a StringBuilder.");
}

/**
    * Append predefined text String to the provided StringBuilder.
    *
    * @param builder The StringBuilder that will have text appended to it; should
    * be non-null.
    */
private void appendPredefinedTextToProvidedBuilderNoCheckForNull(
final StringBuilder builder)
{
builder.append("Thanks for supplying a StringBuilder.");
}

/**
    * Demonstrate effect of checking parameters for null before trying to use
    * passed-in parameters that are potentially null.
    */
public void demonstrateCheckingArgumentsForNull()
{
final String causeStr = "provide null to method as argument.";
logHeader("DEMONSTRATING CHECKING METHOD PARAMETERS FOR NULL", System.out);

try
{
appendPredefinedTextToProvidedBuilderNoCheckForNull(null);
}
catch (NullPointerException nullPointer)
{
log(causeStr, nullPointer, System.out);
}

try
{
appendPredefinedTextToProvidedBuilderCheckForNull(null);
}
catch (IllegalArgumentException illegalArgument)
{
log(causeStr, illegalArgument, System.out);
}
}

When the above code is executed, the output appears as shown next.
ERROR: NullPointerException encountered while trying to provide null to 
method as argument.
java.lang.NullPointerException
ERROR: IllegalArgumentException encountered while trying to provide null
to method as argument.
java.lang.IllegalArgumentException: The provided StringBuilder was null;
non-null value must be provided.


In both cases, an error message was logged. However, the case in which a null was checked for threw an advertised IllegalArgumentException that included additional context information about when the null was encountered. Alternatively, this null parameter could have been handled in a variety of ways. For the case in which a null parameter was not handled, there were no options for how to handle it. Many people prefer to throw a NullPolinterException with the additional context information when a null is explicitly discovered (see Item #60 in the Second Edition of Effective Java or Item #42 in First Edition), but I have a slight preference for IllegalArgumentException when it is explicitly a method argument that is null because I think the very exception adds context details and it is easy to include "null" in the subject.

The technique of checking method arguments for null is really a subset of the more general technique of checking all objects for null. However, as outlined above, arguments to publicly exposed methods are often the least trusted in an application and so checking them may be more important than checking the average object for null.

Checking method parameters for null is also a subset of the more general practice of checking method parameters for general validity as discussed in Item #38 of the Second Edition of Effective Java (Item 23 in First Edition).


Consider Primitives Rather than Objects

I don't think it is a good idea to select a primitive data type (such as int) over its corresponding object reference type (such as Integer) simply to avoid the possibility of a NullPointerException, but there is no denying that one of the advantages of primitive types is that they do not lead to NullPointerExceptions. However, primitives still must be checked for validity (a month cannot be a negative integer) and so this benefit may be small. On the other hand, primitives cannot be used in Java Collections and there are times one wants the ability to set a value to null.

The most important thing is to be very cautious about the combination of primitives, reference types, and autoboxing. There is a warning in Effective Java (Second Edition, Item #49) regarding the dangers, including throwing of NullPointerException, related to careless mixing of primitive and reference types.


Carefully Consider Chained Method Calls

A NullPointerException can be very easy to find because a line number will state where it occurred. For example, a stack trace might look like that shown next:

java.lang.NullPointerException
at dustin.examples.AvoidingNullPointerExamples.
demonstrateNullPointerExceptionStackTrace(AvoidingNullPointerExamples.java:222)
at dustin.examples.
AvoidingNullPointerExamples.main(AvoidingNullPointerExamples.java:247)

The stack trace makes it obvious that the NullPointerException was thrown as a result of code executed on line 222 of AvoidingNullPointerExamples.java. Even with the line number provided, it can still be difficult to narrow down which object is null if there are multiple objects with methods or fields accessed on the same line.

For example, a statement like someObject.getObjectA().getObjectB().getObjectC().toString(); has four possible calls that might have thrown the NullPointerException attributed to the same line of code. Using a debugger can help with this, but there may be situations when it is preferable to simply break the above code up so that each call is performed on a separate line. This allows the line number contained in a stack trace to easily indicate which exact call was the problem. Furthermore, it facilitates explicit checking each object for null. However, on the downside, breaking up the code increases the line of code count (to some that's a positive!) and may not always be desirable, especially if one is certain none of the methods in question will ever be null.


Make NullPointerExceptions More Informative

In the above recommendation, the warning was to consider carefully use of method call chaining primarily because it made having the line number in the stack trace for a NullPointerException less helpful than it otherwise might be. However, the line number is only shown in a stack trace when the code was compiled with the debug flag turned on. If it was compiled without debug, the stack trace looks like that shown next:

java.lang.NullPointerException
at dustin.examples.AvoidingNullPointerExamples.
demonstrateNullPointerExceptionStackTrace(Unknown Source)
at dustin.examples.AvoidingNullPointerExamples.main(Unknown Source)

As the above output demonstrates, there is a method name, but not no line number for the NullPointerException. This makes it more difficult to immediately identify what in the code led to the exception. One way to address this is to provide context information in any thrown NullPointerException. This idea was demonstrated earlier when a NullPointerException was caught and re-thrown with additional context information as a IllegalArgumentException. However, even if the exception is simply re-thrown as another NullPointerException with context information, it is still helpful. The context information helps the person debugging the code to more quickly identify the true cause of the problem.

The following example demonstrates this principle.

final Calendar nullCalendar = null;

try
{
final Date date = nullCalendar.getTime();
}
catch (NullPointerException nullPointer)
{
log("NullPointerException with useful data", nullPointer, System.out);
}

try
{
if (nullCalendar == null)
{
throw new NullPointerException("Could not extract Date from provided Calendar");
}
final Date date = nullCalendar.getTime();
}
catch (NullPointerException nullPointer)
{
log("NullPointerException with useful data", nullPointer, System.out);
}

The output from running the above code looks as follows.

ERROR: NullPointerException encountered while trying to NullPointerException 
with useful data
java.lang.NullPointerException
ERROR: NullPointerException encountered while trying to
NullPointerException with useful data
java.lang.NullPointerException: Could not extract Date from provided Calendar

The first error does not provide any context information and only conveys that it is a NullPointerException. The second error, however, had explicit context information added to it which would go a long way in helping identify the source of the exception.


Use String.valueOf Rather than toString

As described previously, one of the surest methods for avoiding NullPointerException is to check the object being referenced for null first. The String.valueOf(Object) method is a good example of a case where this check for null can be done implicitly without any additional effort on the developer's part. I blogged on this previously, but include a brief example of its use here.

 


Source : Inspired by actual events

Wednesday, 22 June 2011

Avoid subtraction based comparison between integers

Before I say anything I want to share with you a code snippet that is a simplified version of something I have recently wrote in my work. There is a small, yet painful bug in this code… can you see it?

public static class Point implements Comparable<Point> {
private int x, y;

public Point(int x, int y) {
this.x = x;
this.y = y;
}

@Override
public int compareTo(Point other) {
if (this.x != other.x) {
return this.x - other.x;
} else {
return this.y - other.y;
}
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof Point)) return false;
Point other = (Point) obj;
return (this.x == other.x && this.y == other.y);
}

@Override
public int hashCode() {
return 31 * x + y;
}
}

This is a simple value class represanting a point. At first glance everything is good with it: the hash function is not sophisticated, but it is correct and legal. The equals() method is written ‘by the book’ so it is probably OK. The class implements Comparable interface and defines a lexicographic order of the points – the code of compareTo() is standard and fulfills the contract of the interface. All three methods are compatible with each other: hash codes of equal points are equal, comparisons are transitive, if A.compareTo(B) == 0 then A.equals(B)… Basically all is fine, so where is the bug? Is there any bug at all?
Unfortunatelly there is a bug in this code. What is worse you probably read about it many times (’Effective Java’ item 11, ‘Java Puzzlers’ puzzle 65, the list goes on an on…). The problem with this code is that substraction based comparators are BAD as they often exposes you to danger of an overflow. This is what happens in this case – see the following:

public static void main(String[] args) {
Point pZero = new Point(0, 0);
Point pPlus = new Point(2000000000, 0);
Point pMinus = new Point(-2000000000, 0);

System.out.println( pPlus.compareTo(pZero) > 0 );
System.out.println( pZero.compareTo(pMinus) > 0 );
System.out.println( pPlus.compareTo(pMinus) > 0 );
}

We are comparing in this code three points. When you look at the declaration of those object you can already see the order of them: pPlus > pZero > pMinus. Just to be sure we check it by printing to console the result of compareTo() function. If you execute this code you’ll get that as expected ‘true’ for pPlus > pZero and ‘true’ for pZero > pMinus. The suprizing thing is the last comparison that evaluates to false. This is because of the integer overflow: in pPlus.compareTo(pMinus) the result value is 2000000000 – (-2000000000) == -294967296! Scary, right?

Tuesday, 12 April 2011

Pre-java 5 style enums

Enumerations already existed in other languages like C, C++, SmallTalk etc. Enums are used primarily to handle a collection of logically grouped constants.
But in java, in prior releases, the standard way to represent an enumerated type was the int Enum pattern:
// int Enum Pattern - has severe problems!
public static final int SEASON_WINTER = 0;
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
public static final int SEASON_FALL = 3;

Drawbacks of This Approach:

  • Type Safety: All statuses above may carry some business meaning, but in Java language context, these are just int values. This means any int value is a status for this Java program. So the program using these statuses can break with any int value not defined in this group.
  • Compile Time Constants: All these constants are compiled and used in the program. If you want to add any new constant then you will have to add it to the list and recompile everything.
  • Uninformative: When printed, these are just numbers for a reader. E.g. if a program prints status = 3, the reader will have to go and find out what does it actually mean. Amount of information available with the print is minimal.
  • Restricted Behavior: If you want to use these values in a remote call, or compare them, then you will have to handle it explicitly. Serializable, Comparable interfaces offered by Java for same purpose cannot be used. Also there is no room to add any additional behavior to the statuses, e.g. attaching basic object behavior of hashCode(), toString() and equals() methods.
  • Meaningless Switch-Case Use: When you use statuses above in switch case, you cannot use the variable names; instead you will have to use the meaningless/uninformative numbers to compare. Readability of program goes down considerably in this case.
  • Non-Iterative List: This is a list of values, but you cannot iterate over it the way you can on any collection.
The solution to above problem is Enum data type in Java 5. Concept of Enum is obtained from the counterpart technologies like C, C++, C# etc. and also considering the Typesafe Enum design pattern in Effective Java book by Joshua Bloch:


You can read this pattern here.