Invalid Thread Access even with XstartOnFirstThread in vm args

后端 未结 2 1364
故里飘歌
故里飘歌 2021-01-06 06:53

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

相关标签:
2条回答
  • 2021-01-06 07:03

    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.

    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.

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

    Update

    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>
    

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

    Update 2

    Now I dug this up from here:

    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();
          }
    });
    

    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.

    Update 3

    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>
    

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

    0 讨论(0)
  • 2021-01-06 07:28

    This is an answer to the secondary question, "How can you tell if the -XstartOnFirstThread argument is actually being read by the VM?" (or the related question, "how can you detect if -XstartOnFirstThread was passed to the VM?") I looked at java.lang.management.RuntimeMXBean.getInputArguments(), but -XstartOnFirstThread is not included in the returned List. After some research, I was able to figure out something, so I hope this helps someone else who was in my shoes.

    According to this link, there are several environment variables set by the launcher. Among them are:

    JAVA_MAIN_CLASS_pid
    JAVA_STARTED_ON_FIRST_THREAD_pid

    Use System.getenv() to obtain a Map of the environment variables. From there, you can iterate through the entrySet() until you find an Entry with a getKey() whose return value starts with "JAVA_MAIN_CLASS_" . If the discovered Entry's getValue() contains the name of your main class, you can use the rest of the key to determine the pid.

    Once you have the pid, look up the string "JAVA_STARTED_ON_FIRST_THREAD_pid" in the environment Map. If it exists and has the value "1", the process was started with -XstartOnFirstThread. Otherwise, the process was started without the flag.

    This probably won't work in an unsigned WebStart application, since the System.getenv() method is prohibited by default. But in a signed webstart application, or in a regular Java application, this does work.

    Hope that helps,

    0 讨论(0)
提交回复
热议问题