Fundamentally, we have a design flaw in the reference tracking on browser object, and it is revealed now with message deadlock fix for FX.
The client side JSObject is tracked based on JVM GC. Each call to getJSObject() or getWebContext() actually return a new instance of JSObject. That is, each instance can be GCed. We try to maintain a reference counting system based on the native handle and ask server to release the object when the reference count reduced to 0.
On the server side, the reference count is done by browser, we simply tracking the native handle. Whenever a native handle is passed to the client side, we register it, and unregister it when client VM asked to release the object.
The bug is, same native handle can be treated as different object on the client side, and a race condition could cause the object to be released as the reference count down to 0, and noted the race condition could involve latency for getting back from server VM.
When a LiveConnect call is made to the server side, we check if the native handle is registered, and throw the exception we observed if it is not.
The FX message deadlock fix, allows FX application thread run nested message loop while waiting for the response from the browser(more precisely, server VM). Assuming we call getWindowContext() and prepared to LiveConnect call. When waiting for that response, in the nested message handler, somehow we release the JSObject obtained earlier thus could cause release on the server side. Therefore, following call to use the newly obtained JSObject will cause that exception because on the server side, the native handle had been unregistered. However, this is only a faulty alarm as the native object still hold valid in the browser.