Thursday, August 3, 2017

Exception Enrichment in Java

Exception enrichment is an alternative to exception wrapping. Exception wrapping has a couple of disadvantages that exception enrichment can fix. These disadvantages are:
  • Exception wrapping may result in very long stack traces consisting of one stack trace for each exception in the wrapping hierarchy. Most often only the root stack trace is interesting. The rest of the stack traces are then just annoying.

  • The messages of the exceptions are spread out over the stack traces. The message of an exception is typically printed above the stack trace. When several exceptions wrap each other in a hierarchy, all these messages are spread out in between the stack traces. This makes it harder to determine what went wrong, and what the program was trying to do when the error happened. In other words, it makes it hard to determine in what context the error occurred. The error might have occurred in a PersonDao class, but was it called from a servlet or from a web service when it failed?

In exception enrichment you do not wrap exceptions. Instead you add contextual information to the original exception and rethrow it. Rethrowing an exception does not reset the stack trace embedded in the exception.
Here is an example:
  public void method2() throws EnrichableException{
     try{
        method1(); 
     } catch(EnrichableException e){
        e.addInfo("An error occurred when trying to ...");
        throw e;
     }
  }
  
  public void method1() throws EnrichableException {
     if(...) throw new EnrichableException(
        "Original error message");   
  }
As you can see the method1() throws an EnrichableException which is a superclass for enrichable exceptions. This is not a standard Java exception, so you will have to create it yourself. There is an example EnrichableException at the end of this text.
Notice how method2() calls the addInfo() method on the caught EnrichableException, and rethrow it afterwards. As the exception propagates up the call stack, each catch block can add relevant information to the exception if necessary.
Using this simple technique you only get a single stack trace, and still get any relevant contextual information necessary to investigate the cause of the exception.

Unique Error Codes

It is sometimes a requirement that each error raised in an application is identified by a unique error code. This can be a bit problematic since some errors are raised inside components that are reused throughout the application. Therefore an exception may seem the same to the component throwing it, but the context in which the exception occurs is different.
Here is an example:
  public void method3() throws EnrichableException{
     try{
        method1(); 
     } catch(EnrichableException e){
        e.addInfo("An error occurred when trying to ...");
        throw e;
     }
  }

  public void method2() throws EnrichableException{
     try{
        method1(); 
     } catch(EnrichableException e){
        e.addInfo("An error occurred when trying to ...");
        throw e;
     }
  }
  
  public void method1() throws EnrichableException {
     if(...) throw new EnrichableException(
        "ERROR1", "Original error message");   
  }
Notice how method1() adds the code "ERROR1" to the thrown EnrichableException to uniquely identify that error cause. But notice too that method1() is called from both method2() and method3(). Though the error may seem the same to method1() no matter which of method2() and method3() that called it, this may important to know for the developer investigating the error. The error code "ERROR1" is enough to determine where the error occurred, but not in what context it occurred.
A solution to this problem is to add unique context error codes to the exception the same way the other contextual information is added. Here is an example where the addInfo() method has been changed to accommodate this:
  public void method3() throws EnrichableException{
     try{
        method1(); 
     } catch(EnrichableException e){
        e.addInfo("METHOD3", "ERROR1",
            "An error occurred when trying to ...");
        throw e;
     }
  }

  public void method2() throws EnrichableException{
     try{
        method1(); 
     } catch(EnrichableException e){
        e.addInfo("METHOD2", "ERROR1",
            "An error occurred when trying to ...");
        throw e;
     }
  }
  
  public void method1() throws EnrichableException {
     if(...) throw new EnrichableException(
        "METHOD1", "ERROR1", "Original error message");   
  }
Two new parameters have been added to the addInfo() method and the constructor of the EnrichableException. The first parameter is a code identifying the context in which the error occurred. The second parameter is a unique error code within that context. An error identification for an exception thrown by method1() when called from method2() will now look like this:
 [METHOD2:ERROR1][METHOD1:ERROR1]
