DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Keep Your Application Secrets Secret
  • How to Quarantine a Malicious File in Java
  • Dust Actors and Large Language Models: An Application
  • How To Compare DOCX Documents in Java

Trending

  • Automatic Code Transformation With OpenRewrite
  • AI, ML, and Data Science: Shaping the Future of Automation
  • Java Virtual Threads and Scaling
  • Evolution of Cloud Services for MCP/A2A Protocols in AI Agents
  1. DZone
  2. Data Engineering
  3. Databases
  4. Exception Handling in Real-Life Java Applications

Exception Handling in Real-Life Java Applications

Exception handling in an application can often be varied, inconsistent, or inappropriate. This article proposes an API to make exception handling more robust and efficient.

By 
Jalal Kiswani, PhD user avatar
Jalal Kiswani, PhD
·
Muhanna Muhanna user avatar
Muhanna Muhanna
·
Jun. 22, 16 · Opinion
Likes (30)
Comment
Save
Tweet
Share
51.4K Views

Join the DZone community and get the full member experience.

Join For Free

Although Java has been out there for almost 20 years, Java developers still facing problems implementing the exception handling in the most proper way, to be re-usable, encapsulated, centralized, and pluggable. In this article, we propose an API design and implementation for exception handling towards making the exception handling more robust and efficient .

Traditional Exception Handling

In traditional exception handling, it is most of the time depends on the seniority level of developers. For example, for junior developers, most likely you will find them either printing the stack trace, showing error message, or worse, they may just eat the exception, like this:

try{
    ...
}catch(IOException e){
    e.printStacktrac();
}

or:

try{
    ...
}catch(IOException e){
    JOptionPane.showMessageDialog(null,”IO Error in page”);
}

Or the worse:

try{
    ...
}catch(IOException e){
}

For more experienced developers, you may find them wrapping an exception in a runtime exception like this:

try{
    ...
}catch(IOException e){
    throw new RuntimeException(“IO Exception in Class X”,e);
}

Another scenario of wrapping might be seen in a custom business exception,  like this:

try{
    ...
}catch(IOException e){
    throw new ERPTechnicalException(“IO Exception in Class X” ,e);
}

Also, one of the common issues can be identified in distinguishing between the usage of try/catch and throws clause across the different tiers and layers of the application.

Exception Handling API

For an advanced and clean exception handling, we propose the following API that provides the following features:

  1. Reduce the development cost of exception handling (just one single line in a single catch clause).
  2. Avoid the misunderstanding of try/catch and throws by eliminating the need for throws.
  3. Make the actual exception handling centralized and implemented by the appropriate people.
  4. Give developers the ability to plug their exception handling if required.
  5. Make exception handling consistent across the whole application (e.g. a database down exception should be handled in the same way across all the system views).
  6. The exception handling shouldn’t affect back-end and API’s when using different front-end technologies (e.g. web or native).

API-Class Diagram

JK-Exception-handling API Class-Diagram

API-Usage by Example

Assume we want to handle FileNotFoundException; in a traditional way, it would be something like this:

package com.jalalkiswani.example;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ExampleFileReader {

       public void loadFile() throws FileNotFoundException {
              FileInputStream in = new FileInputStream("file-not-found.txt");
       }
}
package com.jalalkiswani.example;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ExceptionTest {

       public static void main(String[] args) {
              try {
                     ExampleFileReader reader=new ExampleFileReader();
                     reader.loadFile();
              } catch (FileNotFoundException e) {
                     e.printStackTrace();
              }
       }
}

Now, assume this has been called across the whole application (e.g. in 200 classes), and in later phases, the business has changed to handle the exception by showing a Swing message—this would be very costly.

In our proposed API, the developer can handle such exceptions all the time by just calling  JKExceptionUtil.handle(e) as follows:

package com.jalalkiswani.example;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import com.jk.exceptions.handler.JKExceptionUtil;

public class ExampleFileReader {

    public void loadFile() {
        try {
            FileInputStream in = new FileInputStream("file-not-found.txt");
            System.out.println("Not reachable");
        } catch (FileNotFoundException e) {
            JKExceptionUtil.handle(e);
        }
    }
}

In the previous example, the developer doesn't need to handle a specific exception; Rather he/she only catches the Exception class, and calls JKExceptionUtil.handle(e) in the catch clause. In this case, it will call the default exception handler, that also prints the stack trace by default, then throws a runtime exception, wrapping the original exception inside.

Custom Exception Handler

Now, say we want to handle this exception in an appropriate way by showing a Swing message, logging the exception, and then throwing a runtime exception, wrapping the original exception in.

We create a custom handler class that implements the JKExceptionHandler Class with the generic parameter FileNotFoundException, as follows:

package com.jalalkiswani.example;

import java.io.FileNotFoundException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import com.jk.exceptions.handler.JKExceptionHandler;

