即使在 vm args 中使用 XstartOnFirstThread,线程访问也无效 [英] Invalid Thread Access even with XstartOnFirstThread in vm args

查看:28
本文介绍了即使在 vm args 中使用 XstartOnFirstThread,线程访问也无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有单个类的初级 Java Web Start 应用程序.它在 Windows 和 Linux 上运行,但在 Mac OS X 上出现可怕的无效线程访问错误.我意识到这已经在别处处理过.我花了整整两天的时间在网上搜索并实施了所有解决方案,但问题仍然存在.

I have an embryonic Java Web Start application with a single class. It runs on Windows and Linux but gets the dreaded Invalid Thread Access error on Mac OS X. I realise that this has been dealt with elsewhere. I have spent two full days scouring the Internet and have implemented all the solutions, but the problem persists.

我的理解是必须从主线程调用 SWT,这里就是这种情况.如果我错了,请纠正我.

My understanding is that calls to SWT must be made from the main thread which is the case here. Correct me if I am wrong in that.

我将在下面发布 3 个片段,应用程序的源代码、jnlp 文件的相关部分和 Mac 上的错误消息.问题在最后.

I will post 3 snippets below, the source code of the application, the relevant part of the jnlp file and the error message on the Mac. The question is at the end.

Java 源代码

package client;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class AccountWindow {
 public static void main(String[] args) {
  Display display = new Display(); **// error occurs here**
  Shell shell = new Shell(display); shell.open();
  while (!shell.isDisposed()) {
   if (!display.readAndDispatch())
    display.sleep();
  }
  display.dispose();
 }
}

<小时>

JNLP 代码段


JNLP SNIPPET

<resources os="Mac\ OS\ X" arch="x86_64">
    <j2se version="1.5+" java-vm-args="-XstartOnFirstThread" />
    <nativelib href="swt-4.2-cocoa-macosx-x86_64.jar" />
</resources>

<小时>

错误信息


ERROR MESSAGE

org.eclipse.swt.SWTException: Invalid thread access
    at org.eclipse.swt.SWT.error(Unknown Source)
    at org.eclipse.swt.SWT.error(Unknown Source)
    at org.eclipse.swt.SWT.error(Unknown Source)
    at org.eclipse.swt.widgets.Display.error(Unknown Source)
    at org.eclipse.swt.widgets.Display.createDisplay(Unknown Source)
    at org.eclipse.swt.widgets.Display.create(Unknown Source)
    at org.eclipse.swt.graphics.Device.<init>(Unknown Source)
    at org.eclipse.swt.widgets.Display.<init>(Unknown Source)
    at org.eclipse.swt.widgets.Display.<init>(Unknown Source)
    at client.AccountWindow.main(AccountWindow.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.sun.javaws.Launcher.executeApplication(Launcher.java:1550)
    at com.sun.javaws.Launcher.executeMainClass(Launcher.java:1488)
    at com.sun.javaws.Launcher.doLaunchApp(Launcher.java:1299)
    at com.sun.javaws.Launcher.run(Launcher.java:114)
    at java.lang.Thread.run(Thread.java:637)

<小时>

请注意
- display.syncExec 解决方案发布在 http://www.eclipse.org/swt/faq.php#javawebstart 不适用,因为在您可以调用它之前,您需要一个显示.当我尝试创建显示时会发生这里的错误.
- 我已经使用 JaNeLa 来验证 jnlp 文件并且没有红色错误.
- <resources os="Mac\ OS\ X" arch="i386">正在被正确解释,因为正在加载正确的 swt 库.
- 您可以在 http://thelinkjuicer.com/gannonline/client.jnlp


PLEASE NOTE
- The display.syncExec solution posted at http://www.eclipse.org/swt/faq.php#javawebstart is not applicable because before you can invoke it you need a display. The error here happens when I try to create the display.
- I have used JaNeLa to validate the jnlp file and there are no red errors.
- <resources os="Mac\ OS\ X" arch="i386"> is being correctly interpreted because the correct swt library is being loaded.
- You can reproduce the error at http://thelinkjuicer.com/gannonline/client.jnlp

现在是问题
任何人都可以在源代码或 jnlp 片段中看到任何会导致错误的内容吗?
次要问题:如何判断 -XstartOnFirstThread 参数是否真的被 VM 读取?

AND NOW THE QUESTION
Can anyone see anything in the source code or the jnlp snippet that would cause the error?
Secondary question: how can you tell if the -XstartOnFirstThread argument is actually being read by the VM?

推荐答案

很明显,您的 main 方法没有在主线程上执行.在堆栈跟踪中可以看到启动器实际上是在另一个线程中启动的,然后Launcher 只是间接调用了main.不幸的是,这只是诊断,我不确定解决方案.我做过类似的事情(通过 Java Web Start 的 SWT 应用程序),但我不记得我们是如何解决这个问题的,如果有的话.

Clearly, your main method is not being executed on the main thread. You can see in the stack trace that the launcher is actually started in another thread, and then the Launcher only indirectly calls main. This is unfortunately just the diagnostic, I am not sure about the solution. I have done a similar thing (SWT app through Java Web Start), but I can't remember how we solved this, if at all.

检查之后com.sun.javaws.Launcher 源代码,目前尚不清楚如何使其工作.Launcher.launch 方法启动一个新线程,在该线程中执行您的 main 方法.您可以按照代码重新创建您获得的确切堆栈跟踪.

After checking the com.sun.javaws.Launcher source code, it is quite unclear how this could be made to work. The Launcher.launch method starts a new thread within which your main method is executed. You can follow the code to recreate the exact stacktrace you are getting.

Java Web Start 的主入口点 显示主线程在启动后很快就死了.

The main entry point of Java Web Start shows that the main thread dies soon after starting.

我发现了一些东西:在 这个 Eclipse 错误报告中建议问题可能与此有关:

I dug something out: in this Eclipse bug report it is suggested that the problem could be related to this:

<resources>
  <j2se version="1.4+" />
  <jar href="client.jar" />
</resources>

解析器从这里获取 j2se 规范并忽略后面更具体的规范.尝试删除 <j2se... 行.

The parser takes the j2se spec from here and ignores the later, more specific ones. Try removing the <j2se... line.

现在我从这里挖掘出来:

com.apple.concurrent.Dispatch.getInstance().getNonBlockingMainQueueExecutor().execute(
  new Runnable() { public void run() {
      final Display display = Display.getDefault(); 
      while (!display.isDisposed()) {
        if (!display.readAndDispatch())
          display.sleep();
      }
});

这听起来确实可行.它完全符合我在下面的评论中所描述的:通过为此目的专门设置的机制修补到主线程中.尝试使其适应您的需要.你甚至可能不需要 -XstartOnFirstThread .

This actually sounds like something workable. It does exactly what I described in my comment below: patches into the main thread through a mechanism specifically put in place for this purpose. Try to adapt this to your need. You may not even need -XstartOnFirstThread with this.

我终于找到了我的旧 SWT-JWS 项目.里面有这个:

I finally found my old SWT-JWS project. It's got this in it:

<resources os="Mac OS X" arch="x86_64">
  <j2se version="1.6+" java-vm-args="-XstartOnFirstThread"/>
  <jar href="swt-cocoa-macosx-x86-64-3.6.2.jar" />
</resources>

它的工作原理.它没有默认的 j2se 元素,该元素出现在 OSX 特定的条目中.

and it works. It has no default j2se element, this element appears only in the OSX-specific entry.

这篇关于即使在 vm args 中使用 XstartOnFirstThread,线程访问也无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