Operating System - OpenVMS
1828316 Members
3660 Online
109976 Solutions
New Discussion

JavaScript not being blocked/synched by Applet init()

 
Richard J Maher
Trusted Contributor

JavaScript not being blocked/synched by Applet init()

Hi,

Not sure how the following behaviour would pan-out on the VMS-available browsers, but I'd like to know if someone could please tell me.

I've come up with a small reproducer (see below) that I hope will help
someone sched light on what's going on. (Also a related SDN Bug ID 6742814
may be of some help: -
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6742814 )

In a nutshell with IE6 the Javascript resumes as soon as the init() method
has called JSObject.getWindow(this) but *before* the init() method has
completed/returned, as can be evidenced from the getNum() results. (Nice
trick!) Try it on FireFox to see the difference.

Is this a new bug that was introduced when trying to fix a "freeze" with
JSObject.Call()? If not, how is one ever supposed to synchronize the
completion of Applet initialization? "Callbacks" a la mode de Adobe
FABridge?

I'll do some more testing with other browsers/versions but surely this can't
be right? Possibly fixed in a later version of IE, JRE, or LiveConnect?

To turn the Java console on on Windows: -
Tools->Control Panel->Java->Advanced->Show Java console

Java Console output IE6

[Alert box is "3"]

in getNum 1
in getNum 2
in getNum 3
in getNum 4
Before sleep call
After sleep call

Java Console output FF2

[Alert box is "36"]

Before sleep call
After sleep call
in getNum 34
in getNum 35
in getNum 36
in getNum 37

Cheers Richard Maher

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

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

public class Sleeper extends Applet {
private int myNum = 0;
private JSObject browser;

public void init() {
try {
browser = JSObject.getWindow(this); }
catch (netscape.javascript.JSException e) {
e.printStackTrace(); }
catch (Exception e) {
e.printStackTrace(); }

System.out.println("Before sleep call");
try {
Thread.sleep(5000);
}
catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("After sleep call");
myNum = 33;
}

public int getNum(){
int i = myNum++;
System.out.println("in getNum " + myNum);
return i;
}

}

Sleeper.html
============



"http://www.w3.org/TR/html4/loose.dtd">



<meta name="author" content="Richard Maher" />
<meta name="description" content="JS Function and Applet Test" />






<script type="text/javascript">

function load() {
var lclNum;
var chan;
try {
chan = document.getElementById("Sleeper");
lclNum = chan.getNum();
lclNum = chan.getNum();
lclNum = chan.getNum();
}
catch (err) {
alert("In catch " + err.description);
}
if (chan == null) alert("chan is null");
alert(chan.getNum());
}

</script>






Test it







type="text"
style="text-align: Left;"
name="next"
size=10
/>


<script type="text/javascript">

var myDef;
if (navigator.appName == "Microsoft Internet Explorer")
myDef =
' 'width= "0" height= "0" id="Sleeper">'
+
''
+
'' +
'' +
'
'
else
myDef =
'+
'type="application/x-java-applet" ' +
'width= "0" height= "0" id="Sleeper">'
+
''
+
'' +
'' +
'
'

document.write(myDef);
</script>





