Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Как найти причину исключения в ГУИ


Автор: COVD 12.1.2011, 18:24
В большом swing приложении, состоящем из множества библиотек, выбрасывается исключение, в трассировке которого нет классов приложения, а только классы из пакетов  java. Как искать место, где исключение выбрасывается? Что-то менее трудоемкое, чем смотреть код всех компонентов и искать ссылки на BoxView, можно сделать? 

Пример:

Код

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0
    at javax.swing.text.BoxView.getOffset(Unknown Source)
    at javax.swing.text.BoxView.childAllocation(Unknown Source)
    at javax.swing.text.CompositeView.getChildAllocation(Unknown Source)
    at javax.swing.text.BoxView.getChildAllocation(Unknown Source)
    at javax.swing.plaf.basic.BasicTextUI$UpdateHandler.calculateViewPosition(Unknown Source)
    at javax.swing.plaf.basic.BasicTextUI$UpdateHandler.layoutContainer(Unknown Source)
    at java.awt.Container.layout(Unknown Source)
    at java.awt.Container.doLayout(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validate(Unknown Source)
    at javax.swing.RepaintManager.validateInvalidComponents(Unknown Source)
    at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)


Автор: ecologist 12.1.2011, 20:43
Без анализа всех признаков, знания, когда именно это происходит и исходных кодов по трейсу вряд ли что получится. Видимо где-то есть пустая коллекция, в которой есть попытка доступа к элементу. Может быть это ArrayList.

Автор: Skipy 13.1.2011, 13:01
Странная ситуация. Исключение в UI-делегате текстового поля при попытке выложить составляющие этого текстового поля. А в каких случаях такое происходит?

Кстати, не пробовали версию Java менять?

Автор: skif18 13.1.2011, 13:07
COVD, код в студию!

Автор: jk1 13.1.2011, 13:36
Я подобные симптомы наблюдал в том случае, когда Swing-компоненты параллельно вызывались не только из EDT, но и из рабочих потоков. А Swing, как известно, однопоточный toolkit.
Мне удалось эту ошибку найти практически случайно, в общем случае могу порекомендовать воспользоваться профайлером.

Автор: COVD 13.1.2011, 17:21
Это исключение обнаружено в логах удаленных клиентов (WebStart). Уточнить обстоятельства события у пользователей нереально. И это далеко не у всех возникает. Воспроизвести даже не пытаюсь. Возможно, это один из компонентов, отображающих хтмл, потому что BoxView является родителем некоторых классов из  javax.swing.text.html . Напрямую он вроде нигде у нас не используется.

Цитата

Кстати, не пробовали версию Java менять? 

Там "зоопарк" начиная с 1.6-оем (мак, видимо) и до последнего апдейта. Спасибо, надо посмотреть, на какой версии срабатывает. 

PS. Зависимости от версии не обнаружил. Наблюдается на разных апдейтах 1.6
  
Цитата

COVD, код в студию! 

Слишком много его.

Цитата

когда Swing-компоненты параллельно вызывались не только из EDT, но и из рабочих потоков

Такая ситуация не исключена. Спасибо, учту.


Автор: mgarin 13.1.2011, 17:30
Цитата(COVD @  13.1.2011,  17:21 Найти цитируемый пост)
Возможно, это один из компонентов, отображающих хтмл, потому что BoxView является родителем некоторых классов из  javax.swing.text.html . Напрямую он вроде нигде у нас не используется.

Не возможно, а точно. BoxView используется для рендеринга HTML в том же JEditorPane или схожих компонентах содержащих "rich" content.

Вылетать такая вещь может в связи, с изменением содержимого такого компонента (например JEditorPane) вне AWT event dispatching thread'а.
(Об этом уже писали выше - "когда Swing-компоненты параллельно вызывались не только из EDT, но и из рабочих потоков")

Без непосредственного воспроизведения ситуации Вы врядли что-то сможете сделать с этой проблемой.
Начинать все смены контента пихать в "SwingUtilities.invokeLater" вероятно тоже не вариант.

Так что Вам необходимо конкретное воспроизведение проблемы, иначе это просто "пальцем в небо".

P.S. Эта ошибка что-то наворачивает, или Вы ее просто в логах усмотрели? 
Просто если она ни на что визуально (повисший интерфейс, кривая отрисовка и т.п.) не влияет и возможности воспроизвести у вас вообще нет - можете не обращать на нее внимания.
Если влияет, но никакой возможности ее отследить нет - не знаю какие еще можно предложить варианты... 
Только повториться - отслеживайте, как найдете корень - пишите smile

Автор: COVD 13.1.2011, 18:20
Да, "просто в логах усмотрел" ( вроде пока никто не жаловался smile ). Гипотеза убедительная, буду искать эти компоненты. Потом сообщу результаты. Спасибо.

Автор: mgarin 13.1.2011, 18:50
Вообще насчет "Начинать все смены контента пихать в "SwingUtilities.invokeLater" вероятно тоже не вариант" я погорячился.
Зависит от того, где и как у вас используется замена текста в JEditorPane (если я угадал?).

Если это что-то наподобие Rich-text редактора с тулбаром, с которого могут заносится изменения - то это как раз тот случай, 
когда полюбому нужно оборачивать все изменения в SwingUtilities.invokeLater.
Впрочем то же самое и если у вас параллельно работает несколько потоков, изменяющих данные в поле.

Только не забывайте, что SwingUtilities.invokeLater добавляет исполняемый код из имплементации Runnable в AWT Event queue
и выполнение текущего потока продолжится сразу же после вызова, не дожидаясь исполнения кода из имплементации Runnable.
Если вам нужно дождаться непосредственно исполнения - есть 2ой вариант - SwingUtilities.invokeAndWait

Автор: COVD 13.1.2011, 19:26
Нашел JEditorPane.setText(), но "This method is thread safe, although most Swing methods are not."
Но возможно найду и другие варианты. 
В большинстве случаев делается асинхронный запрос на сервер и полученный ресурс отображается. Никакого редактирования текста пользователем не должно быть.

Автор: mgarin 13.1.2011, 20:03
Цитата(COVD @  13.1.2011,  19:26 Найти цитируемый пост)
Нашел JEditorPane.setText(), но "This method is thread safe, although most Swing methods are not."

посмотрел я этот метод, там конечно написано, что он Thread safe... Но что-то терзаю меня смутные сомнения...

Плюс, возможно у вас где-то берется Document у JEditorPane и ведется работа с ним напрямую?
Потому Вы могли и не найти более setText...

Автор: COVD 13.1.2011, 21:13
да, я нашел setDocument(), про который ничего не сказано относительно потокобезопасности, но то, что нашел, в  EDT обрабатывается. Буду продолжать искать.  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)