FireFox II setTimeout() Go Back and Applets

R

Richard Maher

Hi,

I hope to come up with a small reproducer shortly but here's the gist of it
in the hope that someone recognizes the foot print and may be able to offer
advice or a work-around: -

1) The page contains an Applet with method send()
2) In the example setTimeout("witeIt()",10000); to fire writeIT() every 10
secs which will in turn call applet.send()
3) User navigates away from Applet-hosting page to a new page
4) When they hit the Go Back /Previous Page button: -
5) The page reloads
6) The old Applets destroy() method is called and should go away please
7) New version of the Applet is in the process of being init()ed
8) The "old" timer from the previous instantiation of the page seems to take
up where it left off
9) The timer fires and writeIt() calls the SEND() from the previous version
of the Applet
10) "synchronized" methods don't help as it looks to be a new instance of
the Applet
11) Historical send() gets called and trashes my latest initialization

This *only* appears to happen on "Go Back" button; "Refresh" is fine. Also,
IE is fine in both cases.

Am I seeing timer and Applet ghosts on FF or just seeing things in general
:)

Cheers Richard Maher
 
R

Richard Maher

Richard Maher said:
Hi,

I hope to come up with a small reproducer shortly but here's the gist of it
in the hope that someone recognizes the foot print and may be able to offer
advice or a work-around: -

1) The page contains an Applet with method send()
2) In the example setTimeout("witeIt()",10000); to fire writeIT() every 10
secs which will in turn call applet.send()
3) User navigates away from Applet-hosting page to a new page
4) When they hit the Go Back /Previous Page button: -
5) The page reloads
6) The old Applets destroy() method is called and should go away please
7) New version of the Applet is in the process of being init()ed
8) The "old" timer from the previous instantiation of the page seems to take
up where it left off
9) The timer fires and writeIt() calls the SEND() from the previous version
of the Applet
10) "synchronized" methods don't help as it looks to be a new instance of
the Applet
11) Historical send() gets called and trashes my latest initialization

This *only* appears to happen on "Go Back" button; "Refresh" is fine. Also,
IE is fine in both cases.

Am I seeing timer and Applet ghosts on FF or just seeing things in general
:)

Cheers Richard Maher

Ok, below its a tiny example.

You need to have the java console on and then you notice that (after you
load the page navigate away and then use the Back button with FF2) that the
instance variables behave like static class variables, and if it isn't a new
instance of the Applet then why are the synchronized methods not
synchronizing? Do I really have to put additional synchronization blocks in
to handle these phantoms?

Does anyone use FF2 anymore? Anyway to say "Nah I really mean destroy() or
reload()!"?

PS. Do a "refresh" to compare and contrast.

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

import java.applet.Applet;
import java.lang.InterruptedException;

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

public synchronized void init() {
super.init();

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

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

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

sleeper.html
=============

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

<html>

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

<head>


<style>

body
{
margin: 0px;
background-color: white;
color: Black;
font-family: times;
font-size: 16px;
border: medium ridge;
}

</style>

<script type="text/javascript">

var timerCnt = 0;
var chan;

function load() {
var lclNum;
document.display.next.value = timerCnt;
try {
chan = document.getElementById("Sleeper");
lclNum = chan.getNum();
setTimeout("writeIt()",0);
}
catch (err) {
alert("In catch " + err.description);
}
if (chan == null) alert("chan is null");
}

function writeIt(){
timerCnt++;
document.display.next.value = timerCnt;
chan.getNum();
setTimeout("writeIt()",1000);
}

</script>

</head>

<body onload="load();">

<br /><h2>Test it</h2><hr /><br />

<form name="display" style="margin-left: 100px;">

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

<script type="text/javascript">

var myDef;
if (navigator.appName == "Microsoft Internet Explorer")
myDef =
'<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ' +
'width= "0" height= "0" id="Sleeper">'
+
'<param name="code" value="Sleeper">'
+
'<param name="mayscript" value="true">' +
'<param name="scriptable" value="true">' +
'</object>'
else
myDef =
'<object classid="java:Sleeper.class" '
+
'type="application/x-java-applet" ' +
'width= "0" height= "0" id="Sleeper">'
+
'<param name="code" value="Sleeper">'
+
'<param name="mayscript" value="true">' +
'<param name="scriptable" value="true">' +
'</object>'

document.write(myDef);
</script>

</body>

</html>
 
R

Roedy Green

6) The old Applets destroy() method is called and should go away please
7) New version of the Applet is in the process of being init()ed