When method1() is called from method3() the error identification will look like this:
 [METHOD3:ERROR1][METHOD1:ERROR1]
As you can see it is now possible to distinguish an exception thrown from method1() via method2() from the same exception thrown from method1() via method3().
You may not always need the extra contextual error codes, but when you do the solution sketched in this section is an option.

Wrapping Non-Enrichable Exceptions

You may not always be able to avoid exception wrapping. If a component in your application throws a checked exception that is not enrichable, you may have to wrap it in an enrichable exception. Here is an example where method1() catches a non-enrichable exception and wraps it in an enrichable exception, and throws the enrichable exception:
  public void method1() throws EnrichableException {
    
     try{
    
        ... call some method that throws an IOException ...
    
     } catch(IOException ioexception)
        throw new EnrichableException( ioexception,
          "METHOD1", "ERROR1", "Original error message");   
  }

Unchecked EnrichableException

I used to be in favor of checked exceptions but over the last couple of years my opinion has changed. Now i feel that checked exceptions are more of a nuisance than a help. Therefore I would prefer to make my EnrichableException unchecked, by having it extend RuntimeException.
There is a more thorough discussion of checked and unchecked exceptions in the text "Checked vs. Unchecked Exceptions".

Exception Enrichment and Pluggable Exception Handlers

Like with any other exception type it is possible to use pluggable exception handlers with enrichable exceptions. If you use the unique error codes described earlier these codes must be added as paremeters to the exception handler interface. Here is an example exception handler interface supporting these unique error codes:
public interface ExceptionHandler{

   public void handle(String contextCode, String errorCode,
                      String errorText, Throwable t)

   public void raise(String contextCode, String errorCode,
                     String errorText);
   
}
Exceptions caught in the program will be passed to the handleException() which will decide what concrete exception to throw instead. In this case an EnrichableException is thrown. If the EnrichableException is unchecked it is not necessary to declare it in the handleException() method.

An Example EnrichableException

Below is an example of an enrichable exception that you can use as a template for your own enrichable exceptions. You may need to change the class definition to suit your own needs. The exception is designed to use unique error codes as described earlier in this text.
Below the code is an example application that uses the EnrichableException, and a stack trace generated from this application.
import java.util.ArrayList;
import java.util.List;

public class EnrichableException extends RuntimeException {
    public static final long serialVersionUID = -1;

    protected List<InfoItem> infoItems =
            new ArrayList<InfoItem>();

    protected class InfoItem{
        public String errorContext = null;
        public String errorCode  = null;
        public String errorText  = null;
        public InfoItem(String contextCode, String errorCode,
                                     String errorText){

            this.errorContext = contextCode;
            this.errorCode   = errorCode;
            this.errorText   = errorText;
        }
    }


    public EnrichableException(String errorContext, String errorCode,
                               String errorMessage){

        addInfo(errorContext, errorCode, errorMessage);
    }

    public EnrichableException(String errorContext, String errorCode,
                               String errorMessage, Throwable cause){
        super(cause);
        addInfo(errorContext, errorCode, errorMessage);
    }

    public EnrichableException addInfo(
        String errorContext, String errorCode, String errorText){

        this.infoItems.add(
            new InfoItem(errorContext, errorCode, errorText));
        return this;
    }

    public String getCode(){
        StringBuilder builder = new StringBuilder();

        for(int i = this.infoItems.size()-1 ; i >=0; i--){
            InfoItem info =
                this.infoItems.get(i);
            builder.append('[');
            builder.append(info.errorContext);
            builder.append(':');
            builder.append(info.errorCode);
            builder.append(']');
        }

        return builder.toString();
    }

