RSL

Table of contents [showhide]

Introduction

Use Flex 3 runtime-shared-libraries (RSLs) to reduce the size of your applications and thereby reduce the time required to download the application. RSLs are just SWF files whose code is used as a shared library between different application SWF files. There are two kinds of RSLs, signed and unsigned. Signed RSLs are libraries that are signed by Adobe and may be stored in the Flash Player Cache, which can be accessed by applications from any domain. This means if your application is using a signed RSL, the RSL may not even need to be downloaded if the RSL is already in the Flash Player Cache. The signed RSL may have been put into the Flash Player Cache by visiting another web site that was using the same signed RSL. Signed RSLs have a “swz” extension.

Unsigned RSLs are normal SWF files and are not loaded into the Flash Player Cache. Instead, these RSLs rely on the browser’s cache to keep them from being downloaded.

A new feature in Flex 3 is RSL verification. To guarantee only the desired RSL is loaded, a SHA-256 hash is used to create a digest of an RSL when a SWC is created. The digest of an RSL is linked into the application SWF loading the RSL. After reading the RSL from a specified URL, the digest of the RSL is compared with the digest of the expected RSL. If the two digests do not match the RSL will not be loaded into memory.

Flex 3 RSLs can be used from the command line and using Flex Builder. From the command line, use the -runtime-shared-library-path option with mxmlc to specify which SWCs you want to link as RSLs and the runtime URLs of where to find the RSLs and policy files. To use RSLs in Flex Builder, modify the project properties by adding RSL information for a SWC in the “Library path” properties. Details will be provided in the next section.

How to use the Flex Framework as an RSL

Let’s use the framework RSL, found in the framework\rsls directory to reduce the size of a simple hello world application. Every Flex application uses many classes in framework.swc, so this is a good choice to use as an RSL. The application source, main.mxml, is just a simple “Hello World” application:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
        <mx:Label x="165" y="10" text="Hello World"/>
</mx:Application>

When compiled normally using the command line,

mxmlc main.mxml

the file size of main.swf is approximately 145 KB. Now re-compile the application using framework.swc as an RSL.

mxmlc main.mxml -runtime-shared-library-path=c:\flexsdk_moxie\frameworks\libs\framework.swc,framework_3.0.165352.swf

Now the size of our hello world program is 46 KB! Let’s look at the -runtime-shared-library-path option in more detail.

The first argument is the path of the SWC file or an open directory that represents a SWC. In this example the sdk is installed in c:\flexsdk_moxie. The next argument is the URL of the RSL that will be used to load the RSL at runtime. In this example the RSL lives in the same directory as the application, but in could live on a server in another domain. The SDK RSLs live in the rsls subdirectory of the framework directory and are named according to the library they represent, version, and build number of the RSL. For example, for build 165352 the RSL for framework.swc is named framework_3.0.165352. The next argument that was not specified is the policy file URL. Since the RSL can live on different servers you may need to specify a crossdomain.xml policy file to gain permission to read the RSL from the server. You can also specify a failover RSL and policy file in case the first RSL can not be loaded. More than one SWC can be used as an RSL. This is done by adding a -runtime-shared-library-path option for each library.

mxmlc main.xmml -runtime-shared-library-path=c:\flexsdk_moxie\frameworks\libs\framework.swc,framework_3.0.165352.swf -runtime-shared-library-path=MyLibrary.swc,http://a.com/rsls/MyLibrary.swf,http://a.com/rsls/crossdomain.xml,MyLibrary.swf

In the case of MyLibrary.swc, the RSL will first be loaded from “http://a.com/rsls/MyLibrary.swf” using a policy file, “http://a.com/rsls/crossdomain.xml” to gain permission to read the file. If the file fails to load, then the next RSL, “MyLibrary.swf”, will be loaded. To learn more about policy files see this link: [1]

Using RSLs in Flex Builder is much easier. First bring up a project’s properties by selecting the project name in the Navigator View and choosing the File – Properties menu item. Next, choose the “Flex Build Path” properties and click on the “Library Path” tab. You should see the following:

