grack.com

2009

GWT 2.0 on OSX and the ExternalBrowser RunStyle

GWT 2.0 ships with a new HtmlUnit-based testing system that makes testing faster, but isn’t full web-browser under the hood. It can’t perform layout, so any tests that rely on layout measurements won’t succeed.

There are a number of alternate run styles that are useful, however. Manual mode, which outputs a URL that you can connect any browser to, works well for quick testing, but is a pain when you need to keep running it over and over. RemoteWeb and Selenium automate the process of starting and stopping browsers, but require you to start an external server before testing.

My Presentation at Google Campfire One

I went down to Mountain View last week to show off the company we’ve been building, DotSpots, plug our brand-new Chrome extension and demo some of the great new features of GWT 2.0.

See it directly on YouTube here:

Kudos to the Google team for putting together such a great event. You don’t realize how much planning and preparation goes into an hour-long event like that.

Re-enable 'Install' button for Mac Chrome Extensions

UPDATE (Jan 6, 2010): The Chrome team has turned on extensions on Mac in the latest dev channel build. Even better, you can install directly from extension pages without this bookmarklet. Hooray!

We just officially launched our extension on the Chrome extension gallery today and Mac users are having trouble installing the extension. The ‘Install’ button for Chrome extensions is disabled if you are running on a Mac.

You can manually download extensions from the Google download site using a URL like so:

https://clients2.google.com/service/update2/crx?response=redirect&x=id%3Danfibeojfgdfejcfflalkebdfgojfbbm%26uc.

Absolutizing URLs in Javascript

Occasionally it becomes useful to get the absolute form path of a URL from a relative one. You might be dynamically changing links on a page, or loading scripts from the same location as scripts that have already been loaded.

Computing an absolute URL by hand is problematic: you need to deal with any <base> elements in the document and properly implement the relative path canonicalization that browsers already do.

It turns out that on standards-compliant browsers based on Gecko, WebKit or Opera, the href property of anchor elements is magical. If you assign a URL fragment to it, it comes back as a fully-qualified URL when you read it back.

Fix for GWT Hosted mode crash with Safari 4.0.4

My local tests started failing soon after upgrading my machine to Safari 4.0.4. Some research and pointers from the GWT folk pointed me at the root cause, a WebKit bug which is now fixed.

Kelly Norton pointed me at a quick fix:

  1. Download the latest WebKit nightly from here

  2. Save it locally

  3. Add the following environment variable to your testing .launch targets (using the path to your new WebKit.app, of course). Tests run from Ant or the command line will need to use the appropriate tasks or shell commands:

    Name: DYLD_FRAMEWORK_PATH
    Value: /Applications/path-to-your-local-webkit/WebKit.app/Contents/Frameworks/10.5
    
  4. Snow Leopard users will need to use 10.6 in the path above.

Packing Chrome extensions in Python

We’re just about to release our DotSpots extension for Chrome and I’ve been working on integrating the CRX packaging into our build process. CRX files are basically ZIP files with an RSA signature and public key tacked on to the front of it. Generating these files requires you to use the Chrome –pack-extension argument (which in turn requires you to deploy the 100MB+ Chrome binaries to your build machine).

Javascript primitive conversion quick-reference

Javascript has three primitive types: number, string and boolean. You can quickly coerce values between the primitive types using some simple expressions.

There are a few different coersion expressions, depending on how you want to handle some of the corner cases.  I’ve automatically generated a list below:

Real-time Search and Frnégtttrdre

Robert Scoble’s accidental tweet (“Frnégtttrdre”) earlier tonite caused a minor ripple: people wondering if he was announcing a secret project, under the influence of alcohol or wandering around with an unlocked iPhone in his back pocket.

It also makes for an interesting test for real-time search.

An hour after his tweet:

rssCloud Security Recommendations

Copy of an email I sent to http://tech.groups.yahoo.com/group/rss-cloud/messages:

I’ve been looking into the security of rssCloud over the last few days and a number of serious issues have come up. The ones of immediate importance have been reported and fixed, but I’d like to suggest some protocol changes to prevent rssCloud servers from DoS’ing sites or ending up DoS’ing each other.