    public String toString(){
        StringBuilder builder = new StringBuilder();

        builder.append(getCode());
        builder.append('\n');


        //append additional context information.
        for(int i = this.infoItems.size()-1 ; i >=0; i--){
            InfoItem info =
                this.infoItems.get(i);
            builder.append('[');
            builder.append(info.errorContext);
            builder.append(':');
            builder.append(info.errorCode);
            builder.append(']');
            builder.append(info.errorText);
            if(i>0) builder.append('\n');
        }

        //append root causes and text from this exception first.
        if(getMessage() != null) {
            builder.append('\n');
            if(getCause() == null){
                builder.append(getMessage());
            } else if(!getMessage().equals(getCause().toString())){
                builder.append(getMessage());
            }
        }
        appendException(builder, getCause());

        return builder.toString();
    }

    private void appendException(
            StringBuilder builder, Throwable throwable){
        if(throwable == null) return;
        appendException(builder, throwable.getCause());
        builder.append(throwable.toString());
        builder.append('\n');
    }

[L1:E1][L2:E2][L3:E3]
[L1:E1]Error in level 1, calling level 2
[L2:E2]Error in level 2, calling level 3
[L3:E3]Error at level 3
java.lang.IllegalArgumentException: incorrect argument passed

 at exception.ExceptionTest$1.handle(ExceptionTest.java:8)
 at exception.ExceptionTest.level3(ExceptionTest.java:49)
 at exception.ExceptionTest.level2(ExceptionTest.java:38)
 at exception.ExceptionTest.level1(ExceptionTest.java:29)
 at exception.ExceptionTest.main(ExceptionTest.java:21)
Caused by: java.lang.IllegalArgumentException: incorrect argument passed
 at exception.ExceptionTest.level4(ExceptionTest.java:54)
 at exception.ExceptionTest.level3(ExceptionTest.java:47)
 ... 3 more

public class ExceptionTest {
 
    protected ExceptionHandler exceptionHandler = new ExceptionHandler(){
        public void handle(String errorContext, String errorCode,
                           String errorText, Throwable t){

            if(! (t instanceof EnrichableException)){
                throw new EnrichableException(
                    errorContext, errorCode, errorText, t);
            } else {
                ((EnrichableException) t).addInfo(
                    errorContext, errorCode, errorText);
            }
        }

        public void raise(String errorContext, String errorCode,
                          String errorText){
            throw new EnrichableException(
                errorContext, errorCode, errorText);
        }
    };

    public static void main(String[] args){
        ExceptionTest test = new ExceptionTest();
        try{
            test.level1();
        } catch(Exception e){
            e.printStackTrace();
        }
    }

    public void level1(){
        try{
            level2();
        } catch (EnrichableException e){
            this.exceptionHandler.handle(
                "L1", "E1", "Error in level 1, calling level 2", e);
            throw e;
        }
    }

    public void level2(){
        try{
            level3();
        } catch (EnrichableException e){
            this.exceptionHandler.handle(
                "L2", "E2", "Error in level 2, calling level 3", e);
            throw e;
        }
    }

    public void level3(){
        try{
            level4();
        } catch(Exception e){
            this.exceptionHandler.handle(
                "L3", "E3", "Error at level 3", e);
        }
    }

