如何诊断无效的线程访问SWTException?

时间:2023-01-12 15:59:13

We're customizing an Eclipse RCP based tool for a client. They have trouble loading it on one of their computers (it works on others) and have provided the following error log.

我们正在为客户端定制基于Eclipse RCP的工具。他们无法在其中一台计算机上加载它(它可以在其他计算机上运行),并提供了以下错误日志。

!SESSION 2009-01-23 12:09:05.593 ----------------------------------------------- eclipse.buildId=unknown java.version=1.5.0_12 java.vendor=Sun Microsystems Inc. BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=en_GB Command-line arguments: -os win32 -ws win32 -arch x86

!SESSION 2009-01-23 12:09:05.593 -------------------------------------- --------- eclipse.buildId = unknown 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 !MESSAGE Bundle com.yantra.yfc.rcp.desktop.ri not found.

!ENTRY org.eclipse.osgi 4 0 2009-01-23 12:09:07.500!MESSAGE Bundle com.yantra.yfc.rcp.desktop.ri not found。

!ENTRY org.eclipse.osgi 4 0 2009-01-23 12:09:11.906 !MESSAGE Application error !STACK 1 org.eclipse.swt.SWTException: Invalid thread access at org.eclipse.swt.SWT.error(SWT.java:3374) at org.eclipse.swt.SWT.error(SWT.java:3297) at org.eclipse.swt.SWT.error(SWT.java:3268) at org.eclipse.swt.widgets.Display.error(Display.java:978) at org.eclipse.swt.widgets.Display.checkDevice(Display.java:638) at org.eclipse.swt.graphics.Device.dispose(Device.java:261) at com.yantra.yfc.rcp.YRCApplication.run(YRCApplication.java:176) at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.core.launcher.Main.invokeFramework(Main.java:334) at org.eclipse.core.launcher.Main.basicRun(Main.java:278) at org.eclipse.core.launcher.Main.run(Main.java:973) at org.eclipse.core.launcher.Main.main(Main.java:948)

!ENTRY org.eclipse.osgi 4 0 2009-01-23 12:09:11.906!MESSAGE应用程序错误!堆栈1 org.eclipse.swt.SWTException:org.eclipse.swt.SWT.error中的无效线程访问(SWT。 java:3374)org.eclipse.swt.Swt.WR.::::: or or or or or or or or or or or or or or or or or or or or or or or or or or or or or or or or or or or or (show.java:978)位于org.eclipse.swt.wts.wtis.checkDevice(Display.java:638)的org.eclipse.swt.graphics.Device.dispose(Device.java:261)com.yantra。 yfc.rcp.YRCApplication.run(YRCApplication.java:176)atg.eclipse.core.internal.runtime.PlatformActivator $ 1.run(PlatformActivator.java:78)org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher位于org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java)的org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)中的.runApplication(EclipseAppLauncher.java:92) :400)在sun.reflect.NativeMeth的org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)位于org.eclipse的java.lang.reflect.Method.invoke(未知来源)的sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)的sun.reflect.NativeMethodAccessorImpl.invoke(未知来源)中的odAccessorImpl.invoke0(本地方法)。在org.eclipse.core.auncher.Main.run(Main.java: 973)在org.eclipse.core.launcher.Main.main(Main.java:948)

I have googled the exception but this seems to happen mostly when people try to develop applications using different threads. Since we don't see this problem on any other computer I'm at a loss as to what might be causing it.

我搜索了异常,但这似乎主要发生在人们尝试使用不同线程开发应用程序时。由于我们在任何其他计算机上都没有看到这个问题,所以我不知道可能导致它的原因。

It must be a configuration problem on the machine in question, as the code is from the vendor (so presumably well tested) and works on every other machine we've tested it on.

它必须是有问题的机器上的配置问题,因为代码来自供应商(因此可能经过良好测试)并且可以在我们测试过的其他每台机器上运行。

Does anyone have any suggestions about what might be behind the problem for that computer? Or suggestions about lines of investigation which might reveal the issue?

有没有人对该计算机的问题可能背后有什么建议?或者有关可能揭示问题的调查线索的建议?

4 个解决方案

#1


It seems to me that an Exception is thrown in the application thread, that happens only in some machines. Probably there is code in the RCP application to display the exception on the GUI with some dialog box, but this is done in the wrong thread. That would explain why it happens only on some machines. It would also explain why the problem went undetected.... it probably never happens in the dev's computers so they never bothered to check that the UI Access is done using the right thread. I had a similar problem once.

在我看来,在应用程序线程中抛出异常,这只发生在某些机器上。可能在RCP应用程序中有代码在GUI上显示异常并带有一些对话框,但这是在错误的线程中完成的。这可以解释为什么它只发生在一些机器上。它还可以解释为什么问题没有被发现......它可能永远不会发生在开发人员的计算机中,因此他们从不打扰检查UI访问是否使用正确的线程完成。我有一次类似的问题。

My suggestion would be to take a close look to:

我的建议是仔细看看:

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

As the code is compiled with line numbers, you can attach a debugger to this line even if you have no source code, and try to see what happens. I am pretty sure that when you hit this breakpoint on the problematic machine, an Exception will be thrown. That will be your "Real" exception.

由于代码是使用行号编译的,即使您没有源代码,也可以将调试器附加到此行,并尝试查看会发生什么。我很确定当你在有问题的机器上遇到这个断点时,会抛出异常。这将是你的“真实”例外。

#2


There's only one UI thread in Eclipse. In a nutshell, the rules are:

