Saturday, July 28, 2007

FlexCamp

I went to FlexCamp last night at Adobe's office in San Francisco. It was awesome. Adobe really knows how to host an event and how to treat developers. I was impressed. It was really cool seeing new Flex Builder 3 features presented by developers (and QA!) One of the sweetest moments was one of the developers showing how you can preview variable expressions during debug sessions just by mousing over the expressions. That may sound like a small thing if you haven't debugged code, but it's really useful. It elicited huge, spontaneous applause from the crowd of developers.

The demos by MixBook and SlideRocket were also really impressive. I was particularly blown away by SlideRocket. I was talking to one of the Adobe guys during a break and he told me that SlideRocket was completely coded by one guy, which just blew me away.

I was also really impressed with the Fireworks integration with Flex. I loved the idea of a designer using Fireworks to create a visual prototype using actual Flex UI components. Designer-developer workflow is still a holy grail of application programming IMO, and this was a small, but significant step in the right direction.

I did a presentation on using Flex to build a Facebook app. It was late at night. I was pretty tired and tried to keep it to 15 minutes, but I think it went over pretty well. I had lots of people asking me for the slides afterwards, so here are the slides in PDF. Also, here's the code for YouTubeFaves.

Thursday, July 26, 2007

XForms Article on IBM developerWorks

IBM recently published an article I wrote on XForms. There have been so many times in the last five years that I've looked at XForms on behalf of whoever I was working for. It was always such a promising technology. It just needs browser support. It's funny that Mozilla has a great plugin that they don't include by default. Of course it's really just a matter of Microsoft. If IE included XForms support, it would get rolled into Firefox the next day. But of course they don't do this and instead re-invent the wheel...

Wednesday, July 25, 2007

Valley Fair Apple Store Chaos

I went to the Apple Store at Valley Fair mall here in San Jose today. I needed to pickup a video adapter for my MacBook. It was complete chaos there.

First, they are remodeling the store. So they have a small fraction of the store open still, while most is closed down. Ok, remodeling is good, but ...

We're still in the midst of iPhone mania, at least here in Silicon Valley. So take the combination of a lot more people than usual at the store plus much smaller space than usual, and what do you get? Chaos.

The Genius Bar was supposedly closed and that area was being used to check out customers. Only there were lots of folks up there with their Macs, presumably with some kind of problem needing attention from a Genius. They had a big wait board for people wanting to buy iPods (no not iPhones.) You put in your name and waited for it to be called apparently. "Take a number" just seems so un-Apple.

Luckily they have the roving checkout people at the Apple Store. So I was able to flag one down and pay with my credit card without having to deal with Geniuses and iPod lines. Another nice feature is that their system recognized my credit card and remembered my email address, so my receipt was emailed to me.

On my way out, I noticed several iPhones without anybody around them. I decided it was time for me to take a look at one. For some reason I thought it would be smaller. Maybe that's because my iPod is a Nano, which is very small. The iPhone was using the store's wifi, but it did seem to load pages pretty slow. I typed in some addresses and did some searches on it. Typing wasn't a problem. I made more typos than I make on my Blackberry, but I'm sure that's just a learning curve.

I tried the king of all AJAX pages, Google Mail. I wanted to view my receipt that Apple had just emailed to me. It did seem to work, but oh man it was much more painful than using GMail on my Blackberry. I guess you can use GMail's POP forwarding to access your mail the mail app on the iPhone. Obviously I didn't try that, though I don't think GMail translates well to POP (I don't want to see my outgoing messages in my inbox, thank you.) Also, I read that a lot of people can't use the "normal" GMail interface on their iPhone unless they are on wifi. Also, I could not open the PDF of my receipt on the iPhone.

I took out my Blackberry, opened GMail on it, and then opened up the PDF receipt from Apple. It took far less time, even on EVDO instead of wifi. I definitely got some unfriendly looks from the customers there...

Tuesday, July 24, 2007

FlashTracer

If you're doing Flash/Flex development, FlashTracer is a great Firefox plugin. It simply monitors your Flash log file and pumps its content to the Firefox sidebar. Very simple, but useful. The only problem I've had with it has been on my MacBook. But I got it to work. Here's how.

From the command line...
cd ~/Library/Preferences/Macromedia/"Flash Player"
mkdir Logs
cd Logs
touch flashlog.txt

Open up FlashTracer and click on Options. In the Select Output File enter Macintosh HD:Users::Library:Preferences:Macromedia:Flash Player:Logs:flashlog.txt
Obviously replace with your username (short name). Restart Firefox, and it should work!

