Building flex 3 (flash) swc libraries on mac os x with ant and flex builder 3

I strongly believe in learning new languages and platforms. While i’m super happy with the ruby / rails / merb world, I know it has it’s limits. Most of the time when i look farther afield i think of hacking on lua, erlang, or smalltalk… But recently i had an app idea which struck me as something which really was a good fit for Air. Adobe’s version of Flash to run desktop applications. Let me say at first I though Air was stupid, but over time i’ve come to realize that for some applications, it makes lots of sense. It’s similar to my thinking Flash was stupid until it changed the world of online video, and ActionScript was some stupid director derived toy language until I realized that these days it’s EMCA script, basically the same damned thing as Javascript.

So i set out on the path of building an Air app. I asked my old buddy, Dom and he said there were two IDE’s for Flex development, flex is the updated version of flash which is more programming like vs Director scripting like. Flex draws on the java world’s traditions more than the scripting world, a sin may be forgivable if i am able to build this cool app i’ve thought up. For Flex there are two IDE’s Apatna (free and ‘professional’ edition) and Adobe’s own Flex Builder 3 which is payware, but you get a 90 free trial to play with. The core is actually free, the SDK to build flex apps and it comes with no IDE, but just command line tools.

Flex draws on Java, there are tools like ant which are used for all the build processes. Really the IDE’s are both based on customized versions of eclipse. I’m not a fan of IDE’s they seem to be needed when the development processes has gotten to complicated to fit inside your head and try and make everything point and click. Silliness. Flex can use html to render an interface, but it also has it’s own proprietary xml for laying out interface elements. It creates a dom like thing, which you can attach action script events to… Once you get over how different it is from real web development, at some level it’s the same damned thing. It’s worth stating, that you can make flash as standards compliant, open, accessible, etc as html and unobtrusive javascript, but nobody seems to actually do it. Just yesterday i was noticing that yahoo map’s flash app wouldn’t let me paste in an address. Just like rails and django encourage you to do the right thing by default, flash defaults to clunky custom interface elements with broken accessibility.

Anyway, back to what i was saying. How to make this stuff work. There are it seems a lot of people with flash / flex development blogs which is useful, but on the whole i’ve been very unimpressed with the documentation. There’s a HUGE amount about how to do various UI widget things, and very little about toolsmithing, libraries, building out flex as a platform.

The thing is, i know how a rails app works, how php plays with apache and a load balancer. I don’t know how these flex apps come together. It found lots of tutorials on building toy apps, but not a one ever mentioned using a library you find online and incorporating it in to your application. I suspect it’s because the open source tradition is pretty week in the flash world. Just like in VB and Java, because you pay for the IDE, it creates a culture of pay to play. It stands in stark contrast to the scripting world of Perl, PHP, Python, and Ruby. In the scripting world we build libraries for our own uses, then release them for the community to use and help maintain. The only libraries i’ve found to be released so far in the flex world, come from Adobe employees themselves. Clearly it’s a failure of community that there is repository of open source libraries like CPAN, Ruby Gems, PEAR, and the Python Package Index. What the adobe does have is RIA Forge, as far as i can tell RIA is some term Macrodobe made up. The thing is, RIA forge is just a directory linking to libraries around the web, kind of like RAA. It has no build process, no clearly defined way in which libraries are included in your larger application. It solves the, how do i find what’s out there problem, but not really the how do i easily include it in to what i’m building.

Which brings me to the whole reason i wrote this blog post. I spent the last day or two trying to figure out what to do with libraries like these: as3corelib and as3awss3lib. They are the core action script 3 libraries for things like md5 hashing, json serialization, and general string, date, and time functionality. The second one is action script 3 library for working with amazon web services. Pretty useful and straight forward stuff. Don’t ask my why the as3corelib isn’t just included for use everywhere all the time, it’s an extreme case of batteries not included. In ruby i’d run ‘sudo gem install aws-s3’ and i’d magically get the libraries i need. There are pretty straight forward alternatives php, python, and perl.

But these libraries aren’t distributed as binaries, packages, nor anything easily installable. What do you do get is a note saying: “There is currently no zip archive available. Please check the code out using subversion. ” That’s pretty much it. When you do check out the svn repo you get this:

bas1:~/code/as3awss3lib-read-only rabble$ tree .
.
`-- src
    `-- com
        `-- adobe
            `-- webapis
                `-- awss3
                    |-- AWSS3.as
                    |-- AWSS3Event.as
                    |-- Bucket.as
                    `-- S3Object.as

5 directories, 4 files

For files, in a nested set of directories which seems pretty straight forward. I want to be able to access these files from my app, so i simply did the obvious thing, from a scripting background, copied the whole com dir and children over to my lib directory in the app i’m building. Needless to say that didn’t work. I tried moving around the files to various other directories and that didn’t work either. I read everything I could find in the documentation and on various community created sites, dead ends. I tried asking in the #flex irc channel, nobody seemed to even understand my question. I tried pinging friends who work on flash stuff at Adobe as well, i got blank stares and silence.

