Search code examples
javaexceptionglobalvisibilityuncaughtexceptionhandler

Visibility in Java global exception handler


I'm writing a program in Java that will allow a person to input data into a form as jobs for a help desk. The submitted form is then used to create a helpRequest object which is entered into a generic Queue for storage in a binary file. However, the onus of the project (it's a school assignment) is to make the program failsoft using exceptions. One specific stipulation of the program is that it must handle any situation where it cannot continue by attempting to save the current helpRequest queue before terminating "gracefully". I've got all of this set up in code, but when the handler runs (by a division by zero in my test), the program hangs as soon as it tries to do anything with the helpQueue.

I've tried looking up Java global variables and global exception handlers, but nothing seems to address the topic of using a structure or variable from another/the throwing class.

Here is the code for the handler. I have helpQueue declared as public and static in the throwing class HelpDeskForm, and NetBeans accepts all the code I have here. The induced exception occurs after the queue has been worked with.

public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler {

    BinaryOutputFile emergencyOutput;

    public void uncaughtException(Thread t, Throwable e) {
        Frame f = new Frame();
        JOptionPane.showMessageDialog(f, "Program error.  Please select a file for queue output.");
        emergencyOutput = new BinaryOutputFile();
        while(!HelpDeskForm.helpQueue.isEmpty())
            emergencyOutput.writeObject(HelpDeskForm.helpQueue.remove());
        emergencyOutput.close();        
        System.exit(1);
    }

}

Rather than a specific solution to my issue, I'd appreciate it if someone could explain why helpQueue is seemingly not actually visible/usable in this exception handler, or what I'm doing horribly wrong.

EDIT: I didn't want to overcomplicate my explanation, but here is the HelpDeskForm code up until my division by zero exception.

public class HelpDeskForm {

    BinaryDataFile input;
    BinaryOutputFile output; 
    CheckedForm c;
    helpRequest r;
    public static Queue<helpRequest> helpQueue;
    int inputSize;

    public HelpDeskForm() {

        GlobalExceptionHandler h = new GlobalExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(h);

        input = new BinaryDataFile();
        inputSize = input.readInt();
        for(int i = 0; i < inputSize; i++) {
            helpQueue.add((helpRequest)input.readObject());
        }
        input.close();

        int y = 0;
        int z = 2;
        z = z/y;
        ... // GUI code follows 
    }
}    

Solution

  • HelpDeskForm seems to lack initialization for queue being used, so NPE is inevitable. Try to add initialization to declaration:

    public static Queue<helpRequest> helpQueue = new ArrayBlockingQueue<helpRequest>(100);
    

    Plus, for the posted code, it would be logical to add volatile keyword to queue declaration:

    public static volatile BlockingQueue<helpRequest> helpQueue;
    
    public void createQueue() {
       // make sure createQueue() is called at the very beginning of your app,
       // somewhere in main()
       helpQueue = new ArrayBlockingQueue...
    }
    

    This way all other threads, if any, will see correct reference to the queue, and thread safety of BlockingQueue guarantees correct visibility of its' contents.