Eclipse中只有一个UI线程。简而言之,规则是:

  • If you got called as part of a UI operation (e.g. event handler, view initialization) you are in the UI thread.
  • 如果您作为UI操作的一部分被调用(例如事件处理程序,视图初始化),那么您将处于UI线程中。

  • All other operations that invoke a UI (e.g. a job which needs to show a dialog or send information to a view which modifies a widget) - need to sync with the UI thread.
  • 调用UI的所有其他操作(例如,需要显示对话框或将信息发送到修改窗口小部件的视图的作业) - 需要与UI线程同步。

This is basically done like this:

这基本上是这样做的:

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

Your code goes in the run method. You may also use the asyncExec method to continue without waiting for the UI to finish.

你的代码在run方法中。您也可以使用asyncExec方法继续,而无需等待UI完成。

Try using the snippet above to wrap the problematic code.

尝试使用上面的代码片段来包装有问题的代码。

EDIT: Ending bracket for Runnable() was missing in the snippet . After adding snippet works fine.

编辑:片段中缺少Runnable()的结束括号。添加片段后工作正常。

#3


You can also find the answer in The Official Eclipse FAQs, in particular: Why do I get an invalid thread access exception?

您还可以在官方Eclipse常见问题解答中找到答案,特别是:为什么我会收到无效的线程访问异常?

#4


If looking at the source code for YRCApplication line 176 does not help (why is it calling Display.dispose() when it is about to start?), I would attach an external debugger to the process running on that particular machine. Have a look at http://wiki.eclipse.org/Ninja#How_to_run_Eclipse_so_that_you_can_attach_an_external_debugger for instructions; if you try to remote-debug the situation from a remote machine you'd have to ensure that firewalls etc. are not blocking the TCP connection used by the debugger.

如果查看YRCApplication行176的源代码没有帮助(为什么它将要启动时调用Display.dispose()?),我会将一个外部调试器附加到该特定机器上运行的进程。请查看http://wiki.eclipse.org/Ninja#How_to_run_Eclipse_so_that_you_can_attach_an_external_debugger获取指示;如果您尝试从远程计算机远程调试情况,则必须确保防火墙等不会阻止调试器使用的TCP连接。

#1


It seems to me that an Exception is thrown in the application thread, that happens only in some machines. Probably there is code in the RCP application to display the exception on the GUI with some dialog box, but this is done in the wrong thread. That would explain why it happens only on some machines. It would also explain why the problem went undetected.... it probably never happens in the dev's computers so they never bothered to check that the UI Access is done using the right thread. I had a similar problem once.

在我看来,在应用程序线程中抛出异常,这只发生在某些机器上。可能在RCP应用程序中有代码在GUI上显示异常并带有一些对话框,但这是在错误的线程中完成的。这可以解释为什么它只发生在一些机器上。它还可以解释为什么问题没有被发现......它可能永远不会发生在开发人员的计算机中,因此他们从不打扰检查UI访问是否使用正确的线程完成。我有一次类似的问题。

My suggestion would be to take a close look to:

我的建议是仔细看看:

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

As the code is compiled with line numbers, you can attach a debugger to this line even if you have no source code, and try to see what happens. I am pretty sure that when you hit this breakpoint on the problematic machine, an Exception will be thrown. That will be your "Real" exception.

由于代码是使用行号编译的,即使您没有源代码,也可以将调试器附加到此行,并尝试查看会发生什么。我很确定当你在有问题的机器上遇到这个断点时,会抛出异常。这将是你的“真实”例外。

#2


There's only one UI thread in Eclipse. In a nutshell, the rules are:

Eclipse中只有一个UI线程。简而言之,规则是:

  • If you got called as part of a UI operation (e.g. event handler, view initialization) you are in the UI thread.
  • 如果您作为UI操作的一部分被调用(例如事件处理程序,视图初始化),那么您将处于UI线程中。

  • All other operations that invoke a UI (e.g. a job which needs to show a dialog or send information to a view which modifies a widget) - need to sync with the UI thread.
  • 调用UI的所有其他操作(例如,需要显示对话框或将信息发送到修改窗口小部件的视图的作业) - 需要与UI线程同步。

This is basically done like this:

这基本上是这样做的:

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

Your code goes in the run method. You may also use the asyncExec method to continue without waiting for the UI to finish.

你的代码在run方法中。您也可以使用asyncExec方法继续,而无需等待UI完成。

Try using the snippet above to wrap the problematic code.

尝试使用上面的代码片段来包装有问题的代码。

EDIT: Ending bracket for Runnable() was missing in the snippet . After adding snippet works fine.

编辑:片段中缺少Runnable()的结束括号。添加片段后工作正常。

#3


You can also find the answer in The Official Eclipse FAQs, in particular: Why do I get an invalid thread access exception?

您还可以在官方Eclipse常见问题解答中找到答案,特别是:为什么我会收到无效的线程访问异常?

#4


If looking at the source code for YRCApplication line 176 does not help (why is it calling Display.dispose() when it is about to start?), I would attach an external debugger to the process running on that particular machine. Have a look at http://wiki.eclipse.org/Ninja#How_to_run_Eclipse_so_that_you_can_attach_an_external_debugger for instructions; if you try to remote-debug the situation from a remote machine you'd have to ensure that firewalls etc. are not blocking the TCP connection used by the debugger.

如果查看YRCApplication行176的源代码没有帮助(为什么它将要启动时调用Display.dispose()?),我会将一个外部调试器附加到该特定机器上运行的进程。请查看http://wiki.eclipse.org/Ninja#How_to_run_Eclipse_so_that_you_can_attach_an_external_debugger获取指示;如果您尝试从远程计算机远程调试情况,则必须确保防火墙等不会阻止调试器使用的TCP连接。