History | Log In     View a printable version of the current page.  
Issue Details (XML)

Key: SDK-14380
Type: Bug Bug
Status: Closed Closed
Resolution: Cannot Reproduce
Priority: None None
Assignee: Peter deHaan (Adobe)
Reporter: Barney Boisvert
Votes: 3
Watchers: 6
Operations

If you were logged in you would be able to see more operations.
Flex SDK

ExternalInterface callbacks cause JS errors in IE when unloading the app

Created: 01/17/08 01:38 AM   Updated: 01/30/09 04:06 PM
Component/s: Flash Integration
Security Level: Public (All JIRA Users )

File Attachments: 1. File parentest.mxml (0.3 kb)
2. Zip Archive SDK-14380-beb.zip (250 kb)
3. Zip Archive SDK-14380.zip (13 kb)

Image Attachments:

1. error-screenshot.png
(12 kb)

2. IE6_version.jpg
(22 kb)

3. js_error_IE6.jpg
(17 kb)

4. screenshot-1.jpg
(70 kb)

5. screenshot-2.jpg
(211 kb)
Issue Links:
Relationship
 
This issue is related to by:
FP-529 ExternalInterface callbacks cause JS ... None Internal Review

Severity: Runtime Error
Reproducibility: Every Time
Discoverability: High
Found in Version: None
Affected OS(s): Windows - All Windows
Steps to Reproduce:
Steps to reproduce:
1. compile the attached MXML application and run it in IE (6 or 7 will do)
2. ensure "notification of every script error" is enabled
3. unload the movie (close the browser or navigate to a new page)
4. witness the error popup about an expected parenthesis
 
 Actual Results:
 An error message about an expected parenthesis
 
 Expected Results:
 a clean unloading of the app
 
 Workaround (if any):
 The issue is with callbacks added via ExternalInterface's addCallback method. You get an error message for each callback registered. The attached example has one callback, so you get one error. If you have three callbacks, you get three errors.
Language Found: English
Bugbase Id: none
QA Owner: Peter deHaan (Adobe)
Resolved by: Peter deHaan (Adobe)
Participants: Alan Chong, Barney Boisvert, Johan Adriaans, Mike Pirnat, Peter deHaan (Adobe) and Thomas Fowler
Browser: Internet Explorer 7.x
JDK: Sun 1.6.x


 All   Comments      Sort Order:
Barney Boisvert - [01/17/08 01:45 AM ]
I should clarify that unloading the movie (step 3) can't be done with Eclipse, you have to either navigate or close with IE itself (close button, exit menu option, etc.)

Peter deHaan (Adobe) - [01/18/08 03:19 PM ]
Added screenshot-1, IE7 Internet Options dialog

Peter deHaan (Adobe) - [01/18/08 03:29 PM ]
Barney,

I'm unable to reproduce this issue in IE6 or IE7 on Windows XP (Flash Player 9,0,115,0 Debug ActiveX).
Do you see this issue from file:// or http://?

Also, do you see the issue if you use my project files ("SDK-14380.zip")?

Peter

Barney Boisvert - [01/18/08 04:01 PM ]
Peter,

If I load that project into Eclipse and launch it into IE6 and then close IE6, I get the error popup. I'm using an http:// URL. With a filesystem access I get a security sandbox warning.

FlexBuilder 3.0 Milestone 3 Beta 2 (build 3.0.183654)
IE 6.0.2900.2180.xpsp_sp2_gdr.070227-2254

I'm going to attach the zip of my Eclipse project that I created based on your zip. I didn't change the code, only the URL I'm connecting to the bin folder at.

Barney Boisvert - [01/18/08 04:02 PM ]
My rezip of Peter's project that does exhibit the behaviour.

Barney Boisvert - [01/18/08 04:05 PM ]
A screenshot of the JS error.

Peter deHaan (Adobe) - [01/18/08 04:24 PM ]
Barney,

I'm still unable to reproduce the issue on IE7 w/ XP SP2 using your code on my local webserver (JRun).
I verified that my JavaScript errors are working by adding some unterminated strings and other hideous JavaScript.

