InterruptedException после отмены открытия файла - 1.6.0_26 - PullRequest
10 голосов
/ 14 октября 2011

Выходные данные из следующего кода:

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)

Следующий код показывает исключение на моей машине.

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();
            }
        });
    }
}

Когда я запускаю программу, главное окно открывается нормально, и программа работает нормально.

Однако, если вы:

  • откроете JFileChooser с помощью кнопки «Открыть файл»
  • нажмите «Отмена» и затем
  • выйдитепрограмма

InterruptedException выбрасывается.Или, если вы выберете файл и откроете его, выйдите из программы и вы получите ту же ошибку.В этом блоге то же самое объясняется с примером кода, его решение - как можно скорее вызвать new JFileChooser();, что я сделал безрезультатно.

Это ошибка в 1.6.0_26?Если да, есть ли обходной путь для этой версии?

Это код?Если так, как это исправить?(Выглядит менее вероятно, с двумя другими нулевыми результатами, один из которых теперь удален.)

Ответы [ 5 ]

12 голосов
/ 26 октября 2011

Я бы сказал, что это небольшая ошибка в sun.awt.Disposer.

Этот класс создает поток демона "Java2D Disposer", который обрабатывает удаление ресурсов AWT из объектов, собираемых мусором (главным образом, окон AWT). Большую часть времени этот поток ожидает в своей ссылочной очереди новый одноразовый объект для сбора мусора. Когда поток прерывается, он явно печатает это исключение.

Когда JVM завершается, он прерывает все потоки. При некоторых обстоятельствах, которые, по-видимому, зависят от использования JFileChooser и инициализированных им подсистем, некоторые потоки по-прежнему могут работать после этого прерывания. И в этом случае InterruptedException выбрасывается в поток «Java2D Disposer», потому что он ожидал блокировки. Было бы лучше, если бы он игнорировал это исключение во время выключения.

В качестве обходного пути замените

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

с

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);
    }
});
4 голосов
/ 27 октября 2011

У меня была похожая проблема. Я исправил это по совету этой темы

2 голосов
/ 26 октября 2011

Мой вывод для слегка измененной версии вашего источника (теперь включается в качестве редактирования самого вопроса):

java.vendor     Sun Microsystems Inc.
java.version    1.6.0_29
java.runtime.version    1.6.0_29-b11
sun.arch.data.model     32
os.name         Windows 7
os.version      6.1
os.arch         x86
Input File Selected: install.ini.
Input selection cancelled by user.
Press any key to continue . . .

Из вашего вопроса кажется, что важная строка:

Input selection cancelled by user.

Но после этого я не вижу InterruptedException в выводе.

0 голосов
/ 27 октября 2011

Попробуйте добавить System.gc() вызов, когда закончите с JFileChooser. У меня были некоторые проблемы с блокировками файлов, которые этот вызов исправил.

0 голосов
/ 27 октября 2011

Разница между кодом в сообщении в блоге заключается в scope JFileChooser. В сообщении в блоге объект является локальной переменной в функции onClickedButton. В вашем примере объект определен на уровне класса . Я предполагаю, что локальная переменная дает потоку Disposer больше времени для очистки объекта JFileChooser.

Когда я сделал объект выбора файлов локальной переменной в блоке метода actionPerformed в вашем примере, исключение не произошло. Я тестировал его около десяти раз. Оба запускали приложение через eclipse и через командную строку. Исключение не произошло.

Если исключение все еще возникает, вы можете инициализировать объект выбора файлов в конструкторе GUI, но не назначая его чему-либо . Я предполагаю, что это действует как ранняя инициализация и удаление тяжелого объекта качания.

Надеюсь, это поможет.

...