Question

What's the difference between these two method groups in terms of the set of classes they work with (i.e. ApplicationDomain's class definition set vs the set of class definitions getDefinitionByName uses)?

  1. ApplicationDomain. getDefinition / hasDefinition / getQualifiedDefinitionNames (Flash Player 11.3+ only, undocumented)
  2. getDefinitionByName

It's clear that there's an application domain hierarchy and that definitions may be visible in some app domains and not others. For example, would ApplicationDomain.getDefinition return a definition that is not defined in the given app domain but is accessible from it? (e.g. if the domain is a child domain and we're looking up a definition defined in the parent?) The documentation for ApplicationDomain just says "Loaded classes are defined only when their parent doesn't already define them." but it also says "(ApplicationDomains) allow multiple definitions of the same class to exist and allow children to reuse parent definitions."

The documentation also indicates that getDefinitionByName returns class definitions, whereas ApplicationDomain.getDefinition will return namespace and function definitions in addition to class definitions.

Assuming I'm only interested in class definitions, what ApplicationDomains does getDefinitionByName search? (e.g. all domains, the current/caller domain only, or any domains accessible to the caller?)

This initial test is confusing:

import flash.system.ApplicationDomain;
var d:ApplicationDomain = new ApplicationDomain( ApplicationDomain.currentDomain ); //child of current domain
trace(ApplicationDomain.currentDomain.hasDefinition("flash.display.DisplayObject")); //true
trace(ApplicationDomain.currentDomain.getQualifiedDefinitionNames().length); //1 (the main timeline class definition only: Untitled_fla::MainTimeline) 
trace(d.hasDefinition("flash.display.DisplayObject")); //false

In the above test, on the one hand, getQualifiedDefinitionNames reports that only the main timeline class is defined in the current app domain, yet getDefinition returns true for DisplayObject, indicating it reports the existence of definitions in the parent (system) domain, yet the final trace on the grandchild domain contradicts that by returning false.

ApplicationDomain.currentDomain.parentDomain also returns null, which directly contradicts the following documentation statements: "The system domain contains all application domains, including the current domain..." and "Every application domain, except the system domain, has an associated parent domain. The parent domain of your main application's application domain is the system domain."

The contradiction is very apparent here, where currentDomain has the definition, but when you create a child domain and access the parent, which should be currentDomain, it suddenly reports that it doesn't contain the definition:

trace(ApplicationDomain.currentDomain.hasDefinition("flash.display.DisplayObject")); //true
trace((new ApplicationDomain( ApplicationDomain.currentDomain )).parentDomain.hasDefinition("flash.display.DisplayObject")); //false! why?
Was it helpful?

Solution

This page is quite comprehensive: http://www.senocular.com/flash/tutorials/contentdomains/?page=2 I've managed to solve a couple mysteries, but the basic question outlined above (particularly concerning the scope of getDefinitionByName) still stands. I just wanted to post an answer for what I was able to resolve.

Retreiving the parentDomain returns null if the parent is the system domain. So although the parentDomain is the system domain, the parentDomain property returns null anyway. That's just the way it is. Unfortunately, that makes the system domain inaccessible, for example, for class enumeration through getQualifiedDefinitionNames.

Concerning my initial test, it seems that constructing a new ApplicationDomain creates a dead object until a SWF is actually loaded under that domain. For example, creating a child domain of the current domain and calling hasDefinition on it will return false, but if you assign that very same instance to a loader context an pass it to Loader.load, once the load completes, you can call hasDefinition on the instance that originally returned false, and it will return true instead. So you can construct an ApplicationDomain with a parent, but it won't really function until it's being actively used.

var d:ApplicationDomain = new ApplicationDomain( ApplicationDomain.currentDomain ); //child of current domain
trace(d.hasDefinition( "flash.display.DisplayObject" )); //false for now...
var l:Loader = new Loader();
l.load(new URLRequest( "any.swf"), new LoaderContext( false, d ) );
l.contentLoaderInfo.addEventListener( Event.COMPLETE, completed, false, 0, true );
function completed(e:Event ):void
{
    trace(d.hasDefinition( "flash.display.DisplayObject" ); //...and now it's true.
}

So it would seem that ApplicationDomain.getDefinition does report classes in the parent, grandparent, etc. domains, but it will only do so after the new ApplicationDomain instance has been activated through loading something into it.

Also, ApplicationDomain instances may refer to the same application domain, but they cannot be directly compared. For example, (ApplicationDomain.currentDomain == ApplicationDomain.currentDomain) is false.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top