Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InterruptedException after cancel file open dialog - 1.6.0_26

The output from the code that follows is:

java.vendor     Sun Microsystems Inc.
java.version    1.6.0_26
java.runtime.version    1.6.0_26-b03
sun.arch.data.model     32
os.name     Windows XP
os.version  5.1
os.arch     x86
Input selection cancelled by user.
Exception while removing reference: java.lang.InterruptedException
java.lang.InterruptedException
    at java.lang.Object.wait(Native Method)
    at java.lang.ref.ReferenceQueue.remove(Unknown Source)
    at java.lang.ref.ReferenceQueue.remove(Unknown Source)
    at sun.java2d.Disposer.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

The following code shows the exception on my machine.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GUI extends JPanel implements ActionListener {

    private final String newline = System.getProperty("line.separator");
    JButton openButton;
    JTextArea log;
    JFileChooser fc;

    public GUI() {
        super(new BorderLayout());

        log = new JTextArea(20,40);
        log.setMargin(new Insets(5,5,5,5));
        log.setEditable(false);

        fc = new JFileChooser();

        openButton = new JButton("Open");
        openButton.addActionListener(this);

        JPanel buttonPanel = new JPanel(); //use FlowLayout
        buttonPanel.add(openButton);

        add(buttonPanel, BorderLayout.NORTH);
        add(new JScrollPane(log));

        showProp("java.vendor");
        showProp("java.version");
        showProp("java.runtime.version");
        showProp("sun.arch.data.model");
        showProp("os.name");
        showProp("os.version");
        showProp("os.arch");
    }

    public void showProp(String name) {
        output(name + " \t" + System.getProperty(name));
    }

    public void output(String msg) {
        log.append(msg + newline);
        log.setCaretPosition(log.getDocument().getLength());
        System.out.println(msg);
    }

    public void actionPerformed(ActionEvent e) {
        //Handle open button action.
        int returnVal = fc.showOpenDialog(GUI.this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            //This is where a real application would open the file.
            output(
                "Input File Selected: " +
                fc.getSelectedFile().getName() +
                ".");

        } else {
            output("Input selection cancelled by user.");
        }
        log.setCaretPosition(log.getDocument().getLength());
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("IDE Output Converter");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Add content to the window.
        frame.add(new GUI());

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

When I run the program the main window opens fine and the program works fine.

However, if you:

  • open the the JFileChooser using the 'Open File' button
  • press cancel and then
  • exit the program

An InterruptedException is thrown. Or if you choose a file and 'Open' it then exit the program the same error is thrown. On this blog the same thing is explained with example code, his solution is to call new JFileChooser(); as soon as possible, which I have done to no effect.

Is this a bug in 1.6.0_26? If so, is there a work-around for that version?

Is it the code? If so, how to fix it? (Looking less likely, with 2 other null results - one of which is now deleted.)

like image 834
mhollander38 Avatar asked Oct 14 '11 15:10

mhollander38


2 Answers

I would say this is a small bug in sun.awt.Disposer.

That class creates the "Java2D Disposer" daemon thread which handles disposing AWT resources of garbage collected objects (mainly AWT windows). Most of the time that thread waits on its reference queue for a new disposable object to be garbage collected. When the thread is interrupted it explicitly prints that exception.

When the JVM is terminated it interrupts all threads. Under some circumstances - which are apparently influenced by the usage of JFileChooser and the subsystems initialized by it - some threads still get a chance to run after this interruption. And in this case an InterruptedException is thrown in the "Java2D Disposer" thread because it was waiting on a lock. It would be better if it ignored that exception during shutdown.

As a workaround, replace

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

with

frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosed(WindowEvent e) {
        PrintStream nullStream = new PrintStream(new OutputStream() {
            public void write(int b) throws IOException {
            }

            public void write(byte b[]) throws IOException {
            }

            public void write(byte b[], int off, int len) throws IOException {
            }
        });
        System.setErr(nullStream);
        System.setOut(nullStream);
        System.exit(0);
    }
});
like image 64
Ingo Kegel Avatar answered Sep 19 '22 15:09

Ingo Kegel


I had a similar issue. I fixed it following the advice from this thread

like image 26
Seitaridis Avatar answered Sep 21 '22 15:09

Seitaridis