That is a bit of wishful thinking. The only way to replace or get rid
of an obsolete version of a class is to restart the JVM or start
another classloader. Browsers won't do either for you. You must stop
them and restart them to see new Applet code.

I have written browser companies asking for a keystroke to force a
fresh JVM to help in debugging. It would also flush the image and page
caches. They have always refused.

One trick you can use is to change the name of the Applet main class
for each go round of debugging.

The way I handle the problem is to write a hybrid, an Applet that can
also be run standalone. Only after it is fully debugged standalone to
I run it as an Applet for a last check. That way I avoid debugging in
the browser. As a standalone, I can use my IDE/debugger in the usual
way.

Another trick in to use IntelliJ Idea which lets you run your Applets
as Applets but in monitored environment, not a true browser.

See http://mindprod.com/jgloss/applet.html#HYBRID

http://mindprod.com/jgloss/intellij.html

--
Roedy Green Canadian Mind Products
http://mindprod.com

"It wasn’t the Exxon Valdez captain’s driving that caused the Alaskan oil spill. It was yours."
~ Greenpeace advertisement New York Times 1990-02-25
 
R

Richard Maher

Hi Roedy,

Roedy Green said:
That is a bit of wishful thinking. The only way to replace or get rid
of an obsolete version of a class is to restart the JVM or start
another classloader. Browsers won't do either for you. You must stop
them and restart them to see new Applet code.

Sorry, I should've said new instance rather than new version. No code
changes took place.

Please see the very small example I gave in the follow-up post. The
behaviour is reproduceable at will and is some of the more bizarre that I've
seen :-(Cheers Richard Maher
 
R

Richard Maher

Richard Maher said:
Ok, below its a tiny example.

You need to have the java console on and then you notice that (after you
load the page navigate away and then use the Back button with FF2) that the
instance variables behave like static class variables, and if it isn't a new
instance of the Applet then why are the synchronized methods not
synchronizing? Do I really have to put additional synchronization blocks in
to handle these phantoms?

Does anyone use FF2 anymore? Anyway to say "Nah I really mean destroy() or
reload()!"?

PS. Do a "refresh" to compare and contrast.

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

import java.applet.Applet;
import java.lang.InterruptedException;

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

public synchronized void init() {
super.init();

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

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

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

sleeper.html
=============

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

<html>

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

<head>


<style>

body
{
margin: 0px;
background-color: white;
color: Black;
font-family: times;
font-size: 16px;
border: medium ridge;
}

</style>

<script type="text/javascript">

var timerCnt = 0;
var chan;

function load() {
var lclNum;
document.display.next.value = timerCnt;
try {
chan = document.getElementById("Sleeper");
lclNum = chan.getNum();
setTimeout("writeIt()",0);
}
catch (err) {
alert("In catch " + err.description);
}
if (chan == null) alert("chan is null");
}

function writeIt(){
timerCnt++;
document.display.next.value = timerCnt;
chan.getNum();
setTimeout("writeIt()",1000);
}

</script>

</head>

<body onload="load();">

<br /><h2>Test it</h2><hr /><br />

<form name="display" style="margin-left: 100px;">

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

<script type="text/javascript">

var myDef;
if (navigator.appName == "Microsoft Internet Explorer")
myDef =
'<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ' +
'width= "0" height= "0" id="Sleeper">'
+
'<param name="code" value="Sleeper">'
+
'<param name="mayscript" value="true">' +
'<param name="scriptable" value="true">' +
'</object>'
else
myDef =
'<object classid="java:Sleeper.class" '
+
'type="application/x-java-applet" ' +
'width= "0" height= "0" id="Sleeper">'
+
'<param name="code" value="Sleeper">'
+
'<param name="mayscript" value="true">' +
'<param name="scriptable" value="true">' +
'</object>'

document.write(myDef);
</script>

</body>

</html>

Look, sorry for replying to my own post but given it's a pretty unusual
problem description I hope I can be forgiven for casting the line one more
time.

- Stale/ghost timers from renderings of old, re-activating
- Synchronized methods not synchronizing
- Instance variables staticising
- True love

This post has got it all!

1) Can anyone reproduce the behaviour with FireFox 2?
2) Anyone ever seen anything similar outside of FF2?
3) Any "I know how to fix that"s?
3) Any empathetic "Shit, that is weird"s?

Cheers Richard Maher
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top