Generate Accessible SWF does not generate a SWF

I am trying for hours to tell Flex, that I need an accessible SWF of my Flex-Library(There is a checkbox in the Actionscript Compiler options panel). But I only get a SWC file. So what is the deal ? Is there no solution to load a Flex Library at runtime without creating a new Project, where I merge the library into code ? The background is, that I want to exclude various classes with dependencies from my current project and export them into one SWF (without dependent classes) and load them in runtime. I want a simple solution without having XML exclude files or similar attacks on the compiler.

Joa pointed out, that the SWC is actually just a ZIP-file, where the SWF and a XML is included. So I tried to load the unpacked SWF and it seems to be possible, but no Event.COMPLETE or Event.INIT is fired. Now the magic: If I try to get my class after a setTimeout (to be sure the SWF is loaded), I effectively get the class. Furthermore both Events are fired after using getDefinition. How weird is that?

Any suggestions are welcome.

Here were my lovely code (as an Application class) to create a SWF with just one class (unfortunately not possible).

package
{
	import flash.display.Sprite;

	[Compiler(include com.domain.package.ClassName)]

	public class LoaderSatisfier extends Sprite
	{
		public function LoaderSatisfier()
		{
		}
	}
}

The goal were to have an Application class with some Meta-Tags to keep all classes except the certain classes from export into the SWF. What a timesaver!

22 thoughts on “Generate Accessible SWF does not generate a SWF”

  1. Matt:
    I am not sure, what you mean. If I declare it as a compiler option (-rsl), doesn’t that mean I merge the library into the application SWF? I want to load several classes dynamically in runtime. So I wouldn’t make sense, if I have to put them all into the compiler arguments. Some of the classes will be loaded, some not…

  2. No, it loads it separately (though it does require the file at startup). If you really want it loaded later this is the kind of thing that Modules has helped with, though it isn’t perfect.

  3. Hi !
    Maybe you should use a Module instead. Modules have been created to be loaded a runtime. I haven’t used it yet, but I think that might be the solution.
    Here’s a link to a presentation I read this morning about modules and rsl, I think it might help you to choose between modules and rsl.

    http://blogs.adobe.com/aharui/2007/03/modules.html

    Good luck :)

  4. That wouldn’t help unfortunately. That means, I need to compile my project everytime I add a new compiled class. The classes are actually plugins extending the application in runtime.

    What do you mean with ‘Modules’ ?

  5. Hi Michelle,

    There’s a way:

    First, the reason why it will not fire Complete/Init event when you load the unpacked swf is that there’s no entry class in it. (You know the application entry of AS3 is a class that must inherited Sprite, when swf is loaded a instance of that class will be created to be the root)

    So, for the case, we should create a swf that include all your classes and has a entry class(it can be a empty Class inherited Sprite), with “include-libraries library […]” or “include class […]” param of the compiler, you can easily compile all classes into your swf.

    So, then you have a library swf that can be loaded into your application at runtime and will fire Event.COMPLETE and Event.INIT events.

  6. you should try “-link-report” in mxmlc options
    then you can exclude any classes you needed
    “Module Chapter in Flex 2.01 doc” maybe help

    The module implementation in flex based on ApplicationDomain and Loader
    the as3 implementation is more easy to write,
    you just need a Loader and load other swf class with
    applicationdomain when flex module also should supprot rsl and other Global Managers.

    flex compiler is not well in supporting module app’s build when you have many modules in different Projects. I

    don’t like Ant, so I wrote a simple .bat file to compile my multi projects, and using “-link-report” to have

    many opertions in including and excluding classes in different swfs.

    I also wrote the module implementation in as3 project,
    is very simple to write, but i get some applicationdomain bug when build
    with flash 9 alpha or flash cs3
    it’s said to be a bug in flash player 9.0.28

    this is the sample bat file for flex compiler to build:
    MagicLinker: the flex framework i needed
    MagicPlatform: is the Module Loader ,the shell
    Modules: other sub module loaded by shell, only have the module logic class, no flex class, no duplicate class

    with the shell

    @ECHO OFF

    REM Definition Path & Name for building

    set LINK_PATH=E:\Projects\Magician\MagicLinker\bin\
    set LINK_SRC=E:\Projects\Magician\MagicLinker\
    set RSL_NAME=MagicLinker
    set RSL_PATH=http://localhost/flex/
    set DEPLOY_PATH=E:\Projects\Magician\Deploy\

    set Build_PATH=E:\Projects\Magician\Build\
    set FLEX_CONFIG=%Build_PATH%flex-config.xml

    set SRC_PATH=E:\Projects\Magician\MagicPlatform\

    set APP_NAME=MagicPlatform
    set REPORT_NAME=report.xml

    REM Step 1 : Build the Linker

    REM generate rsl swc to linker bin folder
    REM compc -debug=false -source-path=%LINK_SRC% -o=%LINK_PATH%%RSL_NAME%.swc %RSL_NAME%
    REM generate rsl swf to delopy folder
    REM mxmlc -o=%DEPLOY_PATH%%RSL_NAME%.swf -file-specs=%LINK_SRC%%RSL_NAME%.as

    REM Step 2 : Build Main Application

    REM Export the report of Main Application
    mxmlc -link-report=%DEPLOY_PATH%%REPORT_NAME% -load-config=%FLEX_CONFIG% -external-library-path=%

    LINK_PATH%%RSL_NAME%.swc -runtime-shared-libraries=%RSL_PATH%%RSL_NAME%.swf -file-specs=%SRC_PATH%%

    APP_NAME%.mxml -source-path+=%SRC_PATH% -defaults-css-url=%Build_PATH%defaults.css -o=%DEPLOY_PATH%%

    APP_NAME%.swf

    REM Step 3: Build Modules
    REM Define Login Module
    set MODULE_NAME=LoginModule
    set MODULE_PATH=%SRC_PATH%Modules\
    set MODULE_SRC=%SRC_PATH%
    REM Export reports
    mxmlc -load-externs=%DEPLOY_PATH%%REPORT_NAME% -external-library-path=%LINK_PATH%%RSL_NAME%.swc -runtime-

    shared-libraries=%RSL_PATH%%RSL_NAME%.swf -load-config=%FLEX_CONFIG% -link-report=%DEPLOY_PATH%%MODULE_NAME%

    _report.xml -file-specs=%MODULE_PATH%%MODULE_NAME%.mxml -source-path+=%MODULE_SRC% -strict=false -o=%

    DEPLOY_PATH%%MODULE_NAME%.swf -defaults-css-url=%Build_PATH%defaults.css

    REM Define Lobby Module
    set MODULE_NAME=LobbyModule
    set MODULE_PATH=%SRC_PATH%Modules\
    set MODULE_SRC=%SRC_PATH%
    REM Export reports
    mxmlc -load-externs=%DEPLOY_PATH%%REPORT_NAME% -external-library-path=%LINK_PATH%%RSL_NAME%.swc -runtime-

    shared-libraries=%RSL_PATH%%RSL_NAME%.swf -load-config=%FLEX_CONFIG% -link-report=%DEPLOY_PATH%%MODULE_NAME%

    _report.xml -file-specs=%MODULE_PATH%%MODULE_NAME%.mxml -source-path+=%MODULE_SRC% -strict=false -o=%

    DEPLOY_PATH%%MODULE_NAME%.swf -defaults-css-url=%Build_PATH%defaults.css

  7. iiley:
    I already had an empty class extending Sprite, but in a FlexLibrary enviroment, there is no way to declare the class as an application class. However it is included already, but no Event is fired on load/init.

    If you are talking about a FlexProject:
    “include-libraries library […]” or “include class […]” does compile all dependent classes into the resulting SWF, which was not the goal.

    Did I get you wrong ?

    zuric:
    You script scares me. Is it really possible, that we need that kind of overhead for this simple task?

    … include a class in a SWF…?

  8. Hi Michelle,

    I’v not explained clearly. :)

    Well, it should be:

    One library have two projects In FlexBuilder2.0.1:

    1. The regular Flex Library Project, with all your classes defined that need to load at runtime.

    2. The ActionScript Project(Note, not FlexProject, so you do not need to do the MXML), with only one empty entry class, but the project included the first library project and use include-libraries library […]” or “include class […]” addition compiler param to force the library classes will be compiled to the output SWF.

    The 2nd project is just additional project to help you to generate the right SWF with a entry class. You also can write a ant or bat script to do that job. (note that there are two compiler, compc is used to compile library project to a SWC, and mxmlc is used to compile the SWF with a entry class)

    And, when you’v generated the SWF with all library classes and a entry point. You can load it at runtime and got events fired when loaded.

    BTW you can use “LinkType -> external”(by default it is “Merged into code”) to make the library classes exclude when compile your main application.

  9. iiley:
    I think I understand. Expect that I have 20-30 Plugins. So for every Plugin I need a library to sort out my classes without dependencies AND a project to create an accessible SWF. So this is real overhead.

    I am trying to understand ANT, since I can imagine that this is the key to solve it as elegant as possible. Unfortunately I even didn’t get Flex_Ant_Tasks installed. I would love to see, that I still have only one project and different ANTs to compile the Plugin and Main-Application.

  10. Ah, yes, It’s a mess for a the project structure if you have many plugins.

    Ant will help you to simple the projects structure. I’m not familiar with Ant script too, but i know it really can make your just have one project and different ANTs(or even one ANT script) to compile the Plugin and Main-Application. :)

  11. I finally could create a working build.xml.

    But still, any include class syntax like “[include -class dir=”src/” includes=”com.domain.plugins.Gain”/]” is failing with an error. ‘The type doesn’t support the “include-class” nested element.’ I am an absolute beginner…

    compc does not support the file attribute (for having an entry)
    mxmlc does not support includes

    HELP! ;)

  12. Hi Andre, have you fixed it out?
    I’m not familiar with ANT script too, i just got success with the way of additional ActionScript Project.

    Well, i’ll try your build.xml later…

  13. Hi Michelle,

    I tried the mxmlc params again, here’s the working example(not include the brackets):

    1. Include all classes in AsWing A3 swc
    [-include-libraries E:\workspace\AsWingA3\bin\AsWingA3.swc]

    2. Include org.aswing.Component and it used classes(the classes should be in classpath of course)
    [-includes org.aswing.Component]

    I have not installed FlexAnt too, so not tried it, but i found some info here

  14. About the includes in the mxmlc task, I face the same problem, and resolving that by not using the FlexAnt anymore. By doing same your task would look like that :

    Assuming that you have defined properties correctly. In that task ${includes} in the space separated list of classes to compile and ${excludes} the path to the exclusions xml file (from -link-report output).

    Unfortunately its really boring to correctly create a specific exclusion file for each swf witch make your plugin swf working everywhere, at end I use the report from my main application assembler to be sure that plugin will work in the most cases.

  15. wooops, forgot that html tags are stripped tag ^^’

    [exec executable=”${mxmlc.exe}”]
    [arg line=”-load-config=’${flex.config}'”/]
    [arg line=”-source-path+=’${flex.framework.dir}'”/]
    [arg line=”-output=’${output}'”/]
    [arg line=”-link-report=’${report}'”/]

    [arg line=”${includes}”/]
    [arg line=”${excludes}”/]

    [arg line=”– ‘${file}'”/]
    [/exec]

  16. I don’t know if you resolved your prob but
    I had the same problem with Event.COMPLETE or Event.INIT on my lib
    i did it that way with ant
    I hope it helps
    makelib.xml ant file

    The "compc.exe" property must be set.


    the build.propreties files

    # location of the Flex 2 SDK
    flex2sdk.bin.dir = /Users/manu/Developpement/lib/flex_sdk/bin

    # General properties

    asdoc.exe = ${flex2sdk.bin.dir}/asdoc
    compc.exe = ${flex2sdk.bin.dir}/compc
    mxmlc.exe = ${flex2sdk.bin.dir}/mxmlc

    # Path properties
    build.dir = build/
    plugin.dir= net/site/path/to/plugin/
    plugin-build.dir = build/plugin/
    lib.dir = build/lib/
    report.dir = build/report/
    plugin-source.dir = /path/to/Eclipse/workspace/Project/src/

  17. the ant file makelib.xml

    The "compc.exe" property must be set in ${build.dir}/katabunga-build.properties.

  18. The secret lies in this sentence tucked way down in the page at
    http://livedocs.adobe.com/flex/3/html/help.html?content=rsl_03.html.

    “After you create the library, you then compile your application against the SWC file and specify the library’s SWF file’s location for use at run time.”

    I use two projects, one for production and one for development. The source files are all the same, meaning the same directories are referenced by both projects.

    The development project has the modules linked using RSL, while the production one has them linked as External Modules. That way when I run the development project is links up all my Library modules and creates the .SWF files automatically. Only problem is that it auto-loads all the RSLs when it starts, but that’s where the production project comes in. The application uses ModuleManager to load the libraries no matter what, but when running the development project this is a no-op using
    ‘if (!ApplicationDomain.currentDomain.hasDefinition(className))
    loadModule(path);
    // e.g. var info = ModuleManager.getModule(path);
    // info.addEventListeners( for READY and ERROR );
    // info.load(ApplicationDomain.currentDomain).
    else
    dispatchEvent(ModuleEvent.READY);’

    I can just run the production project (even in debug mode) to rest assured that everything is truly being dynamically loaded on-demand.

    Also, you have to catch the ModuleEvents to make this work right. Using timers is not a good way, and the code is much cleaner if you get the right events going. I recommend listening for ModuleEvent.READY and ModuleEvent.ERROR so you can know either way if your load worked.

Comments are closed.