Flex3FeatureIntroductions-RSL-image002.jpg

Change the default link type combo box from “Merged into Code” to “Runtime Shared Libraries”. Click on the SDK folder to open it up and do the same on the “framework.swc” entry. Click on the “RSL URL” entry. Your dialog should now look like this:

Flex3FeatureIntroductions-RSL-image004.jpg

Press the “Edit” Button to add an RSL for “framework.swc”

Flex3FeatureIntroductions-RSL-image006.jpg

Click on the “Use default link type” checkbox. This means use whatever link type is set on the “Library Path” page. Now choose the “Digests” radio button to use Flex 3 RSLs. To use RSLs as supported by 2.0.1 choose “None”. Now a table with an “Add…” Button will be displayed below the radio buttons. Click the “Add…” Button to add an RSL URL.

Flex3FeatureIntroductions-RSL-image008.jpg

A signed RSL will be displayed by default. Press OK. Now the “Library Path Item Options” Dialog will look like this.

Flex3FeatureIntroductions-RSL-image010.jpg

Notice the message below the table about requiring Flash Player “9.0.60″. Since only a single signed RSL was specified, Flash Player 9.0.60 will be required to run the application because it is the lowest version that knows how to load RSLs signed by Adobe. To allow the application to used by down-level Flash Players add an unsigned RSL as a failover. At runtime, if the Player running the application is less than version 9.0.60, then the signed RSL will be skipped and the unsigned RSL will be loaded. Press the “Add…” button to add an unsigned SWF. When the dialog first opens the default will be the signed RSL again. Change the extension from “swz” to “swf”.

Flex3FeatureIntroductions-RSL-image012.jpg

Press OK to save. Now the “Library Path Item Options” Dialog will look like this.

Flex3FeatureIntroductions-RSL-image014.jpg

Notice Flash Player version 9.0.60 is no longer required.

Press OK to save the RSL changes. Press OK again to save the changes to the project. If your “Project – Build Automatically” setting is set, the project will be re-compiled. If not, re-build the project. After the re-compile the size of an application will be reduced.

You can easily switch between a statically linked application and a dynamically linked application by just switching the “Default link type” combo box between “Merged into code” and “Runtime Shared Libraries” on the “Library Path” tab.

How to create an optimized RSL

When you are ready to deploy your RSL you will want to reduce its size to be as small as possible. The following steps will reduce the size of your RSL by over 50%.

  1. Extract Library.swf from the SWC.
  2. Run the optimize tool to remove debug information and metadata. Specify the metadata you want to keep by using the –keep-as3-metadata option.
  3. Optionally, run the digest tool to update the SWC digest information since the RSL has been modified.

Here’s an Ant task that runs the steps. The task assumes your SWC is a file, not a directory.

<?xml version="1.0"?>
<project name="myproject" default="create-my-rsls" basedir=".">
        <target name="create-my-rsls" description="Build RSLs">
              <macrodef name="create-rsl">
                       <attribute name="rsl-dir"/>
                       <attribute name="swc-dir"/>
                       <attribute name="swc-name"/>

                       <sequential>
                               <unzip src="@{swc-dir}/@{swc-name}.swc"
                                         dest="@{rsl-dir}" >
                                      <patternset>
                                              <include name="library.swf" />
                                      </patternset>
                               </unzip>

                              <java jar="${basedir}/lib/optimizer.jar" fork="true" failonerror="true">
                                      <jvmarg line="-ea -DAS3 -DAVMPLUS -Dflexlib=${basedir}\frameworks -Xms32m -Xmx384m -Dsun.io.useCanonCaches=false"/>
                                      <arg line="'@{rsl-dir}/library.swf' --output '@{rsl-dir}/@{swc-name}.swf'