Here are my implementor guidelines, based on the research over the last few days. These guidelines should mitigate all of the problems I’ve found so far without requiring rssCloud subscribers to make major changes to their code:

Serious rssCloud Protocol DDoS Vulnerability

UPDATE: There’s a new domain parameter in rssCloud that makes this DDoS far, far worse.  Since there’s no verification (yet) on rssCloud endpoints, you can now subscribe any server to any rssCloud hub’s notifications.

While researching some of the issues of rssCloud running in a shared hosting environment, I came across a serious vulnerability in the protocol. The vulnerability allows someone to cripple a shared web host. Because of the sensitive nature of this vulnerability, I’m not going to share example code or which shared host(s) are vulnerable.  The fix is easy: follow these security recommendations to close the hole.

Parsing the PubSubHubbub Notifications

I’ve updated my prototype to use the excellent Rome feed parser library. Instead of dumping 20kB of ‘useful’ raw feed on you, it now formats the entries nicely.

I’ve hooked it up to deliver me real-time headlines from my Google Reader feed and from TechCrunch, both of which work flawlessly.

With all the building blocks I’ve strung together, this really wasn’t any work at all. All of the complexity lies in the cloud: Google’s AppEngine and XMPP implementation and the PubSubHubbub hub. The rest is done with a feed-parsing library.

Here’s the new code:

A PubSubHubbub to XMPP Gateway

At first glance, both rssCloud and PubSubHubbub have an interesting shortcoming that makes them difficult to use for desktop feed readers. Since both of them require HTTP callbacks to a publicly accessibly endpoint, a user is required to open up a port on their firewall.

It turns out that a subtle difference in the specifications gives PubSubHubbub a big edge in this case. While rssCloud requires your callback endpoint to live at the IP address you make your request from, PubSubHubbub allows you to subscribe any endpoint you wish by specifying a hub.callback url.

rssCloud Meeting Wrap-up

I caught the audio of the rssCloud get-together in Berkeley tonight and it was very enlightening.

PubSubHubbub vs. rssCloud

UPDATE: I’ve written a PubSubHubbub-to-XMPP gateway that solves some of the issues of running a real-time feed reader behind a firewall.

UPDATE 2 rssCloud has a serious vulnerability that needs to be addressed in the protocol. I’ve linked some security recommendations here that rssCloud hubs should implement as soon as possible.

These last few months have brought us not one, but two RSS-to-real-time protocols: PubSubHubbub and rssCloud. While rssCloud has been “around” for a while, it never saw much adoption or interest until recently.

As a developer, the important question is: which of these two protocols should I focus on?

A quieter window.name transport for IE

Using window.name as a transport for cooperative cross-domain communication is a reasonably well-known and well-researched technique. I came across it via two blog posts by members of the GWT community that were using it to submit GWT FormPanels to endpoints on other domains.

Mix's Gestalt project is on the wrong track

I came across the Mix Gestalt project tonight and I thought I’d share some thoughts. It’s a bit of script that effectively sucks code snippets in languages other than Javascript out of your page and converts them to programs running on the .NET platform.

While interesting, it has a number of drawbacks that make it far less interesting than the HTML5-based approach that works in the standards-compliant browsers based on WebKit, Gecko and Opera, as well as the improved IE8.

Disable controls with a CSS-only glass panel

Here’s a neat CSS-only panel that you can use to disable controls within a given <div> element.  It uses an absolutely-positioned <div> within the container of controls you’d like to disable. The glass panel is positioned using CSS to overlap the controls, and set partially transparent to give the controls a disabled look.

Note that this only works in standards mode, <!DOCTYPE html>, due to IE’s painfully outdated quirks mode. Additionally, your container of controls needs to be styled as overflow: hidden to work around the limitations of the height expression and position: relative so the parent can become a CSS positioning parent.

@SuppressWarnings on variable declarations

I’ve been using this trick for a while and I thought I’d share it. For those who live by Eclipse’s quickfixes, it’s not entirely obvious that it’s legal.

If you have legacy code like the code below, where foo.list() is a Java 1.4-compatible method returning java.util.List, you’ll normally see an “unchecked cast” warning on the assignment like so:

