Monday, December 27, 2010

In order to access a Garmin device from Javascript in a web page, the Prototype framework needs to be loaded. The bad thing about Prototype is that messes other things up. One nice thing about jQuery is that it is nonintrusive, defining only one global symbol. Prototype, on the other hand screws with basic Javascript datatypes.

The first thing that I had to deal with after loading Prototype was that I could no longer use for (i in array) { ... }, to iterate through array elements without getting a bunch of extra junk. So I rewrote my for loops to go from 0 to array.length - 1 instead.

The next thing really confused me for hours. I wanted to encode a Javascript data structure as JSON, and JSON.stringify([]) would inexplicably result in "\"[]\"". But if I used the browser's Javascript console, JSON.stringify([]) would correctly result in "[]". Finally, I came across a web page that identified Prototype as causing this problem by setting Array.prototype.toJSON, among other things, which also explained to me why Prototype was screwing up my for loops iterating through arrays.

Monday, December 20, 2010

When building a war file with ant, I found it convenient to include multiple <webinf/> elements in the war task when some of the WEB-INF files were generated, so that the source files and the generated files could be in separate directory trees. However, if there were entries under WEB-INF that were duplicated between the directory trees, one of them would always cause ant to find the war file out of date and rebuild it. It's not that I had any duplicated regular files, but I did have duplicated subdirectories, which had different timestamps. I had been puzzled by why ant was always rebuilding the war file, even if nothing had changed, before looking into it. I finally changed the war task to have a single <webinf/> element pointing at the generated files, and added a task that copies the source files into the directory tree of the generated files.

Monday, December 13, 2010

Facebook authorization has some weirdness that I could only deal with with an ugly workaround. My understanding of OAuth is that I redirect the user to a Facebook URL. Then, Facebook sends the user back to me with a code that I exchange for an access token with Facebook. This works fine if the user has already authorized my application: the user gets redirected to Facebook, and then redirected back to me without a hitch.

However, if Facebook need the user to authorize my application, then there is a problem. My application runs in an iframe in a Facebook page. However, if I redirect the user to Facebook, which shows the user the authorization page, Facebook detects that it's in an iframe and grays out the page. If the user tries to interact with it, the user gets sent to the page out of the iframe. Once the user authorizes my application, the user gets sent back to me, but not in the iframe. Fortunately, when the user comes to my application, Facebook passes a flag to me that says whether the user has already authorized my application. So if the user has already authorized my application, I redirect to Facebook and things work fine. If the user has not, then I show the user a page that has some javascript that sends the user to Facebook out of the iframe, and when the user comes back from Facebook, I redirect the user to the Facebook page that frames my application.

Monday, December 6, 2010

I have an ant target that runs some scripts on some Amazon EC2 instances. So, I first generate a file with a list the hostnames of the running instances. Then, ant runs a shell command that iterates over the hostnames and runs ssh to each with a command. Since I didn't want to run the command as root, the command was su -c "\"command with some parameters\"" username, which worked fine for me. However, on cygwin on Microsoft Windows, the nested quoting didn't work, so that su was trying to set the user to the first command parameter rather than the username I specified. None of the variations of single and double quotes and backslash quoting the space characters worked.

Finally, I gave up on trying to deal with the quirks of the Bourne shell under Microsoft Windows, and moved the su into a script on EC2:

if [ ! `id -un` = username ]; then su -c "sh -c \"$0 $*\"" username; exit; fi

Of course, none of the command parameters are expected to have spaces in them, as the $* would be trouble. And $@ wouldn't help because of the nested quoting.