Flex 2 Runtime Error 1009 and Runtime Modules
While the following error is most often encountered when trying to access a property or function through a null object reference, it can also rear its head when working with runtime modules.
TypeError: Error #1009: Cannot access a property or method of a null object reference. at mx.containers::Panel/mx.containers:Panel::layoutChrome() at mx.core::Container/mx.core:Container::updateDisplayList()[C:\dev\GMC\sdk\frameworks\mx\core\Container.as:2910] at mx.containers::Panel/mx.containers:Panel::updateDisplayList() at mx.core::UIComponent/validateDisplayList()[C:\dev\GMC\sdk\frameworks\mx\core\UIComponent.as:5672] at mx.core::Container/validateDisplayList()[C:\dev\GMC\sdk\frameworks\mx\core\Container.as:2731] at mx.managers::LayoutManager/mx.managers:LayoutManager::validateDisplayList()[C:\dev\GMC\sdk\frameworks\mx\managers\LayoutManager.as:594] at mx.managers::LayoutManager/mx.managers:LayoutManager::doPhasedInstantiation()[C:\dev\GMC\sdk\frameworks\mx\managers\LayoutManager.as:646] at Function/http://adobe.com/AS3/2006/builtin::apply() at mx.core::UIComponent/mx.core:UIComponent::callLaterDispatcher2()[C:\dev\GMC\sdk\frameworks\mx\core\UIComponent.as:7789] at mx.core::UIComponent/mx.core:UIComponent::callLaterDispatcher()[C:\dev\GMC\sdk\frameworks\mx\core\UIComponent.as:7732]
The problem seems to be that if the runtime module makes a side-effect reference to a component, which is not included in the main application, it never really gets included in the SWF and as such causes problems when accessed. That's a jumble of words so I think an example is needed.
Create a Flex Application with two files in it. The first one is called com.example.PanelComp.mxml:
<?xml version="1.0" encoding="utf-8"?> <mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="400" height="300"> <mx:Text text="Hi"/> </mx:Panel>
The second one is the main application, call it LoadTest.as:
package { import com.example.PanelComp; import mx.core.SimpleApplication; public class LoadTest extends SimpleApplication { private static var panelComp:PanelComp; } }
For more information on that SimpleApplication business check out Roger Gonzalez's blog.
Now in a different Flex Application we want to load the first application and then create an instance of PanelComp.
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"> <mx:Script> <![CDATA[ import mx.containers.Panel; import flash.utils.getDefinitionByName; // must uncomment for "Add Panel" to work // TypeError: Error #1009: // private static const panel:Panel = null; private var _loader:Loader; private function loadSwf(location:String):void { _loader = new Loader(); var ctx:LoaderContext = new LoaderContext(); ctx.applicationDomain = ApplicationDomain.currentDomain; _loader.contentLoaderInfo.addEventListener(Event.INIT, swfInit); _loader.load(new URLRequest(location), ctx); } private function swfInit(e:Event):void { _loader.content.addEventListener("ready", swfLoaded); } private function swfLoaded(e:Event):void { trace("Loaded"); } private function createPanel():void { var clazz:Class = Class(getDefinitionByName("com.example.PanelComp")); // see note above about TypeError: Error #1009: addChild(new clazz()); } ]]> </mx:Script> <mx:Button label="Load" click="loadSwf('../../LoadTest/bin/LoadTest.swf');"/> <mx:Button label="Add Panel" click="createPanel();"/> </mx:Application>
As noted in the comments, until you uncomment the static reference to Panel in the wrapper application, you will get the stack trace. Something to keep in mind if you are using runtime modules.