public void doSomeListStuff(Foo foo) {
    List list = foo.list(); // Warning: unchecked cast
    for (Blah blah : list) {
        frobinate(blah);
    }
}

Normally, Eclipse offers to fix it for you like this:

A taste of Firefox Extensions, written in GWT

UPDATE: It’s live! The open-source project is up on Google Code and I’ve blogged a more about it.

I’m getting closer to having the GWT bindings that we wrote for Firefox ready for public release. What we’ve got is more than enough to write a complex extension. The bindings were even enough to write a prototype of an OOPHM server, itself written in GWT!

For now, just a taste of what extension development is like GWT, complete with strong typing, syntax checks, auto-completion and hosted mode support:

Phone number birthday paradox

After receiving my Google Voice invite tonight and picking a phone number, seemingly at random, I discovered that I had picked a number with the same last four digits as one of my friends’ numbers.  If you are familiar with the Birthday Paradox, you might recognize the form of the problem.

Stored Procs are Dead - Long Live Stored Procs!

Every developer has a different opinion of stored procedures. If you’ve worked on a few projects that involve databases, you’ll inevitably come across the as part of a project.

I’ve personally had a love/hate relationship with them. They require maintenance scripts like your regular table structure, but they aren’t structure. Generally, databases don’t give you good introspection ability for stored procedures either - fire-and-forget management.

More on video4all, HTML5 <video> everywhere

If you’re not familiar with video4all, let me start off with a quick intro: It allows you to use the standards-compliant HTML5 <video> tag on any browser, freeing you from the complexity of configuring markup for multiple video formats.

I’ve been tweaking the video4all source a bit since last night’s late release to fix some issues with other browsers and clean up some of the code. Adding support for browsers without binding languages was pretty simple - a setInterval runs and checks for new video elements every few seconds, converting them to flash embeds as needed. It’s not ideal (DOM mutation events would be great here), but it does a decent enough job.

HTML5 <video> support for older browsers

I’ve been working on a small project to bring support for the HTML5 <video> tag to older browsers, hoping to encourage use of this tag.  The idea is to use Flash’s video/mp4 support as a “downlevel” emulator for the video tag.

It uses an HTC binding in IE and an XBL binding in Mozilla to create a flash video in place of the video tag itself. The flash video support is provided by the excellent FlowPlayer, which supports playing mp4 videos out-of-the-box.

Fantastic Rainbow in Calgary #yyc

Check out the double rainbow from today’s weather. Fantastic!

Windows 7 Experience

I spent the last few days shoehorning Windows 7 into one of the laptops I’ve got around the house. My day-to-day desktop for development is a MacBook Pro, but I spend some time testing on Windows. I haven’t had a chance to update my Windows knowledge from where I left it at the XP level, so I figured it would be a good time to give Vista’s successor a shot.

Pixel Qi - Revolutionary Screen Design

I’ve been following the story of Pixel Qi for some time.  I bought an OLPC during the first G1G1 event and I’ve been impressed with the screen’s visibility and low-cost construction.  On top of that, it can turn into a black-and-white, e-ink-like screen with minimal power draw using the same individual pixels it uses for color display, but at 3x the resolution.

Welcome to Calgary

April showers? Ha! Taken outside my driveway:

Update: getting heavier now, near white-out at times.  Another shot from the Apple iBlurryCamPhone:

Digg's optimized data streams

Digg just released a prototype of their optimized data streams.  This this is pretty cool.  It uses MIME multipart HTTP responses to return a stream of responses, dispatching each one as it comes in.  Bugzilla has been using MIME multipart for a while, though only to serve a short “Bugzilla is searching for your bugs” message before returning the actual results.

The Evolution of a Web Technology

  1. Obscurity
  2. Relative obscurity
  3. Robert Scoble gets it
  4. The ?-erati get it
  5. The SEO and marketing “experts” abuse it and annoy everyone
  6. Oprah ?s on her show
  7. Soccer moms and your grandma try ?ing
  8. Charmin Ultra-Soft becomes your friend on ?
  9. Someone in the ? space gets bought
  10. Time passes
  11. Robert Scoble declares that ? is dead

Oracle buys Sun (but really MySQL and Java)

The news that Oracle bought Sun caught me off guard.  I was moderately disappointed when they were courting IBM as a suitor, but I would have been more than happy if they had gone through with the deal.  IBM understands open-source and has a proven track record in Eclipse.

The final word on Google Eclipse plugin OSX crashes

I’ve blogged about the subject of GWT JVM crashes far too much (here and here).  This is, I hope, the final word on the subject.  I spent some time disassembling the Google Eclipse plugin (did I agree not to do that in one of the EULAs? ;)) and discovered that they are launching the JVM without using the Eclipse infrastructure.  This means that the JVM arguments are effectively hardcoded, except in one case where -startOnFirstThread is passed for OSX clients.  For those interested, the buggy classes of note are GWTDeploymentParticipant and LaunchUtils.

AppEngine+Java+OSX "Invalid memory access" on deploy

UPDATE, Apr 19 2009: This does not fix all compiler crashes in Eclipse.  This is only useful for the compiler crashes where an Eclipse JVM configuration is used.  Please see my later blog post for a better fix and disregard this information.

This is the same error I hit before (see my earlier post), but it happens in Eclipse during the “deploy to AppEngine” phase.  You’ll see it if you’ve got a project configured with a 1.6 JVM on the build path (even if your .class compatibility is set to 1.5).  It’s not obvious how to fix this at first glance - I had to dig around to find the options that Eclipse passes to the JVM.

The solution

Google eats GWT dogfood

Google’s new profile editor uses GWT, cool!

Looks like they aren’t obfuscating class names yet (a feature that just landed on the tip of trunk, IIRC):

http://www.google.com/s2/gwt/resources/9312606AE1FEAAD063F34A9446584258.cache.js

The name of the project is “com.google.focus” and there are references to codenames: “evergreen” (contact info DB?) and “publicusername”.  They are also pulling some of the code from Google Collections into the final output.

GWT 1.6 crashes (and a fix)

There’s a bug in the latest Java 1.6  that Apple provides that gets tickled by the GWT 1.6 compiler.  It manifests as a reproducible HotSpot compiler crash that looks like this:

[java] Invalid memory access of location 00000000 rip=01160767

When you look into the crash logs that Java produces (found under ~/Library/Logs/CrashReporter/java_*), you can see that HotSpot was compiling a method when it crashed:

Feedburner slow to update?

I’m having trouble getting Feedburner to update from my server, so feeds aren’t showing up in Google Reader.  It’s not pulling down the latest posts, just the ones from yesterday and before.  Any ideas?

UPDATE: It would help if I didn’t redirect FeedBurner to its own feed.

Google's Eclipse plugin for GWT and AppEngine

We’ve been trying out Google’s Eclipse plugin for the last week and it’s made a huge difference to our GWT development experience.  The plugin is designed to enhance your Java AppEngine and GWT workflow.  We’re mainly using it for GWT development, so the biggest wins for us are the GWT features, including:

Note to the Google Reader mobile team

I read all I my feeds through Google Reader. Of all the RSS readers, it is the cleanest and most convenient to use. When I started reading feeds on a mobile device, I was happy to see that the Reader team had put some effort into creating a fantastic mobile experience as well.

There are a couple of minor issues with the product:

Posting on the go

I’ve been a fan of powerful handheld devices for a long time. I bought a Palm Pilot to help me keep track of my university classes in the 90’s and graduated up to a Treo earlier this decade. The iPhone is the first device out of all of them that makes mobile publishing a breeze (and fun too).

There were a few attempts at blog and twitter integration on the old Palm platform, but networking always felt like it was bolted onto the OS, rather than an integral part of the experience.

Yet another blog engine

My Typo installation has been busted for a while–  I decided I’d bite the bullet and install WordPress.  It’s pretty much the defacto standard for self-hosted blogs and it’s flexible enough for my needs.

This is the fourth iteration of my personal blog.  My first was a hand-crafted news page of posts (using pico and an AIX shell, nonetheless) before blogs were called blogs.