December 17, 2008

Debugging an Open Social application built with Adobe Flex

During my last work week of this year, I got involved in a fun little project where an OpenSocial Widget is developed. This particular widget is targeted at the Dutch Hyves communities. Hyves supports the OpenSocial standard version 0.7.

The widget itself mostly consists of an Adobe Flex 3 application that is embedded in an OpenSocial container using a flash-javascript bridge. The Flex application makes asynchronous calls to the OpenSocial API of Hyves through the javascript bridge.

Hyves users can add this widget to their profile and configure it to point to a charity activity that is initiated by this user. Friends of that user that donate money to support that charity activity are also displayed by the widget, including the total amount of funding that was donated.
All in all a very nice use case for a social application.

The widget was, of course, developed in very little time (remember this is charity...). The code looks awful, but that is okay, because maintenance isn't an issue. It is disposable software. However, because of the extremely pragmatic approach, some nasty bugs creeped in for which I could really use some sort of debugging mechanism. I needed to be able to look inside during runtime.

Fortunately, Hyves provides a sandbox environment that simulates embedding in a real environment. This is where you can test drive widgets that you develop. Of course, I could run and debug the flex application locally, but accessing the OpenSocial API is then meaningless, because you are outside the Hyves context. And, sure, I could possibly produce a debug version of the widget, embed it in the sandbox and connect the Flex Debugger to the application once it runs in the container, but I somehow couldn't get that to work.

That's why I desparately decided to build a mini log console. Since I see no point in keeping that to myself or my employer, I am sharing that thingy with you. It came in really useful to me. I could look under the hood while the app was running and see what was wrong. Purpose fulfilled.

The picture below shows the logger in action:


The mini logger consists of two parts:

  1. Logger.as
  2. LoggerPanel.mxml
Logger.as provides the main interface for writing log messages. It implements a singleton class that has two functions: clear(), and logMessage(message:String), and a public, bindable property logText.

LoggerPanel.mxml displays the contents of Logger.instance.logText, and provides a clear button.

Below I have attempted to display the source code for all this in a somewhat decent fashion. I couldn't get the layout like I wanted it. I hope you will forgive me for that.

Here's the source code for Logger.as:

package components.logger
{
public class Logger
{
[Bindable]public var logText:String = "";

public function clear(): void {
logText = "";
}

public function logMessage(message:String): void {
var now:Date = new Date();
var timestamp:String = "["
+ now.getFullYear() + "/" + now.getMonth() + "/" + now.getDay() + " "
+ now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds()
+ ":" + now.getMilliseconds() + "] ";
var newText:String = logText + timestamp + message + "\r";
logText = newText;
}

private static var _instance:Logger = null;

public static function get instance(): Logger {
if (_instance == null) {
_instance = new Logger();
}
return _instance;
}

public function Logger() {
}
}
}


Here's the source code for LoggerPanel.mxml:


<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="400" height="300" alpha="0.95" initialize="init();">
<mx:Script>
<![CDATA[< logger =" Logger.instance;" id="console" height="100%" width="100%" text="{logger.logText}" label="clear" click="logger.clear()" height="20">


Here's how you use it in your code:


<mx:application mx="http://www.adobe.com/2006/mxml" logger="components.logger.*">

<mx:script>
<!--[CDATA[ import components.logger.Logger; function doSomething(): void { Logger.instance.logMessage("I got here"); } ]]-->
</mx:script>

<!-- ... your components... -->

<!-- Embedding the LoggerPanel. You will need to tweak the position and size for ypour application: -->

<logger:loggerpanel visible="{loggerVisible}" id="logger" top="0" left="0" height="350" width="100%">

<mx:button height="20" top="330" right="0" label="{loggerVisible ? 'hide debug log' : 'show debug log'}" click="toggleLogger();">

<!-- End of LoggerPanel embedding -->

</mx:button></logger:loggerpanel></mx:application>


Use it to your advantage.

2 comments:

Nel said...

Hi

ik las je reactie op m'n weblog. Leuk eens een onbekende lezer terug te vinden.

Over je vraag :
Ik ben heel tevreden over m'n crockpot. Eerst een kleinere gehad die goed functioneerde tot hij kapotviel. Meteen weer een nieuwe besteld en ook hier weer prima resultaten.
Zeker als je veel eters krijgt en je hebt maar één fornuis, dan is het superhandig zo'n extra pot. Vooral met veel stoofvlees en frietjes erbij.

V.w.b.service, bestellen en binnen een paar dagen leveren. Geen gedoe, gewoon via het net besteld, betaald en ontvangen.

ronbo said...

Hi Mark,

I thought you might be interested in checking out Skyway Builder. It’s an Eclipse-based, code generation tool for developing Java apps. Builder is open source and can be downloaded from the community website, www.skywayperspectives.org.

If you have a chance to download Builder, I would be very interested in getting your thoughts/feedback on its capabilities.

Regards,
Ron