Oh yeah, obviously you need to have the debug version of the Flash Player installed...

Google Docs To The Rescue

I was reading this post by Jeremy Zawodny, and it reminded me of my recent Mac Office 2004 meltdown. I went down a similar path. I had an Important Doc(!) that I needed to make some edits on for work. I had planned on doing the edits that morning, before I went in to the office. So I had some serious time pressures. I didn't know how long it would take me to solve the riddle dropped on to me by Apple Software Update. I actually tried loading the document into Pages, but it barfed on it (maybe because the doc had a table of contents?)

So like Jeremy, I fired up Google Docs. I uploaded the Important Doc there (hope nobody from Security is reading this, though the doc was intended for folks outside of my company.) It came through just fine. I made the edits I needed to make and saved it on Google Docs.

Then I went back to fixing Office, which I eventually did. I went in to work, opened the Google Docs version of my document, and manually merged in changes to the original. I would've just exported it as a Word Doc, but I was afraid of how it would handle the table of contents. So I manually merged and then updated the table of contents.

Friday, July 20, 2007

The OSX Update from Hell

Thursday I installed an update on my MacBook that included QuickTime 7.2. I installed while I was watching a DVD during my lunch. I installed it using Software Update, of course. No big deal, I install updates like that all the time.

Friday morning I needed to do some edits to a document I had been working on for work. This was a Microsoft Word document, so naturally I've been using Office 2004 for things like that on my MacBook. I double clicked the document, and Word started. Then it stopped. Abruptly. I tried to open Word directly and the same thing. I tired launching Excel or PowerPoint -- same thing.

I noticed that there was an update for Office 2004 (11.3.6) available. So I downloaded it and tried to run it. It did the same thing.

At this point I knew that something in that update from Apple had crippled Rosetta. It was the only thing that made sense. I did some research. I found one thing that suggested reinstalling the most recent major update from Apple. So I did that. No luck.

I did some more research, and found that the problem stemmed from the presence of Java 6 Developer Preview on my MacBook. To uninstall that, here's what I did:

sudo lsbom -s -f /Library/Receipts/JavaSE6Release1.pkg/ContentsArchive.bom > /tmp/files

I edited /tmp/files and chagned all the spaces to "\ " (backslash and a space) and then changed ./ to rm /. This changed the bindings file to remove the Java 6 bindings to OSX. So I now I just needed to execute this magic file.

sudo bash /tmp/files

Now I could delete Java 6.

rm -r /Library/receipts/JavaSE6Release1.pkg

Now I could rebind Java to OSX.

sudo update_prebinding

I actually deleted Java 5 (rm /Library/Receipts/JavaForMacOSX10.4Release5.pkg) also, and then re-installed it, but I probably didn't have to do that last step. Rosetta and thus Office were now back!

Wednesday, July 18, 2007

Ron Paul and YouTube

There's been a lot written about the Ron Paul phenomenon. One thing I will have to do at some point is just talk about what I like about Ron Paul. I've been very apolitical this year though, so that will have to wait. One very interesting thing about Ron Paul though is his influence on YouTube.

