Augmenting the evolving API
Recently I’ve been confronted with some collective distaste of my in-house framework’s api. It’s been enlightening learning how my original design is failing to meet the needs of the small (but growing) developer community. Like any API, mine prescribes a set of types which are, via the associated framework, injected into developer-provided “components” at run-time. Behind these types are of course, concrete implementations, and in one particular case, instances of MDIWindow of the popular Flexlib library. So the specific problem that folks are running into is that these APIs are a tad too generic. As a project owner, I have to provide regular release cycles, and as a result, changes/enhancements to the api need to applied to scheduled releases. That is to say, if 90% of the developer community is screaming for a “public woobie():void” on the API, it can’t just be slapped on, it has to be implemented during the course of our normal sprint cycle. And after reading the landmark work of 37 signals, Getting Real, I tend to look at adding functionality like adopting children.
But it’s all good. ActionScript (like its cousin JavaScript) allows for the “targeting” of fields.
Consider the following..
public class ThirdPartyThing{
public function woobie():void{...}
}
public interface IMyApiThing{
function someApiMethod():void;
}
public class MyThing extends ThirdPartyThing implements IMyApiThing{
public function someApiMethod():void{...}
}
And then, any client of IMyApiThing can access the “formal” API via instanceOfIMyApiThing.someApiMethod();
or the informal API via instanceOfIMyApiThing["woobie"]();
I understand how that actually kinda sucks. Ideally, an API exposes the correct interface. But in reality, living things evolve. The API of a thing is collectively designed by the community that uses (and curses) it. This post is mostly about the relevance of “targeting” as a mechanism to derive and evolve an API. My view is that every time a user targets a field not exposed by the API, it’s a cue to consider adopting that targeted field as a 1st class citizen. And for that reason, I’ve been encouraging people to target-away – but just let me know about it so that the gorilla tactics of targeting can inform the design of a relevant API.
What happened to the MovieClip?
Flash development is fun…at least, it’s supposed to be. Think about it – why is Flash “Flash?” How did it become “Flash?” It’s because legions of digital artists loved making their designs come to life, loved what a simple little plugin could do within the browser. Before the JavaScript revolution, before HTML5 and the anti-plugin revolution, it was about artists making sht move. “Flash” was born during the time of Real Player, and Netscape, and IE 4. Go back to tweened insanity in Flash 4 and you’ll see innovation, Flash developers duplicating MoveClips and enter-framing their way into animated oblivion. Follow things a few more years and you’ll see the 2 frame Flash movie becoming the standard. Then Flex, the component framework, the development paradigm that would take Flash into the enterprise. But what happened to the MovieClip?
During the day I am responsible for the evolution of an in-house Flex application framework focused on the integration of Flex applications across domain boundaries. As have most Flex developers, I found myself, and my framework, in the middle of a Flex 4 migration. Fortunately I have some talented developers on my team, so migration to Flex 4 was pretty much, a non-issue.
But lately I have been rethinking a few things “Flex.” And truthfully, this reevaluation started at 360|Flex in San Jose, where I first encountered Reflex, a component framework that remembered the the MovieClip, more specifically, the Sprite, but the point is, the lower level goodness of the Flash platform. There has been a lot of discussion around the restructuring of Reflex, specifically Ben’s fork of the codebase and Tyler’s reestablishment of Stealth. In my opinion, it’s a good thing. My hope is that these projects will allow their respective founders to scratch their own itches – work out some details, and then be merged back into a single, and stronger project. But I digress.
What I’m rethinking is the Flex framework itself. Flex 4 is better than Flex 3: I get that. And I’m glad to see Adobe attempting to right some of the wrongs of their component framework. But reading through the code of Minimal Comp’s makes me remember what it felt like to be a Flash developer. Minimal Comps design is refreshingly simple compared to Flex. For example, its invalidation mechanism is about as simple as you can get.
// com.bit101.components.Component
public class Component extends Sprite{
...
// Marks the component to be redrawn on the next frame.
protected function invalidate():void{
addEventListener(Event.ENTER_FRAME, onInvalidate);
}
// Called one frame after invalidate is called.
protected function onInvalidate(event:Event):void{
removeEventListener(Event.ENTER_FRAME, onInvalidate);
draw();
}
// Abstract draw function.
public function draw():void{
dispatchEvent(new Event(Component.DRAW));
}
...
}
And that’s as simple a validation mechanism as you can get! Beautiful. Of course, Minimal Comps is also less flexible but I’m cool with that.
“Who wants to build a custom component out of Sprites for every project?” Well, I think I do actually.
GSkinner’s Quick as a Flash presentation
The always insightful GSkinner just posted another installment of Creating Great Developers, this time focusing on Training. From there I linked to his great presentation Quick as a Flash which discusses Flash performance and optimization. I was really surprised by the stats on several slides. Note that his slides are calculating these stats in real-time, pretty cool.
- use implicit type casting
- bitwise tricks
- callbacks are faster than events for callbacks and dispatch
- class props are slow
- array and vector population
- splicing and deleting – wow, I assumed vector would have been much faster here
- clean your screen
Code Club
So over the weekend a couple of neurons fired as I read through the blog postings of codecraig.
My wife belongs to a couple local area book clubs and in my own secret way, I think I’m kind of jealous. Once a month she heads out to someone’s house, or hosts a meeting at our place. About a dozen ladies come over and drink beer and talk about which ever book they were reading – standard book club stuff. I usually take the kids out for pizza or head over to the playground for a couple hours. Anyway, here’s the noise that I dropped on google buzz.
So I have a proposition…inspired by the blog postings of one codecraig, I propose “Code Club”. Imagine book club but rather than reading books we focus on reading and understanding code… Multiple languages, Multiple open source projects, Anything goes. Maybe bi-weekly, meetup at each other’s offices, coffeeshops, houses, whatever. We follow the standard book club model but focus on the code yall…and the beer. Folks who can’t be there can skype in. Thoughts?
…
Some ideas on format and structure:
Members propose code to read; jquery, flare, groovy’s swing builder, android boot process etc. Group agrees on topic/code. Guidelines for selecting code should be focused on complexity and sloc. The intention is to obtain enough of an understanding about a significant library, feature of a lib (spring’s use of dynamic proxies for example) It will be important to limit the size of the code we are reading so that we can collectively arrive at an in depth understanding of the code within 2 weeks. At the end of the 2 week period we get together to discuss the code, drink some beers, fire up our IDEs in groups of 2-6 and step through the code discussing. Perhaps code club keeps a blog with reading list, schedule and take aways from each 2 week period.
I think that another catalyst for these ramblings was a work encounter I had last Thursday. While working at my client’s office space I was asked to look at some 3rd party code and explain its internals to some people who had never worked with that particular technology. I was a tad nervous because the people who I was to explain it to are some of the most brilliant engineers I’ve encountered. So, it was basically an opportunity for me to shine or to look like a total moron:) So I sat down to the code, a multi-module project spanning all the tiers, with a text editor and half a dozen eyes watching me. Fortunately, my current level of code reading skill was enough for me to dive in and explain things in about 10 minutes – The client was pleased.
So there it is: the value of being able to read and understand code quickly. And of course being able to quickly understand a codebase is job number 1 when you are new to any software development team. I know that I have been guilty in the past of not deep-diving into my project’s code, rather, electing to walk down the hall and ask the guy who has. But that’s a total bitch move and it’s plain old unproductive. Over the years I’ve worked to get myself out of that nasty habit. My hope is that Code Club will be a place where everyone who values good code can learn from one another and super charge their code reading skills.
FlexMojos, Mac OSX and the Stand Alone Flash Player Debugger
I recently struggled with getting a flexmojos-based project to successfully find the stand alone Flash Player Debugger during the testing phase of my build.
Let me say first that on my linux system this was not an issue – I simply placed the flash player executable on my path as flashplayer and FlexMojos was happy to fire it up and run my FlexUnit tests. This was also the case on my Windows machine. But of course, I love my new shinny 17″ PowerBook so finding a solution to the pesky error below became a priority.
[WARNING] [LAUNCHER] Using regular flashplayer tests
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to launch Flash Player. Probably java was not able to find flashplayer.
Make sure flashplayer is available on PATH
or use -DflashPlayer.command=${flashplayer executable}
Read more at: https://docs.sonatype.org/display/FLEXMOJOS/Running+unit+tests
I tried a couple different approaches, stringing together bits and pieces of information from various sources but I eventually arrived at the following configuration.
First, Install the Flash Player Debugger your /Applications directory. Find the Flash Player Debugger in ${FLEX_HOME}/runtimes/player/10.1/mac/Flash Player Debugger.app.zip
Second, utilize the FlexMojo configuration option flashPlayerCommand to configure the mojo so it will look for the Flex Player Debugger on the path as “flashplayer” Feel free to use whatever alias you want here – you’ll reference it in step 3.
<!--My project pom's Flexmojos3.7.1 configuration-->
<flashPlayerCommand>flashplayer</flashPlayerCommand>
Last, from within /Applications/Flash\ Player\ Debugger.app/Contents/MacOS directory, symlink Flash Player Debugger to your decided upon alias (“flashplayer”)
ln -s Flash Player Debugger flashplayer
* I tried just setting Flex Mojo’s flashPlayerCommand option to “Flash Player Debugger” the mojo seemed to ignore that…something to look into that would keep us from having to do #3
* I tried symllinking to FlashPlayerDebugger from an external location that was on my path is ~/mybin/ flashplayer -> /Applications/Flash\ Player\ Debugger.app/Contents/MacOS/Flash\ Player\ Debugger but that resulted in the player not closing to the mojos liking after the test executed.
* Let me know if there is a different approach that you find…something cleaner
GroovyMag and JSMag
I recently joined the editing team over at GroovyMag and JSMag! I’m so excited to have been given the opportunity to contribute to such excellent publications. And along with the opportunity I’ve also been given some digital swag to distribute. So for all you jsmag.com users out there (registration is free for those of you who are not), use the coupon code “oneyear” to get yourself a free issue! Stay tuned for some GroovyMag goodies.
Monstrous list of Maven properties à la groovy recursion
As a silly favor to myself I assembled the following list of maven’s project object model in its dot style syntax. Here’s the groovy script I used to accomplish this. Note the use of groovy’s simple closure recursion. More information on groovy closures is available at JN2515-Closures.
dump={node, path="" ->
node.each{
def item = (path) ? "${path}.${it.name()}" : "${it.name()}"
println item
if(it.children().size() > 0){
dump(it.children(),item)
}
}
}
dump(new XmlSlurper().parse('maven-model.xml')
project
project.modelVersion
project.parent
project.parent.artifactId
project.parent.groupId
project.parent.version
project.parent.relativePath
project.groupId
project.artifactId
project.version
project.packaging
project.name
project.description
project.url
project.inceptionYear
project.organization
project.organization.name
project.organization.url
project.licenses
project.licenses.license
project.licenses.license.name
project.licenses.license.url
project.licenses.license.distribution
project.licenses.license.comments
project.mailingLists
project.mailingLists.mailingList
project.mailingLists.mailingList.name
project.mailingLists.mailingList.subscribe
project.mailingLists.mailingList.unsubscribe
project.mailingLists.mailingList.post
project.mailingLists.mailingList.archive
project.mailingLists.mailingList.otherArchives
project.developers
… You get the point
Google chrome, the Flex Debugger and Linux
Now that the google chrome beta has been released for linux I wanted to investigate its support for flex development, more specifically its stability while debugging flex applications using the Flash Debug Player and the Adobe Flash Debugger. Here are the steps that I took to get google chrome configured as my primary flex debugging platform.
The first hurdle that I had to overcome was the Adobe Flash Debugger’s static configuration of firefox as the only option on *nix. I created SDK-24635 and included a patch that will allow you to configure which browser fdb uses within the $FLEX_HOME/bin/fdb script. See my description in the above ticket for details.
With the fdb changes in place the next step was to install the Flash Debug Player within chrome. I created the /opt/google/chrome/plugins directory and copied libflashplayer.so from flash_player_10_linux_dev.tar.gz to it. After a restart of chrome, the Version test for Adobe Flash Player reported that things were ready to go.
Now, In my case the application that I was interested in debugging required that I configure chrome’s security settings for ssl client authentication. At the present time chrome lacks a convenient ui for this configuration and instead uses Mozilla’s Network Security Services and associated utilities. This chromium wiki page details what’s involved in this configuration but here’s my version.
#1 install the tools (I happen to be running Linux Mint 7)
sudo apt-get install libnss3-tools
#2 add my client cert
pk12util -d sql:$HOME/.pki/nssdb -n seanp33 -i seanp33.pfx
With my cert in place I then needed to ensure that google chrome was started with the --auto-ssl-client-auth command-line option. There are several different approaches but I ended up adding the following script to my path
#!/bin/bash
#google-chrome-ssl
google-chrome --auto-ssl-client-auth "$1"
From there the last change was to edit my $FLEX_HOME/bin/fdb script so that my patched fdb would utilize “google-chrome-ssl” as its browser.
java $VMARGS "-Dapplication.home=$FLEX_HOME" "-Ddefault.browser=google-chrome-ssl" -jar "$FLEX_HOME/lib/fdb.jar" "$@"
And Finally fdb https://myapp.com/myflexapp. Hurrah!
Firefox MUST be the default browser when debugging Flex on nix? What’s up FDB?
So after much frustration attempting to inform Intellij 8 (no, I’m not going to switch to the EAP release that addresses this issue) that my browser of choice for flex debugging sessions should be Epiphany(I’ll explain later) I see that it’s the Flex debugger, FDB, that’s responsible for always launching Firefox when debugging. A bit of googling turned up this post on the Intellij forums where I see that on Windows FDB issues the following command to determine which browser to use cmd /c ftype http.
So a little more googling turned up flash.tools.debugger.DefaultDebuggerCallbacks. Take a look at the value of the static final UNIX_DEFAULT_BROWSER…”firefox” Ah ha! Then take a peek at the implementation of findUnixProgram… which UNIX_DEFAULT_BROWSER. So my quick solution was to change the symbolic link maintained by /usr/bin/firefox to point to Epiphpany, in essence tricking FDB into launching my browser of choice.
Further down in the impl of DefaultDebuggerCallback’s findUnixProgram you’ll see that if which UNIX_DEFAULT_BROWSER fails to resolve, a check is made within the $FLEX_HOME/bin for UNIX_DEFAULT_BROWSER. So I suppose if you wanted to remove /usr/bin/firefox all together and create your hijacked firefox sym link $FLEX_HOME/bin that would work as well. Hrm…but since $FLEX_HOME/bin is already on my path as per common Flex developer practice the initial which UNIX_DEFAULT_BROWSER would have already resolved to $FLEX_HOME/bin. I’m not getting it Adobe.
And just to complete this post – the only reason that I’m going through this is to get around the common issue where the debugger will fail to maintain the connection to the Flash Player when running within Firefox under Linux…awe poop!
Functionlets
So I’m not sure if there is common name for this brand of inner-function but I’m feeling a bit creative at the moment:) A functionlet is what I refer to as the definition of one or more functions within an outer function, typically for the purpose of encapsulating a bit of reusable logic that has no purpose outside of the containing function. I typically prefix the functionlet name with a double underbar just to set it apart from a plain old function(pof). As an example consider this “parameter replacer”.
public static function replaceParams(url:String, token:String, paramMap:Object):String{
for(var key:String in paramMap){
url = __replaceAll(url, token+key, paramMap[key] as String)
}
return url;
// and the functionlet
function __replaceAll(org:String, fnd:String, rpl:String):String{
return org.split(fnd).join(rpl);
}
}

2 comments