--keep-as3-metadata='Bindable,Managed,ChangeEvent,NonCommittingChangeEvent,Transient' "/>
</java>
                               <delete file="@{rsl-dir}/library.swf"/>

                               <java jar="${basedir}/lib/digest.jar" fork="true" failonerror="true">
                                      <jvmarg line="-ea -DAS3 -DAVMPLUS -Xms32m -Xmx384m -Dsun.io.useCanonCaches=false"/>
                                      <arg line="--digest.rsl-file  @{rsl-dir}/@{swc-name}.swf --digest.swc-path  @{swc-dir}/@{swc-name}.swc"/>
                               </java>

                       </sequential>
               </macrodef>

               <!-- myswc RSL -->

               <create-rsl rsl-dir="c:\myproject\rsls" swc-dir="c:\myproject\libs" swc-name="myswc"/>

         </target>

</project>

Command Line Details

Runtime Shared Library Path

A new compiler option has been added to specify RSLs that can take advantage of the Flash Player Cache and may be loaded from a server in another domain. These RSLs are specified with the -runtime-shared-library-path option. Below is a full explanation of the option.

-runtime-shared-library-path=path-element,rsl-url,policy-file-url,[failover-url,policy-file-url]...

 alias -rslp

Specify a separate option for each SWC that will be linked as an RSL.

   * path-element Required. The path of a SWC file or a directory containing the contents of a SWC file. The SWC file allows the digest of library.swf file to be included in the startup information, if -verify-digests is true. The classes in the SWC file are automatically excluded from the application SWF and therefore the SWC file does not need to be added to -external-library-path option.
   * rsl-url Required. The URL of the deployed location of the associated with the SWC given in the first parameter. If the URL has a "swz" extension the signed-digest in catalog.xml will be used to load the RSL. If the URL has a "swf" extension, the unsigned digest xml will be used to verify the correct RSL was loaded.
   * policy-file-url Required. The policy file allows the file specified by rsl_url to be read, if it is located on a server in a different domain than the application loading the RSL. To explicitly not specify a policy file for an RSL, specify an empty string between separators, (for example ",,"). If a policy file is not specified, the player will default to reading the policy file at /crossdomain.xml on the server hosting the RSL.
   * [failover_url, policy_file_url] Optional. The URL of an RSL to try of load in case rsl_url can not be loaded. Any number of failover URLs may be supplied. When failover_url is specified a policy_file_url must also be specified. The policy file may be an empty string or not specfied if the failover url is the last failover in the list.

Enable RSL Digest Verification

After a SWC is updated and the RSL is deployed, applications using the SWC needs to be re-linked. When the application is re-linked, the new digest in the SWC will be written into the application. Failing to relink with the latest library will cause a digest mismatch runtime error when trying to load the RSL. For a development enviroment where the RSLs may be changing often, thereby changing the digest of the RSL, it may be difficult to stay in sync with the latest RSL change. For this reason the -verify-digests option was added.

-verify-digests={true | false}

If true, the application will verify the correct library has been loaded at runtime by computing a digest of the RSL and comparing it to the digest of the library that was linked with.

Defaults to true.

This option should always be true for a production application, otherwise the application is vulnerable to a man-in-the-middle attack. This would be set to false in a developement scenario where an RSL is being modified frequently, so the application does not need to keep re-linking to the latest RSL before it can be run.

Switching Between RSLs and Static Linking

-static-link-runtime-shared-libraries={true | false}

alias static-rsls

If true the RSLs specified by the -runtime-shared-library-path options are ignored, otherwise, the application will be linked using he RSLs. Defaults to true.

This option is useful to quickly switch between static and dynamic linked application without having to change the -runtime-shared-library-path option, which is quite verbose.

Create SHA-256 Digest

When you create a library that you want to use as a RSL and verify the digests, use the “-compute-digest” option to store a digest of the library.swf in the catalog.xml of the library. When the “-runtime-shared-library-path” option is used the compiler will look for a digest in the library to put into the application’s startup information. If no digest is found, the application will not be created.

-compute-digest={true | false}

If the value is true a digest will be written to catalog.xml when an rsl is created. Otherwise, the digest will not be calculated or written. The default value is true.

If compute-digest is true, then digests are created, if false, then digests are not created. Digests are created by default but a SWC with digest information is not backwards compatible. To create a SWC that may be used with Flex 2.0.1 compile your library with the “compute-digest” option set to false.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: