views:

32

answers:

1

Hi all, I'm having something of an issue with trying to load externally defined classes in actionscript 3.0. I believe this to be an issue with my understanding of the ApplicationDomain / LoaderContext classes, but even after going over the documentation and a couple of web searches I'm still stuck.

Essentially what I want to do is load a swf that contains a symbol that is an implementation of an interface shared between the calling swf and the loaded swf. I can load the swf fine and instantiate and execute methods on it fine, but only so long as I don't attempt to cast it to the shared interface type. If I do attempt to cast it, I get a TypeError: Error #1034: Type Coercion failed: type error.

I suspected this is because when I load the new class flash is recognizing it as a completely different class, hence the exception. The documentation suggests the use of a LoaderContext argument, with applicationDomain set to ApplicationDomain.currentDomain.

The problem is this has no effect. Regardless of whether I set the ApplicationDomain to currentDomain, null, or a child of the current domain, I still get an type coercion failed error. The :: part of the error seems to indicate that the class I loaded is in a different namespace or some such, when I want it to be in the same namespace as my loader.

Code:

import flash.display.Loader;
import flash.display.MovieClip;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;

public class TestSkin extends MovieClip
{
    var mLoader:Loader;

    public function TestSkin()
    {
        super();
        startLoad("ExternalTest.swf");
    }

    private function startLoad(url:String):void
    {
        mLoader = new Loader();
        var mRequest:URLRequest = new URLRequest(url);
        var appDomain:ApplicationDomain = ApplicationDomain.currentDomain;
                    //Loading into different domains seems to have no effect
        //var appDomain:ApplicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
        //var appDomain:ApplicationDomain = null;
        mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
        mLoader.load(mRequest, new LoaderContext(false, appDomain));
    }

    private function onCompleteHandler(loadEvent:Event):void
    {
        //Get the object from the loadEvent
        var obj:Object = loadEvent.target.content;
        //Verify that the methods exist on the object
        trace("Loaded item id: " + obj.getInterfaceId());
                    //This returns Loaded item id: ExternalTestInterfaceImplementation!
        //Try assigning as an instance of the shared type - fails with type coercion error
                    //Throws the following type error:
                    //TypeError: Error #1034: Type Coercion failed: cannot convert myPackage::ExternalTestInterfaceImplementation@257b56a1 to myPackage.TestInterface.
        var castItem:TestInterface = TestInterface(obj);
        trace("castItem: " + castItem);
    }
}

Interface declaration:

public interface TestInterface 
{
    function getInterfaceId():String;
}

Interface implementation

public class ExternalTestInterfaceImplementation extends MovieClip implements TestInterface 
{
    public function getInterfaceId() : String
    {
        return "ExternalTestInterfaceImplementation!";
    }

    public override function toString():String
    {
        return getInterfaceId();    
    }
}
A: 

It seems like this is caused by a bug in the player. I've encountered this same problem a while ago. It's described here:

https://bugs.adobe.com/jira/browse/ASC-3529

There's a workaround, which basically consists in loading the swf with an URLLoader (as binary) and then using Loader::loadBytes (instead of just using a regular Loader).

Here's an explantion of this workaround and a loader class that fixes this problem:

http://blog.aleksandarandreev.com/?p=42

Juan Pablo Califano
Thanks that looks like a good place to start.
That definitely fixed the problem, thanks.It seems kind of odd that it's been a year since the bug was reported and it still hasn't been fixed. I wonder if it's some oddness that hasn't been communicated about Security contexts or something, or a genuine bug.