Maven module structure of the project.
Recently I had switched a complex Flex project that previously used all libraries as statically compiled SWCs to dynamically loaded Runtime Shared Libraries (RSL). In the picture on the right you can see the module structure of the whole build, which was done using Maven and the flex-mojos plugin.

You can see that there is one high level library (library A) that is shared across all applications and a more specialized library (library B) that is providing components and classes to a certain subset of other applications.

Library A contains a couple of embedded images containing various icons and a lot of components, while Library B contained just a few components. So after compilation the obvious expected result would be to have an RSL file of library A that is much bigger than the RSL file of library B in case library B uses library A as RSL and not as statically linked SWC.

Well the dynamic linkage worked well for all the applications, which where just a couple of KBs in size after the change in contrast to more than 1 MB before the change. However this was not the case for the libraries. Library A had a size of 1.2 MB but library B had a size of 1.25 MB???

So it looks like the library B Maven project was not set up correctly and is stilled compiled statically against library A. But before we continue let's strip this problem down to a more simple project to be able to examine this in a clean environment. Feel free to download the project and try it out yourself.

Analyzation of the Problem

Module structure of the simplified project.

This simple project contains three modules.

The library lib-a contains a big image that is an embedded resource in the MXML component ImageComponent. This library contains also a couple of other sources that have no other purpose than to increase the size of the library. The flex-mojos configuration defines the 'optimize' goal in its <execution> configuration. This tells the compiler to create a RSL from the generated SWC.

Like Library lib-a, lib-b is also configured to compile into an RSL. It contains another MXML component UsingLibAComponent that uses the ImageComponent from lib-a and therefore has a dependency on that library. This dependency is actually configured as RSL, just like it is done by the application app, which simply displays the component from lib-b.

The library lib-a and the application are only of secondary interest here. The size problem is only in the library lib-b so let's focus on that module.

Have a look into the pom.xml file of lib-b. You'll notice that the scope of the lib-a dependency is really set to rsl. This tells flex-mojos to tell the flex compiler to use this library as RSL dependency.


And in fact flex-mojos seems to behave correctly when it calls the compiler from a mvn clean install. So I do not see a Bug in flex-mojos here.

 [INFO] Flex compiler configurations:                                            
-compiler.actionscript-file-encoding UTF-8                                      
-compiler.external-library-path /home/cschlipf/tmp/rsltest/lib-b/target/classes/libraries/playerglobal.swc 
-compiler.fonts.local-fonts-snapshot /home/cschlipf/tmp/rsltest/lib-b/target/classes/fonts.ser             
-compiler.library-path /home/cschlipf/.m2/repository/com/adobe/flex/framework/flex/ /home/cschlipf/.m2/repository/com/adobe/flex/framework/rpc/ /home/cschlipf/.m2/repository/com/adobe/flex/framework/utilities/ /home/cschlipf/.m2/repository/com/adobe/flex/framework/framework/ /home/cschlipf/.m2/repository/de/yeap/playground/rsls/lib-a/1.0-SNAPSHOT/lib-a-1.0-SNAPSHOT.swc                                        
-compiler.namespaces.namespace /home/cschlipf/tmp/rsltest/lib-b/target/classes/configs/mxml-manifest.xml                                             
-compiler.source-path /home/cschlipf/tmp/rsltest/lib-b/src/main/flex
-default-background-color 8821927
-default-frame-rate 24
-default-script-limits 1000 60
-default-size 500 375 Fri Jun 19 23:23:11 CEST 2009
-target-player 9.0.124

As you can see here lib-a is correctly added to the compiler.library-path and the runtime-shared-library-path options - just like the framework library. But here are the resulting file sizes:


[INFO] Original file is: 10095 k bytes                                                                                                                                              
[INFO] optimized swf is: 606 k bytes    


[INFO] Original file is: 784 k 
[INFO] optimized swf is: 541 k bytes 

So lib-b is almost as big as lib-a although it contains just one class, while lib-a contains 1000 much bigger classes and an embedded big image resource. Looks like lib-b is statically compiled against lib-a.That's why it is a little bit smaller than lib-a as the 1000 source files contained in the lib-a are not used by lib-b and are therefore not linked against lib-b. But let's double check this by uncommenting the scope from the lib-a dependency and see what happens with lib-b in case we compile it statically against lib-a by intention.

[INFO] Original file is: 784 k bytes                                                                                                                                                
[INFO] optimized swf is: 541 k bytes

Exactly the same numbers and yes... I double checked that lib-a is no longer specified to the compiler through the runtime-shared-library-path option.

And the Application?

All the time I was talking about the libraries, but what's about the application, which is also compiled against the RSL libraries? It's size is 72 KB. So obviously the application is dynamically linked against the libraries just like we had expected for lib-b being dynamically compiled against lib-a.


In fact there seems so be a bug in the compiler when linking libraries against dynamically linked RSLs. Libraries are always  linked statically against other libraries - no matter whether specified through the runtime-shared-library-path option or not. This does not apply to applications, where the compiler behaved correctly.


But what can you do against that? The solutions is quite simple:

For libraries externalize all dependencies that are dynamically loaded by the application and make sure that the application loads all required libraries through linking the application against all dependent (inkl. transitive dependent) RSLs.

So do not use the scope 'rsl', but rather use 'external' for dependencies in SWC projects:



To be able to see the result of externalizing dynamic libraries for libraries see this table:

Configuration Size of lib-a
Size of lib-b
Statically linked
606 KB
541 KB
"Dynamically" linked
606 KB
541 KB
Externalized framework.swc and lib-a for lib-b
442 KB
4 KB
Size saving in KB
164 KB
537 KB
Size saving in %
27 %
99 %

Feel free to download my sample application (11.9 MB) to verify my results. You will need to have Maven 2.0.9 or higher installed in order to compile the examples. Just extract the ZIP file, change the directory into the rsltest folder and run mvn clean install.

Update:Had a discussion with Marvin "VELO" Froeder, the developer of the flex-mojos Maven plugin. He wants to improve flex-mojos to automatically handle this situation in the future.

Update (2009-09-10): flex-mojos 3.3.0 is released. In case a SWC projects has runtime dependencies of the scope 'rsl' or 'caching' a warning is shown and the scope is automatically changed to 'external'.


Trackback specific URI for this entry
    No Trackbacks


    #1 Leonardo Varela on 10/11/09 at 07:55 PM
    *Great article!
    Do you have an updated version using flex-mojos 3.3.0?
    #1.1 Carsten Schlipf on 10/12/09 at 01:39 PM
    *Hi Leonardo,

    see my update at the end of this posting from September 10th.

    #2 Anil on 11/22/11 at 11:04 AM

    I am trying to implement RSL in my application, At the same time I am using MAVEN (FLEX MOJOS) to build the project. I started with implementing the same using Flex Builder and everything works fine. But, as soon as, I build the same code base through MAVEN. I am getting following error in class

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at mx.managers::SystemManager/preloader_rslCompleteHandler()
    at mx.preloaders::Preloader/
    at mx.core::RSLListLoader/listCompleteHandler()
    at mx.core::RSLItem/itemCompleteHandler()
    at mx.core::CrossDomainRSLItem/loadBytesCompleteHandler()

    Any Help will be appreciated.


Add Comment

HTML-Tags will be converted to Entities.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.