Welcome on the page of the SexieR project.
Let's first debate what is a dynamic library. You should look at this excellent article by Aral :using swf files as runtime external libraries You may ask why you should use dynamic libraries ? Here are some reasons for you :
Still, the problem with this approach is excluding classes from compile. There are three ways to do it :
In each case, you MUST create an item (ie an entry in an exclusion file or an intrinsic class) for the associated file to be excluded from compile. It means you should have to manually resolve all your dependecies… That is if you do it the hard way.
SexieR will actually do that for you. It can either (for now) generate the complete exclusion (intrinsincs or excl files with dependencies) for :
In the last case, it will also generate a Library class that you will only need to compile to generate your library
The original name of the project whas Sexie for Swc to Exclusion XML or Intrinsic Exporter. This new application is Sexie Reloaded, that is SexieR :p
I will explain here how you can generate your exclusions from a package using Ant. First we will define a new task for ant
<taskdef name="sexiePackage" className="org.aggelos.sexie.app.ant.SexiePackage" classpath="${path.to.sexie.jar}" />
Task that you can use this way :
<target name="generateExclude" > <sexiePackage outputDirectory="${out.dir}" source="${src}" mode="mtasc" dependencies="${dep1};${dep2}" /> </target>
The differente attributes of the task are those :
Sexie Library scans a file pretty much like a mtasc exclusion file, ie that contains a fully qualified class name by line.
It then generates the exclusion items, and a file called Library.as which can be automatically compiled with MTasc or using the line “Library.main()” in a fla to create a dynamic library
First, you will need to instantiate the task :
<taskdef name="sexieLibrary" className="org.aggelos.sexie.app.ant.SexieLibrary" classpath="${path.to.sexie}" />
Then you should create a library.sexie file containing something like:
org.aggelos.myapp.ClassA org.aggelos.myapp.ClassB
You can now create your target for ant :
<target name="create remoting lib" > <sexieLibrary outputDirectory="remoting" sources="${src1};${src2};..." mode="mtasc" classList="library.sexie" /> </target>
In your ouptut folder you should also have your Library.as file
The AggLibTools are a little bunch of classes to easily handle your external libraries.
Let's suppose that I have two classes :
All you need is to create a file called for exemple mylibs.load containing for each line a path to a library. For example here :
./liba.swf ./libb.swf
then, you can use the classes LibrariesLoader and LoadingLibrary this way :
import org.aggelos.utils.libs.LibrariesLoader; import org.aggelos.utils.libs.LoadingLibrary; import org.aggelos.events.Event; import org.aggelos.myapp.ClassA; import org.aggelos.myapp.ClassB; class Application { function Application() { var ll:LibrariesLoader = new LibrariesLoader(this.createEmptyMovieClip("libs",0)); ll.addEventListener("ALL",this); ll.loadFile("mylibs.load"); } function onLibraryStart(evt:Event) { trace("Starting "+evt.target.name); } function onLibraryLoaded(evt:Event) { trace("Loaded "+evt.target.name); } function onLibraryProgress(evt:Event) { var lib:LoadingLibrary = LoadingLibrary(evt.target); trace("Progress "+lib.bytesLoaded+"/"+lib.bytesTotal); } function onLibrariesComplete(evt:Event) { trace("loading complete"); startApp(); } function onLibrariesError(evt:Event) { trace("Error "+evt.target.name); } public static function main() { new Application(); } public function startApp() { var ca:ClassA = new ClassA(); var cb:ClassB = new ClassB(); } }
You should really start your application after the onLibrariesComplete event, which signals that all your code has been loaded.
First, we will create the .swf containing the remoting classes. Let's create the remoting.sexie file :
mx.remoting.PendingCall mx.remoting.Service mx.rpc.FaultEvent mx.rpc.RelayResponder mx.rpc.ResultEvent
the .fla we will compile, containing only :
(new Library()).doNothing();
then, using ANT and Sexier, we will create the Library.as file :
<taskdef name="sexieLibrary" className="org.aggelos.sexie.app.ant.SexieLibrary" classpath="${path.to.sexie}" /> <taskdef name="flashCompile" classname="FlashANT" classpath="${user.home}/.fdt"/> <target name="create remoting lib" > <sexieLibrary outputDirectory="remoting" sources="${pathtoyourclassesfolder}" mode="mtasc" classList="remoting.sexie" /> <flashCompile file="remoting.fla" exe="${path.to.flash}"/> </target>
Well, here I made a little shortcut, assuming you used the flashCompile task shipped with FDT. You can do it manually too. Let's suppose that your output swf is remoting.swf
By now you should create another library with all the classes for your application. Let's call it library.sexie
org.aggelos.myapp.ClassA org.aggelos.myapp.ClassB
Sexie will scan for ClassA, ClassB, and all the classes they depend on, and generate the appropriate exclusion files or intrinsic files. The remoting classes will also be included if ClassA and/or ClassB depend on those. Let's generate the libray and compile it (using mtasc this time :p)
<taskdef name="mtasc" classname="org.as2lib.ant.Mtasc" classpath="${path.to.antmtasc}" /> <target name="create lib" description="creates the library"> <sexieLibrary outputDirectory="main" sources="${src};${dep1};${dep2}" mode="mtasc" classList="library.sexie" exclude="mx.utils.Delegate" /> <mtasc mtasc="${mtasc.path}" src="main/Library.as" classPath="${deps.mtasc}" excl="remoting/exclude.mtasc" swf="library.swf" header="1:1:25"> </mtasc> </target>
I won't come back on how to compile with mtasc, you will find tutorials elsewhere.
Ok, now we have two libraries. How to include them in your code ? Here come the AggLibTools. You will need to use two classes :
LibrariesLoader LoadingLibrary
Create a file containing the list of the urls of the libraries you want to load :
/libs/remoting.swf /libs/library.swf
Let's call it libraries.libs Now for your main AS file
import org.aggelos.utils.libs.LibrariesLoader; import org.aggelos.utils.libs.LoadingLibrary; import org.aggelos.events.Event; import org.aggelos.app.ClassA; import org.aggelos.app.ClassB; class Application { function Application() { var ll:LibrariesLoader = new LibrariesLoader(this.createEmptyMovieClip("libs",0)); ll.addEventListener("ALL",this); ll.loadFile("libraries.lib"); } function onLibraryStart(evt:Event) { trace("Starting "+evt.target.name); } function onLibraryLoaded(evt:Event) { trace("Loaded "+evt.target.name); } function onLibraryProgress(evt:Event) { var lib:LoadingLibrary = LoadingLibrary(evt.target); trace("Progress "+lib.bytesLoaded+"/"+lib.bytesTotal); } function onLibrariesComplete(evt:Event) { trace("loading complete"); startApp(); } function onLibrariesError(evt:Event) { trace("Error "+evt.target.name); } public static function main() { new Application(); } public function startApp() { var ca:ClassA = new ClassA(); var cb:ClassB = new ClassB(); } }
Your code should really start on the onLibrariesComplete event, when all your libraires are loaded. It may look a tad difficult at first sight, but since you automate everything, the only cost is what you do when starting your project. Well, I now gain a lot of time.
Well, it's up to you. To be honnest, I think that hamtasc is a bit more powerful and reliable and yet, I use SexieR in my development and did not have major issues with it.
You should consider this however :
Well, well, well… Intrinsics have the advantage to be cross compiler. That being said, being classes, arranged in a hierarchy of folders, they are a bit more difficult to handle. I personnaly use exclusion files, which proved for me easy to handle, to scan, and so on. Plus, if you modify your classes, you will have to update your intrinsics quite more often than exclusion files.
Not reimplemented yet. Use Sexie or ant to do that :p
Then you should really consider using Aral's excellent DLLLoader class. Available on this page
Current version : 0.7.3
Version 0.7.n : * exclusion for Sexie Package * bug tracking * reintegrate SWF processing
Version 0.8.n : * GUI and eclipse plugin (should use SWT) (WIP)
version 0.9.n : * Command Line
Sexie is released under the GNU GPL Licence
Some times ago, Aral published a page on using swf files as runtime external libraries. We then had an exchange on the mailing list with Aral and Francis Bourre which lead me to create a little graphical tool to generate the appropriate exclusion files or intrinsic packages for complexe libraries via a swc file.
You will need a 1.5 java runtime environment to launch sexie.
imagine you have the following import declarations at the begining of your code
import class1; import com.something.class2; import class3; ... import classn;
and each one of this classes uses a complexe set of imports. There is a way to resolve all the dependencies
class ClassLoader extends MovieClip { public function doNothing() { class1; com.something.class2; class3; ...; classn; } }
notice that I did not write the “import” keyword in order for each class to be loaded.
To create your library swf, simply do as described in Aral's article. You can also use the following command
(new ClassLoader()).doNothing();
Right, now we have our swc. Open sexie and browse to get it, then select wether you want to export an intrinsic package in a directory, an exclusion XML or a MTasc exclusion file. It is as simple as it seems.
Here you go, thanks to Aral, Francis and Steve Webster for their contribution to this subject, and to Cedric Tabin for the suggestions on the windows batch files.
Sexie is released under the GNU GPL Licence
Discussion