Welcome guest, is this your first visit? Create Account now to join.
Results 1 to 5 of 5

This is a discussion on Chrome selects wrong thread for JS-Java upcall on 2nd(ish) Applet instance within the Bugs and Vulnerabilities section, part of the Google Chrome category: Hi, This is directly related to "fix" for SDN Bug ID 6742814: - http://bugs.sun.com/bugdatabase/view...bug_id=6742814 A couple of relevant-sounding quotes from ...


  1. #1
    Richard Maher is offline Junior Member
    Join Date
    Oct 2010
    Posts
    3

    Exclamation Chrome selects wrong thread for JS-Java upcall on 2nd(ish) Applet instance

    Hi,

    This is directly related to "fix" for SDN Bug ID 6742814: -
    http://bugs.sun.com/bugdatabase/view...bug_id=6742814

    A couple of relevant-sounding quotes from that bug report : -
    {
    The rules for initiating JavaScript-to-Java and Java-to-JavaScript
    calls (which will be formalized in the forthcoming new LiveConnect
    specification) are:

    - JavaScript-to-Java calls against a given applet block until that
    applet has completed init(), or

    - that applet initiates a Java-to-JavaScript call in init().
    }

    The definition of "initiates a Java-to-JavaScript" in that last line appears
    to have been further broadened and amplified to include: -
    {
    - If a request comes to the browser from an applet to fetch the
    JavaScript window object corresponding to the applet, drain the
    queued up messages corresponding to JavaScript-to-Java calls,
    which would otherwise occur when init() was completed.
    }

    This was raised as an issue for me in comp.lang.java on the 22-April-2009
    and Mark Space kindly pointed out that the addition of "synchronized" to the
    relevant Applet methods would achieve the desired results, with the worker
    methods only being invoked after the Applet had completed its initialization
    in the init() method. So everything was peachy until I found that Google
    Chrome can, and often does, choose the wrong thread to execute the JS to
    Java upcall when dealing with more than one instance of the Applet in the
    browser instance. (Different tabs in my case)

    You may recall that my Javascript to invoke the Applet looked like this: -

    document.body.appendChild(appletDiv);
    tier3Chan = document.getElementById(appletId);
    var userAuthorized = tier3Chan.isAuthorized();
    }
    catch(err) {
    alert("Err =" + err.description);
    tier3Chan = null;
    };

    What "normally" happens (Firefox, IE, Chrome-[with-Applet-Instance/Tab-1])
    is that: -

    1) The "getElementById(appletId)" loads the Applet and calls init() in a
    thread the JVM calls: -
    "thread applet-tier3Client/Tier3Application-1"
    My package is "tier3Client" and the class is "Tier3Application" and the
    applet instance is "1".
    2) The tier3Chan.isAuthorized() method (JS->JAVA upcall) is executed on a
    new LiveConnect thread called: -
    "Applet 1 LiveConnect Worker Thread"
    Again the "1" relating to the applet instance in the browser. When the
    applet is loaded again via pages in other tabs the instance number is
    incremented and new threads created.
    3) I also instantiate another Thread that can call down to JS but I don't
    believe that to be relevant at this stage.
    4) When my init() method calls JSObject.getWindow(this) Chrome seeks to
    "drain the queued up messages corresponding to JavaScript-to-Java calls,
    which would otherwise occur when init() was completed" and my isAuthorized()
    method is invoked on the "Applet 1 LiveConnect Worker Thread".
    5) Because both my overridden init() method and my isAuthorized() methods
    are synchronized on the Applet instance's object, the isAuthorized() method
    is forced to wait until initialization is complete and authorization has
    been checked.

    A tad complicated but it worked and I was happy with it.

    What appears to go wrong with Chrome on the 2nd -(usually the 2nd but then
    it might work/fail for additional tabs - the first page always works)- tab
    with an applet invoking page is that the isAuthorized() upcall gets executed
    on the "thread applet-tier3Client/Tier3Application-2" Thread. The same
    Thread that init() was/is executing on!!!

    Now my understanding of the Java threading model is that, to support
    recursion, a Thread cannot lock/mutex/synchronize itself out of an object.
    So my "synchronized" init() and isAuthorized() methods on the Applet 2
    instance don't amount to a hill o' beans and my authorization check occurs
    *before* I've determined if the user is authorized and I've had a chance to
    set the variable :-(

    To summarize, Chrome has a bug where it can permit an upcall to execute on
    the "thread applet-tier3Client/Tier3Application-(n)" thread instead of the
    "Applet (n) LiveConnect Worker Thread". Try as I might I cannot create a
    "simple" reproducer for this :-( My Applet is quite complex and I'm
    clutching at straws to guess what algorithm Chrome uses when looking for
    threads to allocate work to, or for Threads to publish their availability.

    Can someone please shed any light on this? Is there a work around? Is there
    a useful Chrome bug-logging forum that will even look at the source without
    a reproducer to go on?

    Look, I know I shot my mouth off before about this being a race condition
    where the isAuthorized() was being called *before* the init() but that was
    because I couldn't cope with the concept of synchronized Applet instance
    methods executing at the same time.

    Please help if you can.

    Cheers Richard Maher

  2. #2
    Richard Maher is offline Junior Member
    Join Date
    Oct 2010
    Posts
    3

    Default

    Hi,

    Here is some version info: -

    Chrome 7.0.517.41
    Java 1.6.20-b02
    Windows XP SP3

    And here's a recent Java console log that clearly shows the isAuthorized() method occuring halfway through *and in the same thread* as the init() method: -

    basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt
    324932 us, pluginInit dt 51588923 us, TotalTime: 51913855 us
    Tier3Client Applet
    Version 1.0
    Copyright (c) Richard Maher
    All rights reserved.

    In init() Thread: [thread applet-tier3Client/Tier3Application.class-2]
    toString = Thread[thread
    applet-tier3Client/Tier3Application.class-2,4,http://192.168.1.159/Applets/-threadGroup]
    hash = 180b22e
    03/11/2010 9:31:21 PM tier3Client.Tier3Application isAuthorized
    INFO: In isAuthorized() Thread: [thread
    applet-tier3Client/Tier3Application.class-2] toString = Thread[thread
    applet-tier3Client/Tier3Application.class-2,4,http://192.168.1.159/Applets/-threadGroup]
    hash = 180b22e
    topDocHost = 192.168.1.159
    Called 2 times
    The value of i is 0
    03/11/2010 9:31:21 PM tier3Client.Tier3Application init
    INFO: Init() - Session ID is 0 refCnt = 1
    Null index is -1
    After connect
    03/11/2010 9:31:21 PM tier3Client.Tier3Application init
    INFO: Applet initialization complete - WindowSlotIndex is 1
    Leaving init() Thread: [thread applet-tier3Client/Tier3Application.class-2]
    toString = Thread[thread
    applet-tier3Client/Tier3Application.class-2,4,http://192.168.1.159/Applets/-threadGroup]
    hash = 180b22e
    basic: Applet initialized

    Cheers Richard Maher

    PS. Is this forum still active? Is there a better Chrome forum than this one?

  3. #3
    Richard Maher is offline Junior Member
    Join Date
    Oct 2010
    Posts
    3

    Default Example code

    Hi again,

    Below is from a post I made yesterday to comp.lang.java.programmer. It contains the code for an attempt at reproducing the problem.

    Cheers Richard Maher

    Hi Daniel,

    "Daniel Pitts" <newsgroup.spamfilter@virtualinfinity.net> wrote in message
    news:NZsAo.3996$8m.468@newsfe09.iad...
    > On 11/3/2010 7:03 AM, Richard Maher wrote:
    8<
    >> Do you not see the same thread being used from init() [up until the code
    >> that calls JSObject.getWindow(this)] then isAuthorized receives control
    >> of
    >> the very same thread, and when that finishes the rest of init() gets
    >> processed.
    > So, the problem appears to be that JSObject.getWindow(this) actually cedes
    > control back to the JS engine parser.

    No, I/we can put up with this wierdness; what I cannot countenance is Chrome
    *and specifically/uniquely Chrome* draining-the-queue via the same bloody
    Thread that init() is running in!

    If someone could just postulate on (a) How the JS-Java upcall gets allocated
    to a Thread, (b) How such swinger Threads make their availability known to
    Chrome, and/or (c) How a Java Thread unilaterally assigns itself available
    work, then I'm more than willing to hear it!

    My theory is that, on the 2nd applet instance, the timing is such that the
    isAuthorized() Applet call arrives before Chrome has had a chance to set the
    There's-Tricky-LiveConnect-Crap-Here flag and the method gets executed on
    the natural choice of the standard applet thread rather than the LiveConnect
    worker thread. But someone with knowledge of A, B, or C from above would be
    in a far better place to answer that question.

    > Perhaps you should avoid calling JSObject.getWindow(this) in init().

    Yes, yes, yes. As with your first reply, the "if (firstTimeFlag = "Y")
    doInit();" should work, but it's bloody inconvenient writing off everything
    that Applet.init() is contracted to do and is just bollocks in my opinion.
    Having said that, pragmatism leads me in that direction :-(

    Again, this is only Chrome. (BTW for IE>7 you have to set the registry
    setting TabProcGrowth < 2)

    >>
    >> Is currentThread() stooging me? Is there something there that I don't
    >> understand? Or is it you that won't see what's in front of our faces?
    > Yes, there is a lot you don't understand, like how to put together an
    > SSCCE which could show this problem ;-).

    Look the crying shame (and imho more evidence of the exception/bug) is that
    I can't reproduce it without the several thousand complex lines of Java that
    goes with it :-( Having said that, please see below for a "working" version
    that happily engages the LiveConnect Worker Thread for isDone() every time.

    If anyone is willing to play around with this in order to reproduce the
    described behaviour then compile Sleeper.java and OutThread.java in to a JAR
    called Sleeper2.jar then stick that in your web root directory with
    dyntest.html and give it a go. Turn the Java Console on to see what's
    happening.

    > Anyway, the solution is to avoid calling getWindow(this) in init(), or at
    > least waiting until the rest of your initialization is complete.
    >
    > HTH,
    > Daniel.

    Cheers Richard Maher

    Sleeper.java
    =========

    import java.applet.Applet;
    import netscape.javascript.JSObject;
    //import netscape.javascript.JSException;
    //import java.lang.InterruptedException;
    import java.util.ArrayList;

    public class Sleeper extends Applet {
    private int myNum = 0;
    private JSObject browser;
    private volatile static int appletIndex = 0;
    private static OutThread writer;
    private boolean initFlag = false;
    private volatile static ArrayList<JSObject> windows = new
    ArrayList<JSObject>();

    public synchronized void init() {
    super.init();
    Thread curr = Thread.currentThread();
    System.out.println(" In Init() " + curr.getName() +
    curr + " hash " + Integer.toHexString(curr.hashCode()));
    appletIndex++;
    try {
    browser = JSObject.getWindow(this); }
    catch (netscape.javascript.JSException e) {
    e.printStackTrace(); }
    catch (Exception e) {
    e.printStackTrace(); }

    synchronized(windows){
    windows.add(browser);

    if (writer == null){
    writer = new OutThread("Fred", windows);
    writer.start();
    }
    }
    /**
    System.out.println("Before sleep call");
    try {
    Thread.sleep(1000);
    }
    catch (InterruptedException e){
    e.printStackTrace();
    }
    System.out.println("After sleep call");
    */
    myNum = 33;
    initFlag = true;
    }

    public synchronized boolean isDone() {
    Thread curr = Thread.currentThread();
    System.out.println(" In isDone() " + curr.getName() +
    curr + " hash " + Integer.toHexString(curr.hashCode()));
    return initFlag;
    }

    public synchronized int getNum(String caller){
    int i = myNum++;
    Thread curr = Thread.currentThread();
    System.out.println("in getNum() " + myNum + " caller " + caller + "
    Thread " +
    curr.getName() +
    curr + " hash " + Integer.toHexString(curr.hashCode()));
    return i;
    }

    public synchronized void destroy ()
    {
    System.out.println("Checked - out");
    super.destroy();
    }
    }

    OutThread.java
    ===========

    import netscape.javascript.JSObject;
    import java.util.ArrayList;

    class OutThread extends Thread {
    ArrayList<JSObject> windows;

    public OutThread(String name, ArrayList<JSObject> windows) {
    super(name);
    System.out.println("Thread constructor");
    this.setDaemon(true);
    this.windows = windows;
    }

    public void run() {
    int sel = -1;
    JSObject browser;
    while (true) {
    synchronized(windows){
    sel++;
    if (sel == windows.size()){
    sel = 0;
    }
    browser = windows.get(sel);
    }
    try {
    sleep((int)(Math.random() * 1000));
    browser.call("tickOver", null);
    } catch (InterruptedException e) {break;}
    }
    System.out.println("DONE!");
    }
    }

    dyntest.html
    ========

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

    <html>

    <head>

    <style>

    body
    {
    background-color: aliceblue;
    color: black;
    font-family: Georgia;
    font-size: 12px;
    margin-left: 5px;
    margin-right: 5px;
    margin-top: 1px;
    padding: 0;
    }

    </style>

    <script type="text/javascript">

    var cntr = 0;
    var chan;

    function load()
    {
    var objectTag = "<object classid=";

    if (/Internet Explorer/.test(navigator.appName)) {
    objectTag = objectTag +
    '"clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ';
    } else {
    objectTag = objectTag +
    '"java:Sleeper.class" type="application/x-java-applet" ' +
    'archive="http://127.0.0.1/Sleeper2.jar" ';
    }

    objectTag = objectTag +
    'width= "0" height= "0" name="TestApp" id="TestApp">' +
    '<param name="archive" value="Sleeper2.jar">' +
    '<param name="codebase" value="http://127.0.0.1/">' +
    '<param name="code" value="Sleeper">' +
    '<param name="java_version" value="1.6+">' +
    '<param name="mayscript" value="true">' +
    '<param name="scriptable" value="true">' +
    '<param name="codebase_lookup" value="false">' +
    '</object>';

    var appletDiv = document.createElement("div");
    appletDiv.innerHTML = objectTag;

    try {
    document.body.appendChild(appletDiv);
    chan = document.getElementById("TestApp");
    }
    catch(err) {
    alert("Tier3 unable to load applet: -\n" +
    (err.description||err.message));
    chan = null;
    };

    if (chan == null) {
    throw new Error("Tier3 was unable to initialize the applet");
    } else {
    try {
    if (!chan.isDone())
    alert("*******RACE******");
    }
    catch(err) {
    chan.setAttribute("id",null);
    chan = null;
    throw new Error("Tier3 unable to load applet: -\n" +
    (err.description||err.message));
    }
    }
    }

    function tickOver(){
    cntr=chan.getNum("TO");
    document.mfForm.username.value="TO:"+cntr;
    setTimeout('fred()',1000);
    }

    function fred(){
    cntr=chan.getNum("AST");
    document.mfForm.username.value="AST:"+cntr;
    }
    </script>

    </head>

    <body id="torso" onload="load()">
    <form name="mfForm">
    Something:
    <input
    name="username";
    class="revLeft";
    style="font-size: 11px";
    type="text";
    size=12;
    /></td>

    </form>
    </body>
    </html>

  4. #4
    AssupMushhica is offline Junior Member
    Join Date
    Mar 2011
    Posts
    3

    Default support with credit card Machine

    First, this probably isnt the right area to post this. Sorry, but im desperate. You users seem to be good with with computer related equipment. We have a credit card processing unit and everything was working good until we went from time warner cable to DSL. Our credit card terminal now will NOT connect through ethernet..only dial up. We have checked our router that it is plugged into and the port is flickering so we know its connected. All of our laptops connect to the internet all day long without problems .Anyone have any ideas!?!? Thanks in advance!

  5. #5
    AssupMushhica is offline Junior Member
    Join Date
    Mar 2011
    Posts
    3

    Default suggestions with credit card processing unit

    First, this probably isnt the right area to post this. Sorry, but im desperate. You users seem to be good with with computer related stuff. We have a credit card terminal and everything was working great until we went from roadrunner cable to DSL. Our credit card unit now will NOT connect through ethernet..only dial up. We have checked our router that it is plugged into and the port is flickering so we know its connected. All of our desktops connect to the internet all day long without problems .Anyone have any suggestions!?!? Thanks in advance!

Similar Threads

  1. Replies: 0
    Last Post: 07-10-2010, 09:00 AM
  2. Chrome plugin for Java applet doesn't work in Ubuntu 9.10
    By jiapei100 in forum Plugins Troubleshooting
    Replies: 1
    Last Post: 04-01-2010, 07:01 AM
  3. A Hottest's Thread
    By hottestbaby in forum Chrome Themes
    Replies: 3
    Last Post: 03-26-2010, 03:56 PM
  4. Thread Delete?
    By Bloody_Turds in forum General Chat
    Replies: 22
    Last Post: 02-28-2010, 03:43 PM
  5. Help with java plugin for Chrome
    By Chrome77 in forum Chrome Troubleshooting
    Replies: 1
    Last Post: 10-11-2009, 04:12 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •