Unexpected behavior during a JavaScript-to-Java call

RESOLVED WONTFIX

Status

()

RESOLVED WONTFIX
8 years ago
2 years ago

People

(Reporter: kig_de, Unassigned)

Tracking

({testcase})

5 Branch
x86
Windows 7
testcase
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

263.52 KB, application/octet-stream
Details
(Reporter)

Description

8 years ago
User-Agent:       Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
Build Identifier: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1

I face a strange behavior while making JavaScript-to-Java calls. The Javascript engine is available for any other calls while the original JavaScript-to-Java call is still active and not yet terminated. According to the LiveConnect Specification, if a JavaScript-to-Java call is made, the JavaScript engine becomes "available" for Java-to-JavaScript calls and NOT for any other calls. Other browsers like IE 8.x (classic & next-generation Java Plug-In) and Firefox 2.x (classic Java Plug-In) behave correctly and ensure that the JavaScript engine is accessed only in the required single-threaded fashion.

This implementation leads to an unexpected behavior, for example a JavaScript library which delegates the implementation to a Java Applet can't guarantee the required single-threaded fashion of the JavaScript engine. Users of the JavaScript library will expect that any function call triggered from an href/button click will run to the end without interruption before any other function call will be allowed. 

The current implementation will allows clicking the href/button once again and trigger the JavaScript library function call while the initial call is not yet terminated.

Therefore implementing a small utility function in Java is dangerous, since during the JavaScript-to-Java call, the user of the function has to set suitable synchronization mechanisms to bypass violating the Single Threaded Model of the JavaScript engine from the browser.

I have reproduced the behavior with href and button controls with the following result:
               
               1. onload: href & button are enabled, could trigger actions from both (always reproducible)
               2. applet call made after onload is finnished: 
                              If I trigger the applet call from href, I'm always able to reproduce the problem
                              If I trigger the applet call from a button, the problem is occasional (~ 1 von 10).
               3. onunload: Buttons are enabled, href not. So, I could click a button and trigger a js function, but I can't trigger a href click event.

You can reproduce this behavior with the attached testcase.

Reproducible: Always

Steps to Reproduce:
1. Make a JavaScript-to-Java call.
2. Trigger another JavaScript function while the JavaScript-to-Java call is not yet terminated.

Actual Results:  
The second JavaScript call will be executed while the initial JavaScript-to-Java call is not yet terminated.

Expected Results:  
The second JavaScript shouldn't be allowed while the initial JavaScript-to-Java call is not yet terminated, as in IE and Firefox 2.x.
(Reporter)

Comment 1

8 years ago
Created attachment 536278 [details]
Testcase to demonstrate the problem
>According to the LiveConnect Specification
where can I find it in the reference ?
https://developer.mozilla.org/en/JavaScript/Guide/LiveConnect_Overview
Component: General → Plug-ins
Product: Firefox → Core
QA Contact: general → plugins
Version: unspecified → 2.0 Branch
(Reporter)

Comment 3

8 years ago
Please take a look in the following document:

http://jdk6.java.net/plugin2/liveconnect/#JS_J_THREADING

chapter 2.5 describes the threading model in detail.
(Reporter)

Comment 4

7 years ago
today i've installed firefox 5 and run the above test case again with the following results:

1. 
onload: href & button are enabled, could trigger actions ONLY from the button!

2. applet call made after onload is finnished: 
If I trigger the applet call from href, I'm always able to reproduce the problem
If I trigger the applet call from a button, I wasn't able to reproduce the problem

It seems that the bug still appears in Firefox 5, however the behavior changed from Firefox 4 to Firefox 5
Severity: major → normal
Keywords: testcase
Version: 2.0 Branch → 5 Branch
(Reporter)

Comment 5

7 years ago
anyone working on this topic?
> anyone working on this topic?

As best I can tell, no.  And I'm not aware of any single Mozilla developer who could cover all the angles of this problem.

But I suspect you're misreading the documentation you referred to (http://jdk6.java.net/plugin2/liveconnect/#JS_J_THREADING).  So let's first address that possibility.

Part of the Threading Model section reads:

"If multiple Java threads attempt to call into the JavaScript engine, only one will be allowed through at any given time. The rest of the threads will wait for one of two situations to occur: either the initial Java-to-JavaScript call completes, or a JavaScript-to-Java call is made. In either of these occurrences, the JavaScript engine once again becomes "available" for Java-to-JavaScript calls."

This says that (generally speaking) only one *Java* thread at a time should be be allowed access to the JavaScript engine.

I haven't yet looked at your testcase.  But you appear expect that no other JavaScript threads should run (or calls be made) while a Java-to-JavaScript call is active.  This *isn't* implied by the text I quoted above.
(Reporter)

