Declarations, Logic, and Macros in Class Definitions

While nearly every current programming language has classes and objects, they have some radically different ideas about how one goes about defining classes.

In strongly-typed languages like C++ and Java, classes are declared. This means compilers (and other tools) have essentially complete information about the class during compilation, which in turn allows for certain classes of errors to be found and various optimizations to be applied. It can also be convenient for developers, in that it’s fairly straightforward to read declarative syntax and understand its meaning.

In script-oriented languages like JavaScript and Ruby, classes are defined by executing program logic at runtime. This is a powerful approach in that it may be much simpler to write a program to generate a given definition than to create the declarative version of it. On the other hand, it can defeat the application of analysis at compile time: some analysis can typically still be performed, but short of executing the class definition logic, it is impossible to fully analyze it.

Macros, such as those implemented by the C preprocessor, provide an interesting balance between the two approaches. The result of the macros is a class declaration, and it’s the declaration that’s available to the compiler. However, the macros can simplify class declarations by providing for generation of those declarations when the preprocessor executes. This is frequently used, for example, to generate declarations for class members that are used repeatedly across a set of (related) classes.

C++ provides another take in this space via its template facility. Unlike the generics capability in Java, C++ templates are themselves programs that are executed by the compiler at compilation time, and resulting typically in new class declarations. (This is referred to as “template metaprogramming.”) It’s an odd sort of programming language based primarily on recursively matching type patterns, but it’s still a programming language.

None of these techniques is necessarily better than another, but they certainly provide a different set of tradeoffs. With a more comprehensive view of the various approaches, one can hopefully be more effective in leveraging the strengths of whatever language is in use.



As part of this week’s restructuring at Adobe, I’m moving to a new role on the Creative Cloud team. Thank you to everyone who has followed my ramblings here on various things AIR-related. While I don’t plan to continue to post further on AIR, I do plan to write about various things Creative Cloud-related as the project moves forward. I hope you’ll consider continuing to read.

Oliver Goldman

AIR Native Extensions, ByteArray, and BitmapData

[Note: Updated on October 11, 2011 to note that multiple ByteArrays or BitmapDatas can be acquired at the same time in the AIR 3 implementation. —Oliver]

The new-to-AIR 3 native extensions capability includes not only a general-purpose API for manipulating ActionScript objects from native code, but also fast-path APIs that allow direct access to ByteArray and BitmapData objects.

Using these APIs, native code can get direct access to the memory that sits behind a ByteArray or BitmapData—no copies, no translations. In order to achieve that, native applications have to declare when they want access via an acquire call, and when they’re done via a release. In between the two, we restrict access to the rest of the API in order to guarantee the pointer that’s returned remains valid.

Furthermore, it’s possible to acquire two or more byte arrays or bitmaps at the same time so long as there no intervening calls to the rest of the API. This can be used, for example, to take image as an input for a filter and write directly to a second as the output.

As always, if you have ideas for enhancements to this and other features, you can vote for them at

See the Native Extensions documentation for more on working with ByteArray and working with BitmapData.

MAX 2011 Follow-up

Thanks to all of you who attended my MAX talks earlier this week! I had a great time presenting, and always enjoy the chance to meet people in person.

Slides and video of my Adobe MAX 2011 presentations are now available online. The two talks are largely the same, with some mobile- versus desktop-specific details appearing in the last 15 minutes or so of each.

How to Extend Your Mobile AIR Applications Using Native Extensions: video on Adobe TV, and slides on

How to Extend Your Desktop AIR Applications Using Native Extensions: video on Adobe TV, and slides on


New Installation and Deployment Options in AIR 3

It is with great pleasure (and a little bit of relief) that I report that AIR 3 will deliver new and much improved installation and deployment options for the desktop. These options enable installation without administrative rights, GPO-based deployment of AIR applications, XCOPY deployment, run-in-place from flash drives, tight binding to specific versions of AIR, and more.

These advantages arise from two new key capabilities:

  1. Captive runtimes. Already used on iOS, this capability allows a copy of the AIR runtime to be embedded with each AIR application. This capability is now supported across Mac OS, Windows, and Android, too.
  2. Custom installers. The application packaging tool, adt, can now be used to generate an application’s file set instead of a complete installer. The file set is a complete copy of the application, capable of being run in place. Or, you can package it up in your own custom installer, whether that’s an MSI for GPO, a PKG for Mac OS, or something else.
