validateTree в Java 7.x не работает (в Java 6.x было хорошо) - PullRequest
7 голосов
/ 18 марта 2012

Моя версия java:

Плагин Java 10.3.1.255 Использование JRE версии 1.7.0_03-b05 Клиент Java HotSpot (TM) VM

Итаккогда у меня была версия 6.x, все было нормально, после обновления у меня это было:

    Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: This function should be called while holding treeLock
        at java.awt.Component.checkTreeLock(Component.java:1196)
        at java.awt.Container.validateTree(Container.java:1682)
        at pl.recorder.ScenarioWindow.showUploadPanel(PlayerWindow.java:721)
        at pl.recorder.actions.UploadFilesAction.execute(DesignFilesAction.java:71)
        at pl.recorder.actions.EndTestAction.actionPerformed(EndTestAction.java:91)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
        at java.awt.Component.processMouseEvent(Component.java:6505)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
        at java.awt.Component.processEvent(Component.java:6270)
        at java.awt.Container.processEvent(Container.java:2229)
        at java.awt.Component.dispatchEventImpl(Component.java:4861)
        at java.awt.Container.dispatchEventImpl(Container.java:2287)
        at java.awt.Component.dispatchEvent(Component.java:4687)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
        at java.awt.Container.dispatchEventImpl(Container.java:2273)
        at java.awt.Window.dispatchEventImpl(Window.java:2713)
        at java.awt.Component.dispatchEvent(Component.java:4687)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
        at java.awt.EventQueue.access$000(EventQueue.java:101)
        at java.awt.EventQueue$3.run(EventQueue.java:666)
        at java.awt.EventQueue$3.run(EventQueue.java:664)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
        at java.awt.EventQueue$4.run(EventQueue.java:680)
        at java.awt.EventQueue$4.run(EventQueue.java:678)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Я изменил validateTree() на validate() и удивляюсь;) - все работает нормально, но я не знаюесли это изменение будет работать и на Java 6.x (я думаю, нет).Как я могу изменить этот код для работы в Java 6x и 7x.

Ответы [ 3 ]

10 голосов
/ 09 июля 2012

«Это не ошибка, это особенность» Java 7;)

Эта функция должна вызываться при удержании treeLock

Это заставит вас писать:

synchronized(getTreeLock()) {
     validateTree();
}
8 голосов
/ 12 октября 2012

В ответ на ответ @ vince я думаю, что поучительно посмотреть на то, что Java 1.4.2 javadoc для метода говорит:

protected void validateTree()

Рекурсивно спускается дерево контейнеров и пересчитывает макет для любых поддеревьев, помеченных как нужные (те, которые помечены как недействительные). Синхронизация должна обеспечиваться методом, вызывающим этот: validate.

(выделение добавлено).

То, как я это читаю, говорит о том, что метод предназначен для вызова validate(), который (предположительно) будет удерживать блокировку дерева.

Обратите внимание, что текст в Java 6 и Java 7 идентичен. Спецификация не изменилась ...

Теперь, очевидно, существует код приложения, который вызывает validateTree() напрямую ... без получения блокировки дерева. Предположительно, это приводит к невоспроизводимым проблемам (Heisenbugs), когда конечный пользователь нажимает слишком быстро или что-то в этом роде. Предположительно, изменение в Java 7 предназначено для того, чтобы довести до сведения разработчиков это неправильное / ошибочное использование validateTree().

ОК, так что это кратковременная боль. Но в долгосрочной перспективе каждый выигрывает (кроме юристов :-)):

  • Oracle не получает отчетов об ошибках из-за странного невоспроизводимого поведения, которое действительно является проблемой для программиста приложения.

  • Разработчики не получают отчеты об ошибках от клиентов за странное невоспроизводимое поведение.

  • Конечные пользователи получают приложения, которые работают лучше.

0 голосов
/ 18 марта 2012

Я не совсем уверен, но я думаю, что вы можете использовать:

System.getProperty("java.version");

Просто проверьте, 6 или 7, и сделайте что-то другое в зависимости от этого.

...