December 08, 2010

How a Flash bug breaks the professional software-release process

This article 1) describes how a Flash bug breaks the professional software-release process, and 2) entreats Adobe to fix said bug.

THE BUG: When a linked class or the document class resides in a .swc file, the Flash authoring tool can't find it, and generates an error.

At MegaPhone Labs, we separate our applications into two parts: the engine .swf (core logic) and the skin .swf (display). We create the engine .swf in Flash Builder, but we want designers to be able to easily rebrand apps, so we generate the skin .swf from a .fla file in Flash authoring. Each visual element in the app is defined as a separate MovieClip symbol in the .fla. The engine controls display by loading the skin .swf at runtime, and instantiating symbols from the .fla. The separation of skin and engine has the following benefits:

  • Lets the engine developer and designer work simultaneously on the same application
  • Makes it easier to manage many different skins for one app
  • Lets us change skins at runtime
  • Lets us test and debug the skin and engine independently
  • Lets us version-control the skin and engine independently
  • Lets us freeze a single engine binary while still changing graphics
  • Keeps code away from people doing skinning

In some cases, we need to add effects code to the skin .swf. For the purposes of version control and IDE comfort, we add effects code by defining external classes, and linking them to symbols in the .fla file.

Linked Classes

For example, for a trivia app, we might have "triviaengine.swf" (the engine), "plainskin.swf" (a skin with no code), and "flamingskin.swf" (a skin with effects code in linked classes).

Now suppose a customer, say NBC, asks us to add corporate branding to flamingskin.swf. To add the branding, the designer needs both flamingskin.fla and the linked classes. We could give the designer the linked classes in the form of raw source code (.as files). But that would be a bad idea because:

  • We have tested the flaming skin's classes exhaustively, and we don't want to risk re-compiling those classes when creating nbcflamingskin.fla
  • We don't want to expose raw source code (.as files) to the designer, who might accidentally break it or be tempted to change it
  • We don't want the designer to waste time re-compiling the linked classes when exporting nbcflamingskin.swf.

Instead of giving the designer raw source files, we want to give the designer a single precompiled .swc file, flamingskin.swc, which contains the linked classes. That way, the classes will be safely tested, version controlled, and zipped. And we want to generate flamingskin.swc via compc, not Flash authoring, as part of an automated build process.

Great idea, but due to a bug in Flash authoring (verified up to CS5), it doesn't work. When a linked class or the document class resides in a .swc file, the Flash authoring tool can't find it, and generates the error "A definition for this class could not be found in the classpath, so one will be automatically generated in the SWF file upon export."

Definition Not Found

There are some workarounds:

  • Make a dummy class that extends the linked class, and link the dummy class
  • Generate the linked classes as components in Flash authoring, as follows: 1) create a symbol, 2) list the classes as statements of the symbol's first frame script, 3) choose Export SWC File from the symbol's library context menu, 4) use that .swc as a component in the destination .fla (i.e., add it to the .fla's library)
  • Peter Hall's workaround: Force the Flash authoring tool automatically generate the linked classes by intentionally *not* including the linked classes in the .fla's classpath. Then, before the app loads the skin, have it load a separate .swf containing the skin's linked classes. Be sure that both the .swf containing the linked classes and the skin .swf are loaded into the same application domain. Thus, when the skin loads, its auto-generated classes will be ignored because classes by the same name will have already been defined by the .swf containing the linked classes. Flash Player will, hence, use the linked classes instead of the auto-generated classes. This workaround is appealing because it prevents the designer from tampering with the linked-class code, and completely removes the need to provide the designer with a .swc file at all. However, this workaround also adds a layer of complexity (the additional "skin classes" .swf file) to the application.
  • Andreas Heim's workaround: Change the linked class name to "SomeClassBase", then set the symbol linkage's Base Class to "SomeClassBase" and Class to "SomeClass". In this configuration, the Flash authoring tool will be able to find SomeClassBase, and will successfully auto-generate SomeClass. However, if there are named instances in the symbol, they will always be declared as variables in SomeClass, and those variables will conflict with any variables of the same name in SomeClassBase, making it impossible to control stage instances from SomeClassBase. The required "classNameBase" naming convention is also unpleasant.

In our workflow, none of the preceding workarounds are worth the production effort and maintenance risks. So we are stuck giving raw source files to designers, which invalidates our testing, and adds significant risk to our software release process.

I would like to appeal to Adobe to fix this bug, and give us the tools to release products using practices befitting a professional software company. MegaPhone software is used by millions of people on television and in stadiums. We simply can't afford the risk imposed by this bug.

Thank you to Flash engineers Rebecca Sun and Jeff Kamerer for confirming this issue and providing its workarounds.

Posted by moock at 07:13 PM | Comments (0)