In many large projects Flex applications are broken into sub-components to help manage size, loading, content updates, etc. The are multiple ways of breaking a project into sub-components such as using Flex modules, building sub-Flex applications that are loaded by the parent application, creating external ActionScript 3 only projects or they may be developed using Flash Professional. The reason for this architectural decision is based on the nature of the project at hand and the experience of the team building the application.
In large projects, breaking the application into testable parts might be wise. It also can allow for distributed teams participating in the development process to work together. Also, if a project is animation and graphical rich, Flash Professional is likely the creation tool for those parts of the application. To integrate these sub-components into the Flex application, they are most likely loaded via SWFLoaders. Once loaded into the application domain, the assets can be controlled by the main application. This is where problems can begin.
Since these sub-application and assets were tested outside of the main application conflict issues do not arise until all of the final pieces are integrated together. One such problem is the dreaded runtime error “Property [property name] not found on [Class] and there is no default value.”
Recently I was asked to debug a client application (we did not initially develop this app), that was throwing this error intermittently. I struggled for about two hours before I found a pattern in the application and sub-application code base. The pattern was a common package naming structure. Each sub-application had the same package structure and some of its classes were named the same. However, the same named classes had a different set of public methods (API). Now, these same named classes were internal to the sub-application (not declared on the parent app) but this error was still being thrown intermittently at runtime.
Here is an example of the two matching packages with different APIs:
The problem was, when a sub-application was loaded into the application, the previous sup-application was not fully unloaded and it’s BaseComponet class was being retrieved from memory instead of the new BaseComponent that was just loaded. At this point the new app is expecting a certain API yet it’s not there, causing the error I outlined above. This only happens in certain cases (I can’t explicitly define the load order, it just happened when rapidly clicking around loading and unloading applications). But, if the main application also has a BaseComponent declared under the same package structure, this problem will be visible every time. The sub-application’s version is ignored and the error above will happen the first time the sub-application is loaded because the parent instance will always be used.
The solution is simple. Make sure each project has a unique package structure or define a standard Interface that is used across the entire application and sub-applications. To solve this problem in an existing application is just add the project name after “developmentarc” making the structure unique per application.
The hard part about the solution is communication. On large teams, this is a topic that needs to be tackled during the planning or architecture phase of a project, not post-development. Try coming up with a standard package pattern that all members can follow. This can be included with Coding Standards or with other development team guidelines as a project kicks off. The longer a team waits to tackle collaboration issues like this, the harder it is to change. Refactoring a 100+ projects can be very time consuming and at the end of a project, developers have more important issues to resolve other than a large scale refactor.