What was going on here? Clearly somebody at Adobe had build this library, clearly it was intended to be used. No where did i find any documentation on how to build these things. The as3awss3lib had more files than as3awss3lib, but still there was no clear path as to what to do with it. Adobe has spent millions of dollars on documentation, help, blogs, building libraries, and trying to create a community around their platform, and I couldn’t figure out how to use a simple library to add to my code?

I think a lot of it comes down to assumptions. People in flash/flex are mostly focused on user facing eye candy and not on the underlying libraries. There isn’t a lot of discussion about the libraries or the work which goes in to them. Many apps are build and left running as they are. They aren’t things which are maintained and run over time with updates.

Eventually i tracked down what i needed to do. It is assumed that although the repositories are called libraries, the thing you want to do is compile them in to swc files. You can’t just include other people’s code as libraries in to your own code tree, you’ve got to compile them. These compiled libraries and ‘assets’ (i guess you can have a ‘library’ of non-code things like images) are called swc files. These files need to be compiled and included in your application, before and separate from the build process for your own code. Again this is a little java like. Not necessarily wrong, but quite different from how most dynamic languages work. ActionScript is a dynamic language, somebody at Adobe clearly fell in love with java as the way enterprise professionals do things, and added some clunky extra steps to the process.

So now that we know that you can’t just include code in the lib directory of your app and have it be available to your app at run time. This is a big leap. It’s part of why i’ve found nobody who understood my questions. Once i made the leap then it was pretty easy to figure out that i needed to use ant to build the app i tried running ant and got errors. A command line utility and errors, that’s something i can debug! To run ant you simply cd to the build directory and type ant.

bas1:~/code/as3corelib-read-only/build rabble$ ant
Buildfile: build.xml

properties:

lib:

BUILD FAILED
/Users/rabble/code/as3corelib-read-only/build/build.xml:63: 
  Execute failed: java.io.IOException:
  C:/Program Files/Adobe/Flex Builder 2 Plug-in/Flex SDK 2/bin/compc.exe: not found

Total time: 0 seconds

This brings me to my other issue which i find so surreal about the Flash / Flex / Adobe world. It’s a windows world, everybody else is an after thought. It’s full of arcane paths, and executables have their own funny little suffixes so that the OS can figure out that they are executable. In the unix world, which includes linux, bsd, cygwin on windows, and of course mac os x, there are standard conventions for figuring out the paths to libraries, executables, etc…

Ant didn’t seem to like spaces in file names so i fixed that, but then there was still a big problem.

## Change this:
# The location of the Flex 2 SDK on your sytem.
flex2sdk.bin.dir = C:/Program Files/Adobe/Flex Builder 2 Plug-in/Flex SDK 2/bin
flex2sdk.lib.dir = C:/Program Files/Adobe/Flex Builder 2 Plug-in/Flex SDK 2/frameworks/libs

## To this:
# The location of the Flex 2 SDK on your sytem.
flex2sdk.bin.dir = /Applications/Adobe_Flex_Builder_3/sdks/3.0.0/bin
flex2sdk.lib.dir = /Applications/Adobe_Flex_Builder_3/sdks/3.0.0/lib

And and now ant gets a little farther down the path of working.

bas1:~/code/as3corelib-read-only/build rabble$ ant
Buildfile: build.xml

properties:

lib:
     [exec] /Applications/Adobe_Flex_Builder_3/sdks/3.0.0/bin/compc.exe: 
     /Applications/Adobe_Flex_Builder_3/sdks/3.0.0/bin/compc.exe: cannot execute binary file
     [exec] Result: 126

BUILD SUCCESSFUL
Total time: 0 seconds

Don’t let the BUILD SUCCESSFUL message trick you! It didn’t actually work. This time it found compc.exe but as you’d expect, this is a mac, and on mac (and it’s unix cousins) exe files don’t run. At first i thought maybe Adobe was doing some craziness where they just decided to make all the executables on every platform .exe. Turns out that wasn’t the case, setting the executable flag didn’t help. What adobe does is include a separate file, sans .exe, which is the version of that app for normal operating systems. So it requires another change to the build.properties file.

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

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

Again if it wasn’t assumed that these libraries would be built in a mono-platform windows only world, then the ant build.xml file would be written in such a way to look in the obvious places. Once everything is in place, then ant works!

bas1:~/code/as3corelib-read-only/build rabble$ ant
Buildfile: build.xml
</p><p>
properties:
</p><p>
lib:
     [exec] Loading configuration file /Applications/Adobe_Flex_Builder_3/sdks/3.0.0/frameworks/flex-config.xml
     [exec] /Users/rabble/code/as3corelib-read-only/bin/corelib.swc (79242 bytes)
</p><p>
BUILD SUCCESSFUL
Total time: 7 seconds

As far as i can tell, the ./libs/ directory is a good place to put these kinds of libraries. Presumably they get bundled in to your application you build an air / flash swf for distribution. I haven’t gotten that far yet. If i stay motivated and keep moving forward with this project, i’ll keep blogging my way through this mess. I am tempted by the shiny bobble of pretty and small cross platform GUI desktop apps which lies on the other end of this journey.

It appears that some libraries need to be compiled, like corelib, while others, the as3awss3lib can just be dropped in the src directory with their full path, ./com/adobe/webapis/awss3 What’s not clear is why it’s one way or another.


About this entry