As applications grow in size and complexity, it becomes necessary to break them up into manageable pieces. To some degree this can be handled at development time by maintaining a carefully-structured source code base.
Compiling the application into a single, monolithic deliverable may itself become a roadblock. For example, it may be desirable instead to compile and validate these pieces separately, and then assemble the resulting binaries. The pieces may be developed and shipped on different schedules, and thus different portions of the application updated independently. Or, the pieces may even be developed by other parties, as is often the case for applications supporting plugins. Regardless, it often becomes necessary to defer loading some of these pieces until runtime.
AIR currently supports two basic approaches for this kind of runtime assembly: Loading code into a network sandbox, and loading code into the application sandbox. The two approaches have different capabilities and different limitations. When designing large applications, it’s good to be aware of these trade-offs.
Code is loaded into a network sandbox via the Loader.load() API by specifying the URL of the target code. Code in this sandbox is restricted from accessing AIR-specific APIs, but has access to the same set of APIs that content running in Flash Player can access. The network sandbox essentially is Flash Player.
Interestingly, by restricting the API to the Flash Player API, the loaded content can necessarily be run in Flash Player or AIR. This may be especially useful if your application runs sometimes in the browser and sometimes in an application.
The API restrictions also mean that you don’t have to trust the code you load. The network sandbox prevent access to potentially dangerous APIs, such as the filesystem API. You can selectively open up access via the sandbox bridge capability.
Because the runtime knows where the code was loaded from, the code can use relative addressing to access other network resources, including additional network-hosted code. This allows for such code to easily be moved between different web servers, including between test and production environments.
The network sandbox is typically not suitable when the code your loading is supposed to function as an integral part of the application, with full access to other parts of the application and to the AIR APIs. For that, you want the application sandbox.
Code is loaded into the application sandbox via the Loader.loadBytes() API. Code in this sandbox runs as if it were installed along with your application, having full access to all of the AIR APIs. This facility provides the basic underpinnings for a complete plugin model. You can use that model to modularize your own application, or even open it up to third-party components.
Code loaded via this method is granted full API access, so it is essential that the application validates that it trusts the code before loading it. This can be accomplished in a secure fashion by using code signing, and validating the signature before loading the code. It may also be sufficient to obtain the code via a secure URL, but it should be noted that this protects the code only while in transit, and not after it is stored locally. To encourage secure use of this API, it loads the code, as the method names suggests, directly from a ByteArray and not from a URL.
Code loaded via this API does not retain its origin (URL), and therefore cannot access other code using relative URLs. Again, this was done to encourage secure use of the API. If this code can implicitly load additional code off the network, it is not sufficient to validate just the first SWF; each link of that chain requires careful validation.
Note that, because the origin of the code is removed, you can’t combine granting access to the application sandbox with the deployment ease of loading a SWF and associated RSLs from the network. If one module depends on another, some other referencing mechanism must be used.
It’s easy to imagine extending these models in a variety of ways. For example, while it is currently possible to create a plugin mechanism for an AIR application, the validation work has to be done by the application. This in turn prevents it from integrating with other runtime features, like RSLs. By expanding runtime support, we could potentially allow these features to work together.
We are actively exploring how AIR applications are using these techniques today, and how we might enhance our support for building large applications in the future. If you have feedback in this area, please let us know via a comment or via ideas.adobe.com/air.
For more in this area, you might want to read: