« Flex 2 Runtime Error 1065 | Main | Lame »

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.

Tags: actionscript as3 flex programming

Comments

Hey there, i am working on something that uses runtime modules. And ran into the same problem today. There were (so far) two problems, the first problem popped up when i used a textarea, apparently it used some locale file that wasnt used in my main application. The solution to this was to add the following to my flex-config.xml:
<include-libraries>
<library>${flexlib}/locale/en_US/framework_rb.swc</library>
</include-libraries>
The second problem came with using a Datagrid. Apparently the component compiler does not add style declarations for unused components. I could add a reference to the Datagrid class in my main application but what also works is adding the defaults.css in a style tag:
<mx:Style source="styles/defaults.css" />
This is a copy from frameworks.swc. The problem is that im stuck with type selector warnings. I noticed you had the same problem (in one of your later posts). If you find a solid solution for this, let me know, i will do the same. Greetz Erik
Create a factory method in your RSL library for your custom class. For example : Custom component (which has a Panel inside) is : MyPanel Factory (also in the RSL library) : MyPanelFactory In the factory method is createMyPanel(some params here) just return the correct class with a : return new MyPanel(); When you use getDefinitionByName("myPackage.MyPanel") you'll get a RTE without a private static reference to Panel in the application which use the library. Then in application (which use the SWC library as an RSL) : var myPanel:UIComponent = MyPanelFactory.createMyPanel(some params here);