Do you see these errors on other computers/browsers, or is this IE specific?
I'll install a virtual Windows XP in VMWare and check on IE6 though.

Barney Boisvert - [01/18/08 04:30 PM ]
Peter,

It's IE specific, and I've just confirmed both IE6 and IE7 exhibit the issue. Using FlexBuilder vs flexant to compile makes no difference (SWFs from both show the problem). Firefox (and it's siblings) are fine.

Did you recompile my project zip, or did you just unzip it and load main.html?

Peter deHaan (Adobe) - [01/18/08 04:36 PM ]
Barney,

I just unzipped your files, put them on my local JRun webserver, confirmed that javascript errors were working by adding errors, removed the errors, and then tested the files. Closing the browser via the big "X" button, or File > Exit didn't throw the JavaScript error on my machine.

I only have one PC, but I can see if I can find another machine to test on (or, I may have to wait until I get home tonight and test from home). I've seen very odd bugs like this before where only one machine can reproduce the issue, but a similarly configured system doesn't show the error.

Peter

Barney Boisvert - [01/18/08 05:30 PM ]
I've just confirmed it's actually a Flash Player issue. I've got 9,0,60,235 on IE6 and IE7 and the error happens. 9,0,47,0 on IE6 and 9,0,115,0 on IE7 (can't speak for other combinations) don't exhibit the behaviour.

My apologies for the troubles.

Thomas Fowler - [06/02/08 01:38 PM ]
I am experiencing the same issue in IE 6 but *not* IE 7 with Flash Player 9,0,115,0.

I am running Windows XP SP2 with IE 6.0.2900.2180.xpsp_sp2_gd4.070227-2254. Here's the offending code:

