Как диагностировать недопустимый поток доступа SWTException? - PullRequest
2 голосов
/ 04 февраля 2009

Мы настраиваем инструмент на основе Eclipse RCP для клиента. У них проблемы с загрузкой его на один из их компьютеров (он работает на других) и предоставили следующий журнал ошибок.

! СЕССИЯ 2009-01-23 12: 09: 05.593 ----------------------------------------------- eclipse.buildId = неизвестно java.version = 1.5.0_12 java.vendor = Sun Microsystems Inc. BootLoader константы: OS = win32, ARCH = x86, WS = win32, NL = en_GB Командная строка Аргументы: -os win32 -ws win32 -arch x86

! ENTRY org.eclipse.osgi 4 0 2009-01-23 12: 09: 07.500! СООБЩЕНИЕ com.yantra.yfc.rcp.desktop.ri нет найдено.

! ENTRY org.eclipse.osgi 4 0 2009-01-23 12: 09: 11.906! СООБЩЕНИЕ ошибка! STACK 1 org.eclipse.swt.SWTException: Invalid доступ к потоку в org.eclipse.swt.SWT.error (SWT.java:3374) в org.eclipse.swt.SWT.error (SWT.java:3297) в org.eclipse.swt.SWT.error (SWT.java:3268) в org.eclipse.swt.widgets.Display.error (Display.java:978) в org.eclipse.swt.widgets.Display.checkDevice (Display.java:638) в org.eclipse.swt.graphics.Device.dispose (Device.java:261) в com.yantra.yfc.rcp.YRCApplication.run (YRCApplication.java:176) в org.eclipse.core.internal.runtime.PlatformActivator $ 1.run (PlatformActivator.java:78) в org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication (EclipseAppLauncher.java:92) в org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start (EclipseAppLauncher.java:68) в org.eclipse.core.runtime.adaptor.EclipseStarter.run (EclipseStarter.java:400) в org.eclipse.core.runtime.adaptor.EclipseStarter.run (EclipseStarter.java:177) в sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Метод) в sun.reflect.NativeMethodAccessorImpl.invoke (Неизвестно Источник) в sun.reflect.DelegatingMethodAccessorImpl.invoke (Неизвестно Источник) в java.lang.reflect.Method.invoke (Неизвестно Источник) в org.eclipse.core.launcher.Main.invokeFramework (Main.java:334) в org.eclipse.core.launcher.Main.basicRun (Main.java:278) в org.eclipse.core.launcher.Main.run (Main.java:973) в org.eclipse.core.launcher.Main.main (Main.java:948)

Я погуглил исключение, но, похоже, это происходит в основном, когда люди пытаются разрабатывать приложения, используя разные потоки. Поскольку мы не видим эту проблему ни на одном другом компьютере, я не понимаю, что может быть причиной этого.

Это должна быть проблема конфигурации на рассматриваемой машине, так как код от производителя (так что, вероятно, хорошо протестирован) и работает на любой другой машине, на которой мы его тестировали.

Есть ли у кого-нибудь предложения о том, что может быть причиной проблемы для этого компьютера? Или предложения о направлениях расследования, которые могут выявить проблему?

Ответы [ 4 ]

11 голосов
/ 04 февраля 2009

В Eclipse только один поток пользовательского интерфейса. В двух словах, правила таковы:

  • Если вас вызвали как часть операции пользовательского интерфейса (например, обработчик событий, просмотр инициализации), вы находитесь в потоке пользовательского интерфейса.
  • Все другие операции, которые вызывают пользовательский интерфейс (например, задание, которое должно отображать диалоговое окно или отправлять информацию в представление, которое изменяет виджет), - должны синхронизироваться с потоком пользовательского интерфейса.

В основном это делается так:

 Display.getDefault().syncExec( new Runnable() {  public void run() { } });

Ваш код идет в методе run. Вы также можете использовать метод asyncExec, чтобы продолжить, не дожидаясь завершения пользовательского интерфейса.

Попробуйте использовать фрагмент кода выше, чтобы обернуть проблемный код.

EDIT : Конечная скобка для Runnable () отсутствовала во фрагменте. После добавления сниппет работает нормально.

2 голосов
/ 05 февраля 2009

Мне кажется, что в потоке приложения создается исключение, которое происходит только на некоторых машинах. Возможно, в приложении RCP есть код для отображения исключения в графическом интерфейсе с некоторым диалоговым окном, но это сделано не в том потоке. Это объясняет, почему это происходит только на некоторых машинах. Это также объясняет, почему проблема осталась незамеченной ... это, вероятно, никогда не происходит на компьютерах разработчиков, поэтому они никогда не удосужились проверить, что доступ к пользовательскому интерфейсу выполняется с использованием правильного потока. Однажды у меня была похожая проблема.

Мое предложение было бы присмотреться к:

com.yantra.yfc.rcp.YRCApplication.run (YRCApplication.java:176)

Поскольку код компилируется с номерами строк, вы можете присоединить к этой строке отладчик, даже если у вас нет исходного кода, и попытаться увидеть, что произойдет. Я почти уверен, что когда вы достигнете этой точки останова на проблемной машине, возникнет исключение. Это будет ваше "настоящее" исключение.

1 голос
/ 04 февраля 2009
0 голосов
/ 09 февраля 2009

Если просмотр исходного кода строки YRCApplication 176 не помогает (почему он вызывает Display.dispose (), когда он собирается начать работу?), Я бы подключил внешний отладчик к процессу, работающему на этой конкретной машине. Посмотрите на http://wiki.eclipse.org/Ninja#How_to_run_Eclipse_so_that_you_can_attach_an_external_debugger для получения инструкций; если вы попытаетесь выполнить удаленную отладку ситуации с удаленного компьютера, вам необходимо убедиться, что брандмауэры и т. д. не блокируют TCP-соединение, используемое отладчиком.

...