My friend Chris wrote an interesting program to calculate the "influence" of political candidates via YouTube. Most of the major candidates have accounts (ok so it's surely their staffers, but whatever) on YouTube, and you can be their "friend." Chris looked at each candidate's friends and at what YouTube videos they had marked as favorites. He looked at the common favorites among friends of candidates. Here's a chart showing this data for Barack Obama:

The big red bar is the most common favorite among friends of Barack Obama. Why did I pick Obama here? Well he is the most popular candidate on YouTube (and on Facebook) as measured by how many friends he has. Anyways, back to the red bar. The most popular video among his Obama's friends is a favorite of 12 of his friends. #2 on the list is a favorite of 8 of his friends. Now let's take a look at the same chart for Ron Paul.



The #1 video among Ron Paul is a favorite of 34 friends, while #2 is a favorite of 17 friends. The video in question is a video of Ron Paul speaking at Google.

I guess none of this should come as a surprise. Ron Paul supporters are ... very passionate about Paul. It's that passion that infuriates many people. He is very much a fringe candidate right now, but the passion of his supporters may well push Paul into the mainstream. Is YouTube a place for that to happen? Probably not, but it's a start. To do my part, here's the video in question. Enjoy.

Monday, July 16, 2007

Cross Site Scripting with Yahoo Local Search API

So I have a fun a little project where I was playing around with the Yahoo Local Search API. I really like Yahoo's local search. I think it is much better than Google's, though in all fairness that opinion was formed 18+ months ago. They have a great open API. Of course they place a limitation on how much you can use. What's interesting is that usage is tied to IP address. The limit is 5000 queries per day per IP address.

This of course begs for Cross Site Scripting(XSS.) If the call to their API to happen from a user's browser, then it counts against that individual user's 5000 query limit. One obvious way to accomplish is this is with Flex. That's because the Yahoo API server farm has an open policy for Flash.

Another way is via JavaScript. Of course I can't make an XMLHttpRequest directly from a user's browser to Yahoo because of browser security. Luckily Yahoo encourages Cross Site Script. You can make a request to their local search API with response output set to JSON and with a callback method. From there you just need some sneaky JavaScript:

 function search(lat,lng,cat){
var reqUrl = "http://local.yahooapis.com/LocalSearchService"+
"/V2/localSearch?appid=YahooDemo&"+
"output=json&callback=showResults";
var req = reqUrl + "&query="+cat+"&latitude="
+lat+"&longitude="+lng;
var rdiv = document.getElementById("resultlist");
var jsonp = document.createElement("script");
jsonp.setAttribute("type","text/javascript");
jsonp.setAttribute("src",req);
rdiv.appendChild(jsonp);
}

The sneaky part here is creating a "script" DOM element, setting its src attribute to the dynamic URL, and then dropping it into the main page DOM. It gets evaluated immediately. The URL response looks like:


showResults({"ResultSet":{"totalResultsAvailable":3423,"totalResultsReturned":10,"firstResultPosition"

:1,"ResultSetMapUrl":"http:\/\/local.yahoo.com\/mapview?stx=coffee&radius=50&ed=sh5iF6131DyGMtZvcmi9jNSxMpMwUjolfcSc44DLrkDbXpY-"

,"Result":[{"Title":"City Espresso Gourmet Coffee","Address":"630 Blossom Hill Rd","City":"San Jose"

,"State":"CA","Phone":"(408) 972-4500","Latitude":"37.250463","Longitude":"-121.8436","Rating":{"AverageRating"

:"","TotalRatings":"0","TotalReviews":"0"},"Distance":"1.18","Url":"http:\/\/local.yahoo.com\/details

?id=21609154&stx=coffee&csz=San+Jose+CA&ed=WbZ4Ba160SzTaXFlbDSmVAyxneC9N59mhMtS3xZb6kL86aeI4P1iTZT5BJOOXR5qK9HSoV5KX0wL"

,"ClickUrl":"http:\/\/local.yahoo.com\/details?id=21609154&stx=coffee&csz=San+Jose+CA&ed=WbZ4Ba160SzTaXFlbDSmVAyxneC9N59mhMtS3xZb6kL86aeI4P1iTZT5BJOOXR5qK9HSoV5KX0wL"

,"MapUrl":"http:\/\/maps.yahoo.com\/maps_result?name=City+Espresso+Gourmet+Coffee&desc=4089724500&csz

=San+Jose+CA&qty=9&cs=9&ed=WbZ4Ba160SzTaXFlbDSmVAyxneC9N59mhMtS3xZb6kL86aeI4P1iTZT5BJOOXR5qK9HSoV5KX0wL

&gid1=21609154","BusinessUrl":"","BusinessClickUrl":""}]}});

The function showResults gets evaluated with the results from Yahoo. How nice of Yahoo to support JSONP. The eBay APIs also have great support for this technique.

Friday, July 13, 2007

Non-Java Article on IBM

I have a new article up on developerWorks: Developing applications using the Eclipse C/C++ Development Toolkit. This is one does not use Java, as should be obvious from the name, though it does use Eclipse. For some reason IBM listed my very old "About the author" info from the first article I wrote for them 1.5 years ago. So it says I work for Vitria still, instead of eBay.

It was a fun article, though I must provide a word of warning on it. CDT relies on g++/make/gdb being "properly" installed on your system. This can be a real pain on Windows, though it is status quo on any kind of Linux or on OSX. From the screenshots, it is obvious I wrote the article on a Mac, and part of why I did that was so that I did not have to deal with make/cygwin configuration on Windows. So before trying CDT out, make sure you have its prereqs working, i.e. at least use make to build something with at least two source files, via the command line. Otherwise you might think there's a problem with CDT, when actually the problem is with make or cygwin.

Thursday, July 12, 2007

Better Than an Autograph

Ok, I know this post is going to make me look stupid, but oh well. Isn't that part of the point of having a blog? Neal Gafter gave me a compliment on my blog. Yes, The Neal Gafter. Seriously, That Neal Gafter. Quite a thrill for a long time Java hacker like me :-)

Update: Not only a compliment from Neal Gafter, but one from Joshua Bloch! And that might mention my investigation on the puzzler on the book's website... Wow!

New Facebook App

Today I wrote a new Facebook app. It's a Flex based app that let's you watch the most popular videos on YouTube. You can watch the YouTube video from inside Facebook, which is kind of nice. That required some hacking of how YouTube hides the URL of their FLV files. The FLV is the actual video you watch on YouTube. People love to use the embed code for a YouTube video so they can put the video on their own page/blog/whatever. The embed references a SWF file. That SWF file is what references the FLV file and plays it inside the Flash Player.

Anyways, back to the Facebook app. I wrote it with the primary intent of using it for a presentation I'm planning on doing at FlexCamp in a few weeks. The presentation is going to be on *drum roll* creating a Facebook app using Flex. I'm also going to use the Find it on eBay application written by my colleague Anand Gangadharan. It's a lot more advanced than my little YouTube application.

Auto Unboxing in Java

There has been a lot of discussion among my colleagues about the evilness of auto unboxing in Java. The evilness can be easily demonstrated:

int x = null;
if (x == 0) {}; // this throws a NullPointerException

The argument on why this is evil is that in pre-Java 1.5 days, developers would have written the following equivalent instead:

if (x.intValue() == 0) {}; // still throws a NullPointerException

When they typed the ".intValue()" they would realize that they needed to add a null check:

if (x!=null && x.intValue() == 0) {}; // No NPE here

The other case for evilness is imagine somebody created the following API:

public void foo(Integer i);

And then changed the signature to:

public void foo(int i);

In pre-Java 1.5 days, any clients of foo() would have compilation errors, thus alerting "people" that they needed to add null-checking code. With Java 1.5+, there would be no compilation errors, so there is obviously a chance for Something Bad To Happen.

You might have noticed that I've been distancing myself from these arguments. I don't really buy them and tend to argue the other side. Auto unboxing is just a new language feature that you had better understand before you use it. If you understand it, then of course you will write

if (x!=null && x == 0) {}; // no NPE here either

And you will change your API as:

@Deprecated public void foo(Integer i);
public void foo(int i);

The real antidote is developer knowledge and good testing to catch the corner cases.

A lot of my colleagues would like an option in Eclipse to cause a compiler error whenever auto unboxing could cause problems. IntelliJ IDEA gives a warning. Maybe there's an option for it to give an error instead of a warning.

I remember when unboxing was a JSR. It was definitely the most controversial part of JSR 201. Many people argued for default values to avoid the NPE problem. That would have been horrible, IMO. Of course C# has the advantage here. That's because they had boxing/unboxing from day one. You can't write Double x = null; --- it won't compile. You can do something like Object x = null; Double d = (Double) x; ... but you're really trying to throw an exception at that point.

Monday, July 09, 2007

Java Puzzler

I've been reading Java Puzzlers by Josh Bloch and Neal Gafter. I usually read (and hopefully solve) one puzzle each day. I had one last week that was ridiculously hard. It was puzzle #44 Cutting Class. The puzzle is pretty simple. You have a simple class called Missing. Then you have two other classes, Strange1 and Strange2. Both have a main method where they construct a new instance of Missing using the usual

Missing m = new Missing();

Both classes also have a try ... catch block where they catch a NoClassDefFoundError. The difference in the two classes is that the first (Strange1) wraps all references to Missing inside the try, but the other(Strange2) does a blank initialization (Missing m;) outside, and then invokes the constructor inside (m = new Missing()) the try.

In the puzzle, you compile all three class and then delete Missing.class. You then execute Strange1 and Strange2. The puzzle is that Strange1 throws a NoClassDefFoundError, but Strange2 does not.

In the solution, the authors point out that the behavior is undefined, so it is possible for different JVMs to exhibit different behavior. The book was written with Java 1.5 in mind. I tried a couple of different 1.5 JVMs (HotSpot and IBM's) and both behaved just as the book claimed.

In the solution to the problem, you have to use a little known part of the JDK, the javap tool. I had not used javap in a long, long time. I used it once to track down a problem that turned out to be a classloader issue. Anyways, javap shows you the instructions that the JVM is going to execute. The key to the puzzler is that in Strange1, the memory location allocated for the instance of Missing has to get merged with the instance of NoClassDefFoundError caught in the catch block. This causes the JVM to have to computer the most specific common superclass of the two classes, and thus load Missing. This causes a NoClassDefFoundError to be thrown before any execution can take place. In Strange2, the memory location is allocated outside the try ... catch, so it is different location than the location for the caught NoClassDefFoundError, so no merging, etc.

For kicks, I then tried a couple of 1.6 JVMs( HotSpot and JRockit.) With a 1.6 JVM, neither Strange1 nor Strange2 throw a NoClassDefFoundError! I did a javap on the 1.6 class files, and they were identical to the 1.5 class files. So what gives?

The key is JSR 202. This JSR introduced a new class verifier (the split verifier) in Java 1.6. One of the ideas on this JSR was to improve class loading time by speeding up class verification. Class verification is where the exception gets thrown in the puzzler. So how does the new class verifier avoid the exception? Basically it allows for extra metadata to be included in the class file around join points. The merging of the Missing instance and the NoClassDefFoundError instance is a join point. So with Java 1.6, the Missing class does not have to be loaded to compute the most specific superclass of the type merged variables because it is already embedded in the class file. So the Missing instance is not attempted to be loaded until its constructor is invoked during execution, and at that point the error is caught. Beautiful.

Saturday, July 07, 2007

Cable Modems, Routers, and Connection Speed

Comcast is our ISP. We have a cable modem from them, and we also get cable TV from them. Lately our connection speed started to stink. So I called Comcast and complained. The service rep told me "indeed I see some packet loss from your modem, we'll send out a technician." He then added that if for some reason the problem was being caused by non-Comcast equipment then we would be charged some outrageous fee. Whatever.

Two technicians actually came out and we were very nice and helpful. They confirmed our connection stunk. They put in a "line filter" (whatever that is) and they switched out modems. They then tested the connection and it was once again blazing fast, like it used to be. Everybody was happy. Way to go Comcast!

Crystal pointed out that there was also the possibility that some of our other equipment could be slowing down our connection. Our topology is: cable modem -> Vonage modem -> wireless router -> computers. Our home built desktop system has a wired connection to the router, even though it actually has a wireless PCI card in it as well. My MacBook uses the wireless of course. Just to be sure that the other stuff was not causing any problems, I did some experimentation.

I did speed tests with various configurations. First I tested with the cable modem connected directly to the desktop computer. I used this as a baseline. I got 600K down and 550K up.

Next I put the Vonage modem in between the cable modem and the desktop computer. This had no significant effect on the speed. It was actually slightly faster down and slightly slower up. No difference. I was happy to see this.

Finally I set up my usual setup. Now I found a dip in speed. I was only getting 500K down and 475K up. It was a pretty consistent 15-20% drop in speed.

Now 500K down is still plenty fast. It's certainly fast enough to support Vonage and "heavy" internet use like streaming video. I suppose some loss because of the router (a D-link DI-60 80211g that includes a hardware based firewall) should be expected, but 15-20%? I really don't know if that's a really bad amount or just par for the course. Do I need a new router?

Wednesday, July 04, 2007

Palo Alto 4th of July Chili Cook-Off

Today we went to the 26th Annual 4th of July Chili Cook-Off in Palo Alto. It was a lot of fun. They had inflatable jumpers and slides that Michael, Jr. really enjoyed:



Of course we had to try some chili. Here we are learning the secrets from one of the chili chefs:


Our favorite was Papa's. Another really good one  was the Margarita Meata Chili. It had a nice mix of tequila sweetness and heat.


We'll definitely have to go back again next year!

Sunday, July 01, 2007

All Star Game

The top story on ESPN starts out "Despite a lackluster season ... Barry Bonds will be right at home in the 78th All Star Game." A lackluster season? Bonds is #1 in the NL in OBP with a gaudy 0.513. OBP is arguably the most important stat in baseball, but it is often overlooked by sports writers. Fine. He's #2 in the NL in SLG at 0.599, and not surprisingly #1 in OPS at 1.112. He's not just #1, but #1 with a bullet. The difference between him and #2 Chase Utley is 0.128. If you subtracted 0.128 from Utley's OPS you would drop 24 slots in the rankings. Yet, Bonds is clearly having a lackluster season...

Scarcity

I walked by the San Jose Oakridge Apple Store today. They had up a sign indicating that they had no iPhones. So I guess those things really did sell out. Hey that's good for business.