Tuesday 9 December 2008

Signing Adobe AIR files with Authenticode Certificates

There are some things that always seem a little trickier than they should be. Renting an apartment in London that has working heating and hot water is one of them, converting an Authenticode certificate from SPC and PVK files to a format that you can sign Adobe AIR files with is another.

Since I still haven't figured out the former, I'm going to write about the latter.

First things first, if you're going to get a certificate solely for signing AIR files, then buy one from Verisign or Thawte specifically for AIR. It's just easier.

If, however, you want to use your certificate to sign .NET applications as well, then get a Microsoft Authenticode certificate. You can use that certificate to sign AIR apps and well as .NET apps. We got our Authenticode certificate from Verisign, but there are other vendors. If this is what works for you, then the following might be helpful. If you have haven't already done so, go away and buy the certificate now - I'll see you again when you have downloaded a PVK file and an SPC file.

So, let's skip forward a few days. You've got your PVK file (the private key), and the SPC file. You're probably wondering how to turn those files in to a PFX file that you can use with ADT to sign files. Hopefully, these steps should help. Oh, I'm assuming that you're using a PC here...

Firstly, you need to ask yourself two questions:

  1. Do you feel lucky?

  2. Can you find a tool called pvk2pfx on your machine. This is a pain to get hold of, but lives in bin directory of most Microsoft SDKs.

If you're lucky AND you can find pvk2pfx, then skip forward a little. If you can't find it, then read on.


I don't have pvk2pfx, I need something else


Worry not, this is still completely possible...

  1. Get a tool called pvkimprt. You can download it from Microsoft. Run the self extracting whatsit, then run the installer, and make a note of its final resting place.

  2. Open up a commmand prompt (Start, Run, "cmd").

  3. Change to the directory where pvkimprt ended up.

  4. Run:
    pvkimprt -PFX <path\to\cert.spc> <path\to\key.pvk>

  5. Choose the following options:

    Choose to export the private key...

    Choose the PFX format, choosing to include certificate chain and use strong protection.

    Choose a password...

    Select a location to save the pfx file

    This is what success looks like...

  6. You can use the resulting pfx file to sign an Adobe AIR file with adt.


You're done! You might want to ignore the rest of this post, it will make you wish you were luckier. Any questions/mistakes/omissions, feel free to ask...

I'm lucky, I have pvk2pfx

This is much easier. Simply:

  1. Open up a commmand prompt (Start, Run, "cmd")

  2. Change to directory where you found pvk2pfx.

  3. Run:
    pvk2pfx -pvk <path\to\key.pvk> -pi <pvk password> -spc <path\to\cert.spc> -pfx <path\to\output.pfx> -po <new password for pfx file> (all on one line)

  4. You can use the resulting pfx file to sign an Adobe AIR file with adt.



I hope that was helpful!

Thursday 4 December 2008

The Anatomy of a Seriously Sophisticated AIR Application

As promised, I've uploaded the slides that Rick Williams and I presented at Adobe MAX Milan on December 2nd 2008. Enjoy!

Tuesday 2 December 2008

Thanks to all those who came to see us talk...

Just a quick note to say thanks to all the folks that came to see Rick and I present "The Anatomy of a Sophisticated Air Application" at Adobe MAX in Milan. It was also great to speak to so many people who loved Fiat eco:Drive.

We will the get the slides up ASAP. Over the next few weeks, I'll blog about some of the topics we covered in a bit more detail - leave a comment if there is something specific you would like to know about.

Thanks!

Friday 14 November 2008

The kind of waterfall development I like...

The process cynic in me says you don't often hear the words "waterfall" and "innovation" in the same sentence... This, however, is an exception.

Tuesday 11 November 2008

Web Sequence Diagrams: It doesn't get any more exciting than this...

Ok, a slight exaggeration. You might even accuse me of lying, but I find this pretty damn cool.

Last year I stumbled upon an ingenious tool - Web Sequence Diagrams. By using a markup language, you can draw sequence diagrams without the fuss of Visio, or even Gliffy.

A day in the life of a builder, sequence diagram style...


In just a couple of hours, you can be in diagram heaven. You could flood your desktop with exported versions of the diagrams. You could fill your office with print outs (but consider the environment kids). But there was something missing. There just wasn't an easy way to store them in their raw text format, and view the results... The tool was SCREAMING out for a wiki plugin.

So, I set about writing one. And got no further. Life, well actually work, intervened, as usual.

But fear not (for I know you are trembling with fear and anticipation), others have come to the rescue with a plugin for Confluence and a plugin for the rather wonderful Trac. On top of all this, you can also find a whole set of example scripts for Python, Java, and Ruby. Apparently, you can even render inline markup by using a bit of JavaScript magic, but I haven't quite got that working yet...

Genius.

Friday 7 November 2008

A prediction about projection...

This morning, news about a tiny projector dropped into my inbox.

To summarise, this is a battery powered projector, perfect for showing movies from your ipod. Great. The author of that article got it right, this is game changing stuff. Very cool.

But I think it is bigger than that.

You see, when the MP3 format first came on the scene, the people rejoiced. "Woo", said Bob, "I can burn a CD with 200 songs". "Amazing", said Esmeralda, "I can FTP this song in just 1 hour!". "Holy crap!", said Justin, "I can make a fortune out of writing a media player". No one (that I knew) said: "Wow, in just a few years we'll have changed the way we listen to music. Oh, it'll be much prettier too." Very few really saw the true potential of this breakthrough. And I think the same is true here.

Right now, we're using desktops and laptops as much as ever. Sure we're using mobiles to access the web, but we're not using them as a replacement. We use them where we wouldn't use a regular computer. With a few improvements, we'll start to see these small projectors converge with mobile devices. Add to the mix the inevitable rise in processing power, and a new breed of device will start to replace the desktop computer, and indeed the laptop. We'll be able to forget about the small screen, and use a projected larger one. Add a futuristic input mechanism, and you'll have a pocket powerhouse.

I'm guessing this is why Google never bothered trying to make a desktop operating system - mobile will be the new desktop.

Tuesday 28 October 2008

A belated first post...

There seem to be a few questions to answer before actually starting a blog. What will the content be? How often will I post? How will I start it? When will I stop procrastinating and actually do it?

This sentence answers all those questions in one - (see below; whenever something substantial falls out of my brain; with a random post; a few posts ago)

With the realisation that a blog that has a shaky start is better than no blog at all, it's time to get this thing off the ground. First let me introduce myself. My name is Adam Creeger. I work as a "Technical Architect" for AKQA London, a leading light in the murky world of Digital Advertising. They used to call themselves an interactive marketing shop, but I guess the advertising industry shifted itself our way, and swallowed us up in the process.

What is a Technical Architect at an ad agency? Good question. I get to spend most of my time designing (think UML - not crayons), mentoring, experimenting, talking to the people that pay the bills and occasionally coding. Somewhere amongst this I get to observe - and even influence - the running of some pretty intense projects. Pushing boundaries under tight timeline pressures with challenging resourcing issues makes for an interesting day.

Traditionally (7 years professionally), I've been devoted to the art of .NET and all things Microsoft, especially C#/ASP.NET. These days though, I've broadened my horizons to include RIAs (Flex, AIR, WPF, and of course the AJAX/DHTML combo), functional languages and the fall and rise of the dynamic language (including Powershell). At the end of last year, I stepped back in time and did some award winning, brain-taxing work (transitive closures, anyone?) in Actionscript 2. Learning a new language is always fun, but having to do without all the goodness of C# (au revoir Typed Arrays, Generics, Run time type checking to name a few) makes it well, let's just say, intriguing. Right now I'm recovering from giving birth to Fiat eco:Drive - one heck of an AIR project. Most importantly though, I get to work with some inspirational people who astound me with their passion for this game.

I'm going to write about all these things. There's plenty of room for discussion on all fronts, but I imagine I'll spend a fair amount of time on the art of software development itself. What makes for a successful project? Why do smart programmers fail to produce applications that work? Why are project management techniques so hit and miss? How do you ensure teams in different time zones get along just fine? These questions have been answered before, but perhaps not from the inside of an advertising agency where the projects are many and the risks, rewards and pressures are high. There'll be a few tech-heavy posts too, stuff I discover along the way etc etc. Whatever happens, I'm sure this will evolve into something beyond what I imagined in this paragraph.


Thank you, and good night.

Thursday 28 August 2008

Logging in Flex/Air: Filters behaving badly...