public class FileNotFoundExceptionHandler implements JKExceptionHandler<FileNotFoundException> {
    Logger logger = Logger.getLogger(getClass().getName());

    public void handle(FileNotFoundException throwable, boolean throwRuntimeException) {
        JOptionPane.showMessageDialog(null, "The file your requested is not found");
        logger.log(Level.WARNING, "File not found : ", throwable);
        if (throwRuntimeException) {
            throw new RuntimeException(throwable);
        }
    }
}

Next, we'll want to register this handler during application startup in a static initializer as follows:

package com.jalalkiswani.example;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import com.jk.exceptions.handler.JKExceptionHandlerFactory;
import com.jk.exceptions.handler.JKExceptionUtil;

public class ExceptionTest {

    static {
        JKExceptionHandlerFactory.getInstance().setHandler(FileNotFoundException.class, new FileNotFoundExceptionHandler());
    }

    public static void main(String[] args) {
        ExampleFileReader reader = new ExampleFileReader();
        reader.loadFile();
    }

}

By registering this exception handler, this handler will be called every time by ExceptionUtil.handle(e) if the exception instance is of type FileNotFoundException.

It's recommended the handlers are set in the application bootstrapping phase, in the main class in the case of native applications (i.e. desktop, console, or mobile), or in context listeners in the case of web and enterprise applications.

Sequence Diagram

The following sequence diagram shows how the API works.

It starts by getting an instance of the exception handler factory, then calls getHandlerInfo for a specific exception; If no handler is registered, the default handler is called, which prints the stack trace by default and then throws a runtime exception wrapping the original exception in.

JK-Exception handler sequence diagram

JK-Util

Since I have been using this technique for a long time, I have uploaded it along with other utility APIs to one of my open-source projects github (JK-Util) as a contribution to the open-source community. Just drop the Maven dependency into your Maven project as follows :

<dependency>
    <groupId>com.jalalkiswani</groupId>
    <artifactId>jk-util</artifactId>
    <version>0.0.9</version>
</dependency>

Future Work

Annotation detection will be useful for automatic registration of exception handlers, which will make it even easier and more robust.

Update - June 27,2016:

I have updated the API to include annotation detection, which will reduce the size and efforts registering the exception handlers.


You can do that by adding @ExceptionHandler annotation to your exception handler classes, then In your application bootstrap register the package that contains the handlers using:

JKExceptionHandlerFactory.getInstance().registerHanders(yourPackageNameString); 


and it will automatically scan for all classes annotated with ExceptionHandler.

Updated Example:


package com.jalalkiswani.example;
import java.io.FileNotFoundException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import com.jk.exceptions.handler.ExceptionHandler;
import com.jk.exceptions.handler.JKExceptionHandler;

@ExceptionHandler
public class FileNotFoundExceptionHandler implements JKExceptionHandler<FileNotFoundException> {
            Logger logger = Logger.getLogger(getClass().getName());
            public void handle(FileNotFoundException throwable, boolean throwRuntimeException) {
                        JOptionPane.showMessageDialog(null, "The file your requested is not found");
                        logger.log(Level.WARNING, "File not found : ", throwable);
                        if (throwRuntimeException) {
                                    throw new RuntimeException(throwable);
                        }
            }
}



package com.jalalkiswani.example;

import com.jk.exceptions.handler.JKExceptionHandlerFactory;
public class ExceptionTest {
            static {
                        JKExceptionHandlerFactory.getInstance().registerHanders("com.jalalkiswani.example");
//                      JKExceptionHandlerFactory.getInstance().setHandler(FileNotFoundException.class, new FileNotFoundExceptionHandler());
            }

            public static void main(String[] args) {
                        ExampleFileReader reader = new ExampleFileReader();
                        reader.loadFile();
            }
}



Be sure to updated maven dependecy to version 0.0.9-1:

            <dependency>
                        <groupId>com.jalalkiswani</groupId>
                        <artifactId>jk-util</artifactId>
                        <version>0.0.9-1</version>
            </dependency>

Conclusion

In this article we have discussed the issues and limitations of traditional exception handling in Java. In addition we proposed an API design for exception handling that overcomes these limitations and constraints to make exception handling the most appropriate approach for all types of applications.

Acknowledgement

As always, without the support, review, and auditing from my dear friend Dr. Muhanna Muhanna , Assistant Professor at Princess Sumaya University for technology, this article wouldn’t be published with this quality. Thanks Dr.Muhanna.

Jalal Kiswani

http://www.JalalKiswani.com

"Talk is cheap. Show me the code."
Torvalds, Linus

application Java (programming language) Open source API

Opinions expressed by DZone contributors are their own.

Related

  • Keep Your Application Secrets Secret
  • How to Quarantine a Malicious File in Java
  • Dust Actors and Large Language Models: An Application
  • How To Compare DOCX Documents in Java

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!