Approaches to Modular AIR Applications

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.

Network Sandbox

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.

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.

Futures

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.

References

For more in this area, you might want to read:

One Response to Approaches to Modular AIR Applications

  1. Hi Oliver,

    interesting topic. I’d tried to apply these concepts in a modular AIR application, and there are some caveats I can share.

    1) Loading a module in the application sandbox (Loader.loadBytes) load the bytecode in the application security domain, thus merging with its remote aliases registry (i.e. the information produced with the RemoteClass metadata or the registerClassAlias method) – I wasn’t able to reset/reassign these alias registration, along with other connected behaviors this makes the module almost impossible to unload or reload later, and can produce unexpected behavior when multiple submodules uses the same aliases.

    2) Loading a module in the network sandbox place places it in a separate SecurityDomain (this prevents the accesso to the AIR APIs and other protected objects such as the Stage), in order to work these modules needs to leverage the “Marshal Plan” feature to work: basically many features will be internally delegated to the main application using SharedEvents or SandboxBridge technique.. this adds some restriction to the capabilities of the submodule, requires the main application to be a full Flex application (it cannot be a pure ActionScript AIR project) and some care must be taken in managing Flex SDK versions of the main application and its submodules.

    Cosma