"Richard Maher" wrote in message
news:gsmp8k$hfo$1@news-01.bur.connect.com.au...
> Hi,
>
> I'm probably seeing-things again but here goes: -
>
> IE6 with JRE 1.6.0_12 looks to continue the Javascript processing while my
> Applet.init() has yet to return. FireFox is fine and when I went for a
small
> reproducer IE also performed as expected. (Both with Applet appended in a
>
or document.writeN() as an in the body)
>
> See below for a reasonable code snippet, but the critical bit is this: -
>
> var tier3Chan;
> try {
> document.body.appendChild(appletDiv);
> tier3Chan = document.getElementById(appletId);
> alert("Auth = " + tier3Chan.getThree());
> var userAuthorized = tier3Chan.isAuthorized();
> }
> catch(err) {
> alert("Err =" + err.description);
> tier3Chan = null;
> };
>
>
> If I take out that 'alert("Auth =' bit then isAuthorised() gets called and
> returns false even though the user hasn't had a chance to enter their
> Username/Password yet. (Pop-up dialog currently sitting on the screen)
>
> I understand when it would be valid to let the JS run past the
> getElementById so I normally stick a method call (such as isAuthorized())
in
> their to force the block-for-init but this time it doesn't seem to work
:-(
>
> For a similar setup please see: -
> http://manson.vistech.net/t3$examples/demo_client_flex.html
> Username: TIER3_DEMO
> Password: QUEUE
>
> All (slightly dated) Java/Javascript/HTML source code is at: -
> http://manson.vistech.net/t3$examples/
>
> Unfortunately that example works but the one below doesn't :-(
>
> Anyone know the mechanics behind what Javascript is looking for on IE to
> tell it that the Applet has finished init()ing? Or how I might be stomping
> on it? (Or at least failing to flag it?)
>
> Cheers Richard Maher
>
>
> /**
> * Copyright (c) Richard Maher. All rights reserved.
> */
>
> function Tier3Client(application,
> codeBase,
> port,
> maxBuf,
> hostCharSet,
> sslReqd)
> {
> this.application = application;
> this.codeBase = codeBase;
> this.port = port;
> this.maxBuf = maxBuf;
> this.hostCharSet = hostCharSet;
> this.sslReqd = sslReqd;
>
> var appletId = "Tier3__" + application + "_Applet";
>
> try {
> var idTaken = document.getElementById(appletId);
> }
> catch (err) {};
>
> if (idTaken != null) {
> throw new Error("Tier3 Client already registered for " +
> this.application);
> return;
> }
>
> var archiveName = "tier3Client.jar";
> var className = "tier3Client/Tier3Application";
>
> var appletParams = [{"name":"archive", "value":archiveName},
> {"name":"codebase", "value":codeBase },
> {"name":"code", "value":className },
> {"name":"mayscript", "value":"true" },
> {"name":"scriptable", "value":"true" },
> {"name":"APPLICATION", "value":application},
> {"name":"PORT", "value":port },
> {"name":"MAXBUF", "value":maxBuf },
> {"name":"HOSTCHARSET", "value":hostCharSet},
> {"name":"SSLREQD", "value":sslReqd }];
> var startParam = 0;
>
> var objectTag = "> } else {
> objectTag = objectTag +
> '"java:' + className + '.class"
type="application/x-java-applet
> " ' +
> 'archive="' + codeBase + archiveName + '"';
> startParam = 1;
> }
>
> objectTag = objectTag + ' width= "0" height= "0" id="' + appletId +
> '">';
>
> for (i=startParam; i> objectTag = objectTag + '> 'value ="' + appletParams[i].value
+
> '">';
> }
>
> objectTag = objectTag + "
";
>
> var appletDiv = document.createElement("div");
> appletDiv.innerHTML = objectTag;
>
> var tier3Chan;
> try {
> document.body.appendChild(appletDiv);
> tier3Chan = document.getElementById(appletId);
> alert("Auth = " + tier3Chan.getThree());
> var userAuthorized = tier3Chan.isAuthorized();
> }
> catch(err) {
> alert("Err =" + err.description);
> tier3Chan = null;
> };
> alert("After check");
> if (tier3Chan == null) {
> throw new Error("Tier3 was unable to initialize the applet for " +
> this.application);
> return;
> } else {
> if (!userAuthorized) {
> throw new Error("Tier3 User authentication unsuccessful for "
+
> this.application);
> return;
> }
> }
>
> this.chan = tier3Chan;
>
> Tier3Client.applications[this.application] = this;
>
> return this;
> }
>
>
1 REPLY 1
Richard J Maher
Trusted Contributor

Re: JavaScript not being blocked/synched by Applet init()

Upon re-reading that bug report I quoted, I've come to the conclusion that (for whatever compelling reasons) it was a deliberate break of upward-compatibility and the laws of browser-physics as we knew them pre-Java6. (Java 1.4 and I'm guessing 5 behave "as expected" with IE6)

A couple of relevant-sounding quotes from that bug report from Sept last
year: -
{
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.
}

So it appears that through the wonders of Java6 we now have your init()
method and your JavaScript executing in parallel (presumably in seperate
threads), but *only* if you're doing something with JSObject. And for the
squeamish among us that like our initialization to finish before the
mainline methods start crunching numbers, there's now a need for
intervention.

I do glance through the JRE release notes when they come out but can't
recall seeing this one; anyone else?

Anyway, thanks to a guy in cljp, the answer is to "synchronized" all applet methods that need it. (Or at least init() and the one you want to call from JavaSCript to block on.)

Cheers Richard Maher

PS. Happy Mother's Day to all the Mums in this part of the world!