I'm a firm believer in diagnostics - in .NET land I just can't live without log4net. The mx.logging.* namespace in Flex 3 appears to give us some similar functionality (I'm talking about restricting loggers to certain "categories" here) but without the lovely configuration framework of log4net.

In an app we're writing at the moment, I was seeing some wierd behaviour. Basically, the logging targets were just not obeying their filters, meaning every message was getting written everywhere. Not good. At all.

So I did some digging and found two things that surprised me:

1. Setting a level on a target will call Log.addTarget() - probably prematurely


When stepping through the source code of the Flex logging framework, I found this bit of code in AbstractTarget:

public function set level(value:int):void
{
// A change of level may impact
// the target level for Log.
Log.removeTarget(this);
_level = value;
Log.addTarget(this);
}

This highlighted line is the culprit. The contents of the addTarget method set up logging restrictions based on the value of the filters array. This has two consequences. Firstly, if you follow Adobe's guidelines you'll end up running through the addTarget code twice, once when you set the level, and once when you actually call Log.addTarget yourself - not awful, but not great either - lots of loops, which gets bad when you've got a lot of Loggers.

The other consequence was the cause of my pain...

2. You have to set your filters before you set your level


Yep. That's right, the following code is bad:
//BAD CODE, DON'T USE
var target : TraceTarget = new TraceTarget();
target.level = level; //This should not come first.
target.filters = filters; //This is pretty much ignored

Here's why:
  1. The default value of target.filters is ["*"], which will means the target listens to log messages from every logger.
  2. When you set target.level, Log.addTarget is called, and all the filter magic happens. Except that you haven't set the filters yet. So it uses the default value ["*"], and your filter listens to everything. This was what was happening in our code.
So, the correct code should be:
var target : TraceTarget = new TraceTarget();
target.filters = [com.mydomain.myproject.MyClass,mx.rpc.*]; //Set first
target.level = level; // set second.

In this example, a TraceTarget is created which will only listen to Loggers that have a category that is equal to "com.mydomain.myproject.MyClass" or begins with "mx.rpc". It is not at all obvious, but you the above code will also start Logging, as setting target.level also calls Log.addTarget().

The observant among you may have noticed that if Adobe improve the behaviour of setting target.level in the future, you may find that your logging stops because addTarget never gets called. If you're worried about that, you can do the following:
var target : TraceTarget = new TraceTarget();
target.filters = [com.mydomain.myproject.MyClass,mx.rpc.*];
Log.addTarget(target); //honours the filters
// setting target.level will
// remove the target, then add it again.
target.level = level;
Still inefficient, but at least it is future proof. I hope that helps somebody, somewhere...

Friday 25 July 2008

Ballmer gets that search thing wrong...

Microsoft are rather obviously obsessed with getting their search revenues up. That's no surprise - pretty much everyone knows about their [twice] failed Yahoo bid. Then there is their cashback offer, and now the announcement of a plan to provide search facilities (and therefore advertising revenue) on Facebook. It makes sense. Search is big business.

It seems, however, that Steve Ballmer has forgotten why people actually use search engines. Apparently he thinks that:

"advertisers don’t want to sell on Live Search unless there’s more people using the site, and people don’t want to search on the site unless there are more relevant ads."
Source: CNN
Oh dear.

Surely Ballmer cannot believe that Google's near domination of the global search market was down to relevant ads? Can he? That would make him slightly crazy...

Tuesday 15 July 2008

OutOfMemoryError while using mxmlc and ant

My first blog post. Very practical too...

Basically, I'm working on a fancy Adobe AIR app right now. As part of that, we are implementing an automated build process using CruiseControl and such. I'm using ant, and the flexTasks provided by Adobe. All was going pretty well, until this happened:
[mxmlc] Loading configuration file C:\Program Files\Adobe\Flex3SDK\frameworks\air-config.xml
[mxmlc] Error: null
[mxmlc]
[mxmlc] java.lang.OutOfMemoryError

After a bit of googling, there was no obvious solution. I did see mentions of setting the ANT_OPTS environment variable. So this is what I did (I'm running Windows Server 2003 btw...):

  1. Hit Windows-Break to open the "System Properties" dialog.
  2. Go to the advanced tab.
  3. Click "environment variables"
  4. In the System variables section, click New.
  5. Enter the variable name as ANT_OPTS, and the value as -Xmx512m.
  6. Click "OK".
If you were using a command prompt, you'll need to close it down and re-open it to use the new settings. Try running your ant script again, and your error should be gone.

You can find a much nicer visualisation of that process here. If you are on a UNIX box, then you'll need to:
set ANT_OPTS=-Xmx512M; export ANT_OPTS
from the shell.

If you want to know more, you should read about the Java virtual machine's memory tuning options. I couldn't find any documentation about the ANT_OPTS environment variable.