SUNIWE
 

Logging and Exception Handling

Two essential practices helped to preserve developer sanity during the creation of the Web services and portal channels. Logging and chaining exceptions in the source code.

Logging statements are a crude method for debugging but sometimes logs are the only source of information. The SUNIWE system was built upon layers of web applications, each potentially with their own logging configuration and logs. It was vital to institute a consistent logging approach across all these applications. Otherwise, developers could easily spend a long time trying to track down logs and log messages.

The Apache Commons Logging package was used for logging in the SUNIWE code. Commons Logging is an ultra-thin bridge between different logging implementations which allows changing of the underlying logging implementation without recompiling code. Log4J was used as the logging implementation. The combination of commons logging and Log4J enabled detailed logging messages to be easily created. Each log message would include information about the context of any error. Log4J gave control over the granularity of the logging. Logging could easily be configured for individual classes, packages or across the whole codebase and the type of logging messages output could be controlled in a similar fashion.

Where possible, the Web applications (uPortal, Axis, Shibboleth IdP and SP) and Tomcat itself were configured to use Log4J via Commons Logging. This reduced the complexity of the logging set up. The logging was configured to create a separate log for each Web application but to put all the logs in the same directory. The other approach was to make all the Web applications append to the same log but this resulted in huge logs and confusion where log entries from different Web applications were interspersed. Defining and testing the logging configuration for the Web applications was a time consuming and fiddly business but the resulting collection of coherent logs was well worth the effort.

Exception objects in Java represent exceptional conditions that occur while the system is running. Exception chaining is a method of setting up an association between exception objects. This allows the root cause of a problem to be persisted even though the surrounding exception type might change as it is propagated through the program until it is dealt with. Without this association, the developer would have no way of identifying the original cause of an exception.

In the SUNIWE code, service exceptions often had to be propagated to the uPortal framework as input/output (IO) exceptions. This involved catching a service exception and throwing an IO exception with the root cause set to be the original service exception as illustrated in the code below.

From the PersonManagementService SUNIWE implementation

              try
            {
                personManagementServiceSync = 
    personManagementServiceSyncLocator
    .getPersonManagementServiceSyncSoap(pmsURL);
            }
            catch(javax.xml.rpc.ServiceException e)
            {
                IOException ioException = new IOException(e.getMessage());
                ioException.initCause(e); // chain ServiceException 
                throw ioException;        
            }
    
      

The result of implementing the above was log entries that clearly identified the context and nature of the root cause of any exception or error.