For a more comprehensive overview, please see Installation and Deployment Options in AIR 3 on the Adobe Developer Connection.

AIR Native Extensions Samples Available

In conjunction with today’s announcement of AIR 3, we have now posted a Native Extensions for Adobe AIR page on the Adobe Developer Connection. It currently lists four extensions available for download from both Adobe and our developer community. We’ll post more here as they become available.

And, a reminder that there’s still time to register for Adobe MAX 2011. It’s a great place to find out about all of the new AIR 3 and Flash Player 11 features, including native extensions.


Disabling AIR Certificate Revocation Checks During Silent Install

Here’s a quick tip that doesn’t seem to be covered in the administrator’s guide for AIR, although it likely should be: You can control how revocation checks are performed during silent installs via the -revocationCheck flag.

When digital signatures are validated, one step in the process involves checking to see if the certificate used to sign has been revoked. This is how certification authorities defend against stolen certificates: they revoke stolen certificates by publishing them in a revocation list; software that validates signatures then checks those lists.

Revocation lists are published to web servers at URLs embedded in the certificates themselves. In order to check the lists, they need to be downloaded. This gives rise to a number of potential questions, like what to do when you are offline and can’t download the latest version. One needs to make a policy decision to answer such questions.

The -revocationCheck flag accepts four values, one for each supported policy:

  • never Don’t check the list, period. No network requests will be issued. (More on this below.)
  • bestEffort Look for a revocation list, but if something goes wrong other than the certificate being revoked, proceed on the assumption that everything is ok.
  • requiredIfInfoAvailable Assuming you can fetch the revocation list, then fail if any later errors occur. But if you can’t download the list at all, proceed as for bestEffort.
  • alwaysRequired If the revocation list can’t be checked without error, don’t proceed.

AIR defaults to “bestEffort”. That’s typically a reasonable choice, and it has the advantage of working both online and offline. But it does mean that for most installations, the AIR installer will at least attempt to issue a network request to download the list. (Lists are also cached, so you won’t always see the request, however.)

Now, there’s one particular case where “never” is a handy setting: Silent installation behind an HTTP proxy that requires authentication. In this situation, so long as AIR issues a network request, the OS will typically pop up a proxy authentication dialog, which of course halts the installation flow and requires manual intervention. To work around it, simply add “-revocationCheck never” to your command line arguments.

The Unique ID Situation & iOS

I’ve written earlier to explain that AIR doesn’t include a device identifier API because it doesn’t have a useable definition across platforms. (Also, it can be easily replaced for most use cases with a random identifier generated by the app.)

Now comes news that this capability is becoming even less implementable: Apple is deprecating their own UDID API. TechCrunch has the story at

Math.random() is your friend.

Social Algorithm

if( message.length <= 140 && message.isPublic ) {
    Twitter.tweet( message.text );
} else if( message.isPublic ) {
    if( !intersection( message.recipients, Contacts.facebookOnlyUsers ).isEmpty ) {
        FaceBook.setStatus( message.text );
    } else {
        GooglePlus.share( message.text, GooglePlus.PUBLIC );
} else {
    circles = GooglePlusUtilities.computeRelevantCircles( message.recipients );
    GooglePlus.share( message.text, circles );

Using a Cross-Platform Runtime to Build Better Apps

The inherent advantage of using a cross-platform runtime, such as AIR, to develop applications is typically understood to be the boost in productivity that’s achieved by reducing the amount of per-platform work that’s required. While it’s true this is a potential advantage, it’s generally discussed with an implicit assumption that the developer is interested in reducing the development cost.

Suppose, for moment, that this is not the case. If you spend just as much on development as you did before and use a cross-platform runtime, then what happens? You build better apps.

The key is to take all the time you saving writing code once and apply the savings elsewhere in your application. That could be to additional features. Or it could be a better experience: improved responsiveness, more intuitive UI, lower memory use. No matter how you spend this savings, you build a better app.