    public void level4(){
        throw new IllegalArgumentException("incorrect argument passed");
    }

} 
 
@reference_1_tutorials.jenkov.com
Exception Enrichment in Java

Exception Handling Templates in Java

Correct Error Handling is Tedious to Write

Correct exception handling code can be tedious to write. Try-catch blocks also clutter the code and makes it harder to read. Look at the example below:
    Input       input            = null;
    IOException processException = null;
    try{
        input = new FileInputStream(fileName);

        //...process input stream...
    } catch (IOException e) {
        processException = e;
    } finally {
       if(input != null){
          try {
             input.close();
          } catch(IOException e){
             if(processException != null){
                throw new MyException(processException, e,
                  "Error message..." +
                  fileName);
             } else {
                throw new MyException(e,
                    "Error closing InputStream for file " +
                    fileName;
             }
          }
       }
       if(processException != null){
          throw new MyException(processException,
            "Error processing InputStream for file " +
                fileName;
    }
In this example no exceptions are lost. If an exception is thrown from within the try block, and another exception is thrown from the input.close() call in the finally block, both exceptions are preserved in the MyException instance, and propagated up the call stack.
That is how much code it takes to handle the processing of an input stream without any exceptions being lost. In fact it only even catches IOExceptions. RuntimeExceptions thrown from the try-block are not preserved, if the input.close() call also throws an exception. Isn't it ugly? Isn't it hard to read what is actually going on? Would you remember to write all that code everytime you process an input stream?
Luckily there is a simple design pattern, the Template Method, that can help you get the exception handling right everytime, without ever seeing or writing it in your code. Well, maybe you will have to write it once, but that's it.
What you will do is to put all the exception handling code inside a template. The template is just a normal class. Here is a template for the above input stream exception handling:
public abstract class InputStreamProcessingTemplate {

    public void process(String fileName){
        IOException processException = null;
        InputStream input = null;
        try{
            input = new FileInputStream(fileName);

            doProcess(input);
        } catch (IOException e) {
            processException = e;
        } finally {
           if(input != null){
              try {
                 input.close();
              } catch(IOException e){
                 if(processException != null){
                    throw new MyException(processException, e,
                      "Error message..." +
                      fileName);
                 } else {
                    throw new MyException(e,
                        "Error closing InputStream for file " +
                        fileName;
                 }
              }
           }
           if(processException != null){
              throw new MyException(processException,
                "Error processing InputStream for file " +
                    fileName;
        }
    }

    //override this method in a subclass, to process the stream.
    public abstract void doProcess(InputStream input) throws IOException;
}
All the exception handling is encapulated inside the InputStreamProcessingTemplate class. Notice how the process() method calls the doProcess() method inside the try-catch block. You will use the template by subclassing it, and overriding the doProcess() method. To do this, you could write:
    new InputStreamProcessingTemplate(){
        public void doProcess(InputStream input) throws IOException{
            int inChar = input.read();
            while(inChar !- -1){
                //do something with the chars...
            }
        }
    }.process("someFile.txt");
This example creates an anonymous subclass of the InputStreamProcessingTemplate class, instantiates an instance of the subclass, and calls its process() method.
This is a lot simpler to write, and easier to read. Only the domain logic is visible in the code. The compiler will check that you have extended the InputStreamProcessingTemplate correctly. You will typically also get more help from your IDE's code completion when writing it, because the IDE will recognize both the doProcess() and process() methods.
You can now reuse the InputStreamProcessingTemplate in any place in your code where you need to process a file input stream. You can easily modify the template to work for all input streams and not just files.

Using Interfaces Instead of Subclassing

Instead of subclassing the InputStreamProcessingTempate you could rewrite it to take an instance of an InputStreamProcessor interface. Here is how it could look:
public interface InputStreamProcessor {
    public void process(InputStream input) throws IOException;
}


public class InputStreamProcessingTemplate {

    public void process(String fileName, InputStreamProcessor processor){
        IOException processException = null;
        InputStream input = null;
        try{
            input = new FileInputStream(fileName);

            processor.process(input);
        } catch (IOException e) {
            processException = e;
        } finally {
           if(input != null){
              try {
                 input.close();
              } catch(IOException e){
                 if(processException != null){
                    throw new MyException(processException, e,
                      "Error message..." +
                      fileName;
                 } else {
                    throw new MyException(e,
                        "Error closing InputStream for file " +
                        fileName);
                 }
              }
           }
           if(processException != null){
              throw new MyException(processException,
                "Error processing InputStream for file " +
                    fileName;
        }
    }
}
Notice the extra parameter in the template's process() method. This is the InputStreamProcessor, which is called from inside the try block (processor.process(input)). Using this template would look like this:
    new InputStreamProcessingTemplate()
        .process("someFile.txt", new InputStreamProcessor(){
            public void process(InputStream input) throws IOException{
                int inChar = input.read();
                while(inChar !- -1){
                    //do something with the chars...
                }
            }
        });
It doesn't look much different from the previous usage, except the call to the InputStreamProcessingTemplate.process() method is now closer to the top of the code. This may be easier to read.

Static Template Methods

It is also possible to implement the template method as a static method. This way you don't need to instantiate the template as an object every time you call it. Here is how the InputStreamProcessingTemplate would look as a static method:
public class InputStreamProcessingTemplate {

    public static void process(String fileName,
    InputStreamProcessor processor){
        IOException processException = null;
        InputStream input = null;
        try{
            input = new FileInputStream(fileName);

            processor.process(input);
        } catch (IOException e) {
            processException = e;
        } finally {
           if(input != null){
              try {
                 input.close();
              } catch(IOException e){
                 if(processException != null){
                    throw new MyException(processException, e,
                      "Error message..." +
                      fileName);
                 } else {
                    throw new MyException(e,
                        "Error closing InputStream for file " +
                        fileName;
                 }
              }
           }
           if(processException != null){
              throw new MyException(processException,
                "Error processing InputStream for file " +
                    fileName;
        }
    }
}
The process(...) method is simply made static. Here is how it looks to call the method:
    InputStreamProcessingTemplate.process("someFile.txt",
        new InputStreamProcessor(){
            public void process(InputStream input) throws IOException{
                int inChar = input.read();
                while(inChar !- -1){
                    //do something with the chars...
                }
            }
        });
Notice how the call to the template's process() method is now a static method call.

Summary

Exception handling templates are a simple yet powerful mechanism that can increase the quality and readability of your code. It also increases your productivity, since you have much less code to write, and less to worry about. Exceptions are handled by the templates. And, if you need to improve the exception handling later in the development process, you only have a single spot to change it in: The exception handling template.
The Template Method design pattern can be used for other purposes than exception handling. The iteration of the input stream could also have been put into a template. The iteration of a ResultSet in JDBC could be put into a template. The correct execution of a transaction in JDBC could be put into a template. The possibilities are endless.
Context reuse and templates are also discussed in the article Code Reuse: Context and Action Reuse.

@reference_1_tutorials.jenkov.com
Exception Handling Templates in Java

Wednesday, August 2, 2017

Validation - Throw Exception or Return False?

When validating input data you do not always have to throw an exception if the input is invalid. How to handle invalid data or state sensibly often depends on the condition:
Can the code detecting the error, interact sensibly with the
user, to correct the error?
If the error is caused by input from a user, and that user is able to correct the input and retry, then interacting is often preferable to throwing an exception. In addition you might want to detect all possible errors in the input before showing them to the user. That way the user can correct all the errors before next retry, instead of repeated iterations of correcting, retrying, correcting, retrying etc. For instance, in a servlet you could do like this:
public void service(HttpServletRequest request,
                  HttpServletResponse response){
  boolean isStreetvalid  = validateStreet (request);
  boolean isZipCodeValid = validateZipCode(request);
  boolean isPhoneValid   = validatePhone  (request);

  if(isStreeValid && isZipCodeValid && isPhoneValid){
      //perform action
  } else {
      //redirect back to HTML form and show the three errors.
  }

}
Notice how none of the validation methods throw exceptions. Rather they return true or false. There is no need to throw an exception even if the input data is invalid.
In contrast, inside a DAO class you will most likely not be able to interact with the user to correct the error. A DAO object may not even know if it is called from inside a web service, a servlet, or somewhere else. It has no way of knowing if the input came from another system, a file, or a user. It has no way of knowing how, or even if, the error could be sorted out through interact with the user.
In this case the standard way for the DAO object to signal the error is to throw an exception. Other mechanisms like return codes etc. could be used, but it doesn't change the fact that the DAO cannot handle the error itself. The input data should have been validated before the call to the DAO. Here is how it could look:
public void insertAddress(Address address){

  validate(address);

  //insert address
}


public void validate(Address address) {

   if(isInvalidCity(address.getCity()){
       throw new InvalidArgumentException(
        "City " + address.getCity() + " is not valid");
   }

   // more if-statements like the one above,
   // validating each field in the address object.
}

In this example the validate() method throws an exception as soon as an validation error is found. The insertAddress method cannot interact with the user to correct the error. Thus it is appropriate to throw an exception to signal the error. Alternatively all errors could be detected before throwing the exception.

@reference_1_tutorials.jenkov.com
Validation - Throw Exception or Return False?

Pluggable Exception Handlers

Pluggable exception handlers is a technique that allows the users of a component to customize the exception handling of that component. Instead of handling, enriching, wrapping and/or logging the exception, the exception handling is delegated to an exception handler. Here is how an exception handler interface could look in code:
    public interface ExceptionHandler {
        public void handle(Exception e, String errorMessage);
    }
And here is a class that uses it:
public class Component{
    protected ExceptionHandler exceptionHandler = null;

    public void setExceptionHandler(ExceptionHandler handler){
        this.exceptionHandler = handler;
    }

    public void processFile(String fileName){
        FileInputStream input = null;
        try{
            input = new FileInputStream(fileName);
            processStream(input);
        } catch (IOException e){
            this.exceptionHandler.handle(e,
                "error processing file: " + fileName);
        }
    }

    protected void processStream(InputStream input)
        throws IOException{
        //do something with the stream.
    }
}
Notice how the catch clause in the processFile method does not wrap, rethrow or log caught IOException's. The exceptions are passed to the ExceptionHandler instance's handle() method. The exception handler can then decide what to do with it. Should the exception be ignored? Logged? Wrapped in a different exception? Or just rethrown as it is? The exception handler can decide for itself. Note however, that the exception handler cannot throw checked exceptions that were not declared in the method where the exception was caught. For instance, the processFile method does not declare any checked exceptions. Thus, the ExceptionHandler's handle() method cannot throw any checked exceptions. However, the ExceptionHandler can throw all the unchecked exceptions it wants (RuntimeException and subclasses of it).

Where to use Pluggable Exception Handlers?

Pluggable exception handlers are most effective in situations where the exceptions occurring can be handled sensibly in different ways. For instance, when validating an XML document, or an HTML form, you may not always want to stop the validation at the first validation error. In some situations you might want to continue validation to catch all validation exceptions thrown, and show them all to the user at the same time. This saves the user from having to correct an error, validate, correct error, validate over and over again. All errors can be caught and corrected in one iteration.

Implementation

There is no standard ExceptionHandler interface in Java. You will have to define one yourself, matching the needs of your component or application. Exactly how many parameters the ExceptionHandler's handle method should take depends on what the component is trying to do. As a minimum though, I would recommend taking the caught exception and a text explaining what tried to do at the time of the error.
It can be a good idea to provide a default implementation of your ExceptionHandler interface, and have your components initialized with an instance of it. This saves the user of the component from having to plugin an exception handler in the situations where the desired handling of the exception is the same as the default implementation provides. For instance, a default implementation could just rethrow the exception, or wrap it in a component specific exception.

Code Examples

Here are a few examples of exception handlers.
public class IgnoringHandler implements ExceptionHandler{
    public void handle(Exception e, String message) {
        //do nothing, just ignore the exception
    }
}
public class WrappingHandler implements ExceptionHandler{
    public void handle(Exception e, String message){
        throw new RuntimeException(message, e);
    }
}
public class CollectingHandler implements ExceptionHandler{
    List exceptions = new ArrayList();

    public List getExceptions(){ return this.exceptions; }

    public void handle(Exception e, String message){
        this.exceptions.add(e);

        //message is ignored here, but could have been
        //collected too.
    }
} 
 
@reference_1_tutorials.jenkov.com
Pluggable Exception Handlers

Fail Safe Exception Handling

It is imperative that the exception handling code is fail safe. An important rule to remember is
The last exception thrown in a try-catch-finally block is
the exception that will be propagated up the call stack.
All earlier exceptions will disappear.
If an exception is thrown from inside a catch or finally block, this exception may hide the exception caught by that block. This is misleading when trying to determine the cause of the error.
Below is a classic example of non-fail-safe exception handling:
  InputStream input = null;

  try{

    input = new FileInputStream("myFile.txt");

    //do something with the stream

  } catch(IOException e){
    throw new WrapperException(e);
  } finally {
    try{
     input.close();
    } catch(IOException e){
       throw new WrapperException(e);
    }
  }
If the FileInputStream constructor throws a FileNotFoundException, what do you think will happen?
First the catch block is executed. This block just rethrows the exception wrapped in a WrapperException.
Second the finally block will be executed which closes the input stream. However, since a FileNotFoundException was thrown by the FileInputStream constructor, the "input" reference will be null. The result will be a NullPointerException thrown from the finally block. The NullPointerException is not caught by the finally block's catch(IOException e) clause, so it is propagated up the call stack. The WrapperException thrown from the catch block will just disappear!
The correct way to handle this situation is course to check if references assigned inside the try block are null before invoking any methods on them. Here is how that looks:
  InputStream input = null;

  try{

    input = new FileInputStream("myFile.txt");

    //do something with the stream

  } catch(IOException e){ //first catch block
    throw new WrapperException(e);
  } finally {
    try{
     if(input != null) input.close();
    } catch(IOException e){  //second catch block
       throw new WrapperException(e);
    }
  }
But even this exception handling has a problem. Let's pretend the file exists, so the "input" reference now points to a valid FileInputStream. Let's also pretend that an exception is thrown while processing the input stream. That exception is caught in the catch(IOException e) block. It is then wrapped and rethrown. Before the wrapped exception is propagated up the call stack, the finally clause is executed. If the input.close() call fails, and an IOException is thrown, then it is caught, wrapped and rethrown. However, when throwing the wrapped exception from the finally clause, the wrapped exception thrown from the first catch block is again forgotten. It disappears. Only the exception thrown from the second catch block is propagated up the call stack.
As you can see, fail safe exception handling is not always trivial. The InputStream processing example is not even the most complex example you can come across. Transactions in JDBC have somewhat more error possibilities. Exceptions can occur when trying to commit, then rollback, and finally when you try to close the connection. All of these possible exceptions should be handled by the exception handling code, so none of them make the first exception thrown disappear. One way to do so is to make sure that the last exception thrown contains all previously thrown exceptions. That way they are all available to the developer investigating the error cause. This is how our Java persistence API, Mr Persister, implements transaction exception handling.
By the way, the try-with-resources features in Java 7 makes it easier to implement fail safe exception handling.

@reference_1_tutorials.jenkov.com
Fail Safe Exception Handling

Java: Difference between PrintStream and PrintWriter

@reference_1_stackoverflow
Java: Difference between PrintStream and PrintWriter

@reference_2_tutorials.jenkov.com
Java IO: PrintWriter

@reference_3_tutorials.jenkov.com
Java IO: PrintStream

@reference_4_stackoverflow
PrintStream vs PrintWriter

@reference_5_stackoverflow
PrintWriter vs PrintStream vs OutputStreamWriter timecosts

@referene_6_way2java.com
PrintStream vs PrintWriter

Tuesday, August 1, 2017

CharArrayWriter - Initial Array Size

Setting Initial char Array Size

The Java CharArrayWriter has a constructor that lets you set the initial size of the char array used internally to store the written characters.
Setting the initial size does not prevent the CharArrayWriter from storing more characters than the initial size. If the number of characters written to the CharArrayWriter exceed the size of the initial char array, a new char array is created, and all characters are copied into the new array.
Here is how setting the initial char array size using the CharArrayWriter constructor looks:
int initialSize = 1024;

CharArrayWriter charArrayWriter =
    new CharArrayWriter(initialSize);
This example creates a CharArrayWriter with an initial char array size of 1024.

@reference_1_tutorials.jenkov.com
Java IO: CharArrayWriter