Comment 7

7 years ago
Actually, what I expect is that no other JavaScript threads should run (or calls be made) while a JavaScript-to-Java call is active. But, what you mentioned, "no other JavaScript threads should run (or calls be made) while a Java-to-JavaScript call is active", is already fulfilled by Firefox, otherwise the single-threaded nature of the JavaScript engine with respect to the web page is no longer guaranteed.

This implementation leads to an unexpected behavior, for example a JavaScript library which delegates the implementation to a Java Applet can't guarantee the required single-threaded fashion of the JavaScript engine. Users of the JavaScript library will expect that any function call triggered from an href/button click will run to the end without interruption before any other function call will be allowed.
What you say confirms that you're misreading the doc you referenced.

There's nothing in it that says the JavaScript engine *must* be
single-threaded.  It does say that "the JavaScript engines in all of
today's web browsers are conceptually single threaded with respect to
the web page."	But while this was true	of Firefox for a while, I
don't think it is any longer.

Jst, do you have any observations on this?  Do you know if our
JavaScript engine is now multithreaded?

Also, do you know if only one Java thread at a time is allowed to
access the JavaScript engine?  And if you don't know, who should we
ask?
dmandelin, do you have any observations on this bug?

Is our JavaScript engine now multithreaded?

Do you know if only one Java thread at a time allowed access to the
JavaScript engine (as expected by
http://jdk6.java.net/plugin2/liveconnect/#JS_J_THREADING)?

Would you say that, even if our JavaScript engine is multithreaded, it
is (or should be) "conceptually single threaded with respect to the
web page"?
> Do you know if only one Java thread at a time is allowed to access
> the JavaScript engine?

Please answer this question, jst and dmandelin, if you can.

But, now that Liveconnect is implemented entirely in the Java plugin
(as of Java Plugin2), it may be up to the Java plugin to enforce this
-- in which case we (probably) don't have to worry about it.
(Reporter)

Comment 11

7 years ago
Is it really possible that the Java PlugIn can control the synchronization mechanism of the Javascript Engine? If that’s the case it sounds strange to me that other browsers like IE behave differently to Firefox.

However, suppose you have a scenario where you trigger a Java utility function from HTML Controls (or href), which calculates something. In previous FF versions and other browsers such utility functions were called synchronous but now in Firefox this is no longer guaranteed. This brings us to a point that web applications have now a completely different runtime behavior in case of threading depending on the browser version. 

From my point of view it’s really a fundamental requirement that the called Java function will be executed completely before another Javascript function can be called. If you can’t guarantee the Javascript single threaded fashion, developers have to build a Firefox specific handling for their Java / Live Connect based web applications.
The JavaScript that runs in a webpage is, and always has been, only ever able to run on the main thread in Firefox. The JS engine itself is in some ways thread safe, but not in the way that it's used for webpage JS in the browser. As far as Firefox goes here, there's nothing special about calling from JS into Java or the other way around, that goes through the same APIs that all plugins are scriptable through, and all those calls are completely synchronous from our point of view. But I know that the Java plugin runs the applet itself (i.e. the Java code you point the browser at) in a different process (we do make an exception for the Java plugin in that we don't run it in its own process since it already runs the Java code in a separate process), and whether that Java code uses one or more threads is up to the Java code itself and possibly the Java plugin. But at the API layer between the browser and Java we enforce that all those calls happen on the main thread (with one exception which is an API that's explicitly callable from other threads to funnel calls to the main thread, and some additional exceptions where we just warn instead of actually enforcing).

What's most likely happening here is that the Java plugin allows the browser to process messages while it's waiting for a synchronous call to complete and return, which could lead to timers or UI events or what not to trigger additional JS to run while the JS code that called into Java is still waiting for the call to return. I really doubt there's any other threads involved here.

I don't know that there's anything we can do to fix this on our end, I would take this up with the Java plugin developers at Oracle.
Out of curiosity, how is this behaving in Google Chrome?
(Reporter)

Comment 14

7 years ago
I ll create a corresponding entry in the Java Bug Database and will inform you about the results here

Comment 15

7 years ago
The important point here is: the browser thread does block waiting for a call to plugins to return. But if the plugin spins the event loop (which is a terrible idea, but many plugins do it anyway), then the browser can reenter through events such as additional mousemoves/mouseclicks or even networking events.
I'm marking this bug as WONTFIX per bug #1269807.

For more information see - https://blog.mozilla.org/futurereleases/2015/10/08/npapi-plugins-in-firefox/
Status: UNCONFIRMED → RESOLVED
Last Resolved: 2 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.