function __flash__arrayToXML(obj) {
var s = "<array>";
for (var i=0; i<obj.length; i++) {
s += "<property id=\"" + i + "\">" + __flash__toXML(obj[i]) + "</property>";
}
return s+"</array>";
}
function __flash__argumentsToXML(obj,index) {
var s = "<arguments>";
for (var i=index; i<obj.length; i++) {
s += __flash__toXML(obj[i]);
}
return s+"</arguments>";
}
function __flash__objectToXML(obj) {
var s = "<object>";
for (var prop in obj) {
s += "<property id=\"" + prop + "\">" + __flash__toXML(obj[prop]) + "</property>";
}
return s+"</object>";
}
function __flash__escapeXML(s) {
return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
}
function __flash__toXML(value) {
   var type = typeof(value);
if (type == "string") {
return "<string>" + __flash__escapeXML(value) + "</string>";
} else if (type == "undefined") {
        return "<undefined/>";
} else if (type == "number") {
        return "<number>" + value + "</number>";
} else if (value == null) {
        return "<null/>";
} else if (type == "boolean") {
        return value ? "<true/>" : "<false/>";
} else if (value instanceof Date) {
        return "<date>" + value.getTime() + "</date>";
   } else if (value instanceof Array) {
       return __flash__arrayToXML(value);
   } else if (type == "object") {
       return __flash__objectToXML(value);
   } else {
return "<null/>"; //???
}
}
function __flash__addCallback(instance, name) {
  instance[name] = function () {
    return eval(instance.CallFunction("<invoke name=\""+name+"\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments,0) + "</invoke>"));
  }
}
function __flash__removeCallback(instance, name) {
  instance[name] = null;
}

The problem occurs when 'instance[name]' is being set to 'null' on line 53 (if you were to copy and paste this code into a file.)

Thomas Fowler - [06/02/08 01:50 PM ]
One other thing I forgot to mention is that the error seems to occur for every ExternalInterface callback method being made available to the HTML/JS code through Flex.

Peter deHaan (Adobe) - [07/15/08 12:52 PM ]
Added screenshot 2. I was unable to repro the issue with IE6 on Win XP with Player 9,0,115,0 running from my web server (http://)

Peter deHaan (Adobe) - [07/15/08 12:57 PM ]
Thomas, I'm unable to reproduce the issue with [seemingly] the same environment as you (IE6/XP/FP 9,0,115,0, with the attached source files).

Were you using the attached files, or some other code?

Would it be possible for you to attach a reproducible test case (MXML, generated HTML and SWF) and I can try on a few different computers here and see if I can reproduce the issue with your files)?

Peter

Thomas Fowler - [07/15/08 01:27 PM ]
Sure thing Peter. I'll try to get one to you today or tomorrow and thanks for responding.

Thomas

Thomas Fowler - [07/15/08 02:08 PM ]
By the way Peter, what version of the Flex SDK are you using to compile?

Peter deHaan (Adobe) - [07/25/08 07:04 PM ]
Thomas,

Sorry, I completely missed this comment. I was compiling using the Flex 3.0.0.477 SDK.

Peter

Thomas Fowler - [07/25/08 07:25 PM ]
No worries Peter, thank you for the info!

I think I have uncovered the problem however and it has to do with MooTools 1.11. I'd like to pose the question to the people watching this bug, are any of you using MooTools or other JS library in your application? If so, the issue could be related to the way MooTools (or similar library) cleans up its objects on the 'onunloadbefore' event.

What I *think* is happening with the version of MooTools I'm using (v. 1.11) is an event handler is registered with the 'onunloadbefore' event and is performing object cleanup and in turn, removing the object/embed instance containing the Flex .swf. Because the Flex application instance is removed, when the 'onunload' event is fired which executes the '__flash__removeCallback' method attached to the instance by the Flash Player (not entirely sure the preceding description is accurate, but I think it's close) an error is thrown because a reference to 'instance' argument passed to the '__flash__removeCallback' method is null. Therefore, when this line is executed:

instance[name] = null;

IE6 throws an 'Object expected' error.

I think an easy fix for this could be to simply put in a check to see if 'instance' is null and if so, return execution back to the global scope. Any thoughts or comments on this? Again, I am very curious to see if the comment contributors to this bug are using MooTools or a similar JavaScript library. Looking forward to getting to the bottom of this!

Cheers,

Thomas

Mike Pirnat - [08/07/08 05:48 PM ]
Thomas,

I encounter this same behavior with the Dojo toolkit. Their Flash Storage.swf (used as an IE alternative for client-side storage) registers 13 ExternalInterface callbacks, and I get a runtime error for each of them in IE (6 and 7) when I exit the browser. Normal page unloading (navigating to different pages) does not seem to throw any errors.

This is on Windows XP (SP2) running Flash Player 9,0,124,0.

FWIW, the Dojo Storage.swf is built using mtasc.

I like your easy fix suggestion. Not being an Actionscript/Flash guru (I'm mainly a Python & Javascript guy), is there an unload hook I can tie into to clean up the callbacks while I've still got an instance of the swf, before Flash tries to do it itself and fails?

Thanks and good luck,

Mike Pirnat

Mike Pirnat - [08/07/08 06:16 PM ]
FWIW, since this seems like a Flash Player bug, I filed https://bugs.adobe.com/jira/browse/FP-529 to see if that gets the issue some appropriate visibility.

Thomas Fowler - [08/07/08 06:46 PM ]
Hi Mike- Thanks for logging the bug in the Flash Player JIRA, I really appreciate it. To answer your question about the hooks, unfortunately there isn't a way to dump those callbacks through ActionScript. I do believe however ther is a way to remove these through JavaScript. I am going to begin working on some JS code to prevent this issue very soon.

Here's my plan of attack so far:

1. Add an event handler for the unbeforeunload event.

2. Get a reference to the swf and iterate through all the properties checking for function types.

3. If a function is found use regex to see if the function name matches the Ext. Interface naming convention. If a match is found blow it away and move to the next property. This part could be a little dicey if for some reason the Ext. Interface function naming convention were to change with a player update. We'll cross that bridge though when we come to it.

4. Once all suspected Ext. Interface callback methods are removed return and continue execution.


Like I said, I'm hoping to start on this soon, but if you see any gotchas in my approach please let me know.

Thanks,

Thomas

Mike Pirnat - [08/12/08 03:20 PM ]
Thomas,

Sounds like it has potential... I'm not enough of a Flash/Actionscript guru to know if there's anything blatantly problematic about it.

If you manage to get something that works, would you be willing to share your solution with the rest of us?


Thanks -- Mike

Thomas Fowler - [08/12/08 03:26 PM ]
Absolutely. This has been a burden to me and I'm sure quite a few other developers so how could I not? I will definitely share my solution so stay tuned.

Thanks,

Thomas

Alan Chong - [10/09/08 06:52 PM ]
I had a similar problem (ExternalInterfaces), but my java and AS were setup correctly and it was not consistent from machine to machine. I was able to confirm that for me, the systems that were getting this error was using the Adobe Flash ActiveX Plugin version 9, or 9.0.47. The working systems all had the latest (9.0.124.0). Updating those systems to the latest flash plugin resulted in errors that went away.

Maybe it has nothing to do with the version, and more to do with the install (I uninstalled, the reinstalled). Adobe can answer what changed in the flash plugins...

Johan Adriaans - [10/28/08 07:40 AM ]
I had the same error using:
- Windows XP SP3
- Flash player: WIN 9,0,124,0, IE6
- IE 6.0.2900.5512
- Flex compiler 3.0.0
- MooTools 1.11
- swfObject 1.5

I solved the problem by wrapping a try block around the __flash__removeCallback function.
So after calling the swfobject.embedSWF() function, i exec the following function:

function fixRaceCondition () {
  var backup = window.__flash__removeCallback;
  window.__flash__removeCallback = function (instance, name) { try {backup(instance, name)} catch (x){} };
}

Keep in mind that this prevents the error, it doesn't really solve it. A function rewrite might feel like the better option, but i think that might cause problems in future players / compilers.

Johan Adriaans - [10/28/08 09:23 AM ]
Hmm, i'm still having some issues. The best solution seems to be: calling the fixRaceCondition function onbeforeunload. (IE6+7 support this event,)
So for mootools you can use: window.addEvent("beforeunload", fixRaceCondition );

Thomas Fowler - [10/28/08 10:26 AM ]
Hi John, et al.-

I posted a comment a while back about coming up with a fix for this nuisance, but I decided to try Dojo 1.2 when it was released recently. Since porting my code to Dojo 1.2 from MooTools 1.1x the problem has gone away. I did some reading on the MooTools forums about this problem and there is what I guess some at Adobe would call a flaw in the MooTools code base. It's basically what I described in my comment back in July about this (http://bugs.adobe.com/jira/browse/SDK-14380#action_189817). The reason why this problem doesn't exist using Dojo 1.2 (I think) is because it's waiting until other onunloadbefore/onunload handlers finish before it does any cleanup and/or housekeeping of its own. Thus, eliminating the errors when the Flash Player attempts to remove the EI callbacks when the page is unloaded.

Once again, however, my solution will more than likely not be ideal for most since it involved porting my code from MooTools to Dojo 1.2 (although, if you have the time I highly recommend it.) The *real* solution IMHO is to put the appropriate checks in the ' __flash__removeCallback' method like so:

function __flash__removeCallback(instance, name)
{
     if ( instance )
     {
          instance[name] = null;
     }
}

After writing this, I'm realizing how trivial of a fix this would be. Hopefully, the powers that be will come to their senses and realize more due diligence is required for these External Interface methods. With that said, I will stick to my promise from before and write a small script to search for the offending Ext. Interface methods attached to the Flash .swf and remove them. Once again, stay tuned and let me know if you have a question or comment.

Thanks,

Thomas

Peter deHaan (Adobe) - [10/28/08 01:00 PM ]
Thanks for the feedback everybody, can you please vote on the associated Flash Player bug: https://bugs.adobe.com/jira/browse/FP-529

Peter deHaan (Adobe) - [01/30/09 04:06 PM ]
Closing this issue.
Please continue this conversation in the related Flash Player bug, FP-529