Vista: Day 600

So, I had meant to do this sooner, but here’s the follow-up to my 1-day update after 18 months of using Vista.

  • I haven’t downgraded to XP, nor felt any need to. On the flip side I’m still running XP at home, and haven’t felt the need to upgrade.
  • It hasn’t crashed. Nope, not once.
  • The one vista feature I’ve grown to use is the “Start Search” box, which is basically a slower/simpler version of Quicksilver, but provides most of the functionality you need (i.e. finding programs and files you don’t use all day).

Well, that’s about it.

Oh, the Macbook I gave to Phil when I got the PC? He used it for a while, but after too many problems with it, he eventually had to go and buy a replacement (his 4th Macbook in 2 years).

Java Goofs: Enhanced For Loop

One of the “big deals” in Java 5 was the enhanced for-loop. Basically you could trim this:

for(int i=0;i<collection.size();i++) {
Object object = collection.get(i);
doSomething(object);
}

down to this:
for(Object object:collection) {
doSomething(object);
}

I don’t think such an improvement was really necessary, but combine this with generics and I have to admit your code does look a little cleaner, so I use them when possible. However, the for-loop is basically a half-implemented hack with two major goofs.

1. It works with anything implementing Iterable, and arrays. Despite working with anything Iterable, it does not work actual iterators, which seems just silly to me.
2. If the collection is null, it throws a NullPointerException. The only defense I’ve seen for this is that “a null collection is not the same as an empty collection”. Agreed, and those people clearly missed the point. The point was to clean up the code and now we have to add the same silly if(collection==null) around the loop. If your code really did need to know if the collection was null (e.g. lazy-loading), it’s going to check anyways, but this would save at least one more repetitive line if the loop just treated null as empty and did nothing.

Missing Java Annotations

@SelfExplanatory – I’d love to be able to turn on JavaDoc warnings in Eclipse, but I can’t. Why? Because 90% + of the code is self explanatory. Do I really need to see that getName() “Returns the name”, or that setName(String name) has the utter audacity to “Set the name”? No, I don’t. Put a @SelfExplanatory and JavaDoc can create these braindead comments without cluttering up my code, while Eclipse can reserve its warnings for the more interesting methods.

@NotNull – Other languages may have solved or avoided this problem, but I’d like to be able to dictate that a variable can be set to anything except null, and also that a method will never return null. It would just save so many headaches (of the onerous Runtime variety, no less), as well as lots of “if (foo == null)”…

The ulterior purpose of this post is to test the upgrade to WordPress 2.6.

Register My Login to Join Your Account

One of the details that can be tough to keep track of with a large or fast-moving website is language consistency. Of course, to be consistent, you need to decide what to use. I did an audit of the most popular English-language sites (as determined by Alexa and Compete), to see how three key phrases were being used. These were:

Login/Log In/Sign in – The action of authorizing your account.
My/Your – My Movies, Your Account, etc.
Join/Sign Up/Register/Create – Creating a new account.

Here is the raw data, see below for some analysis.

adultfriendfinder.com login my join
aim.com sign in my join/get
amazon.com sign in your start
aol.com sign in my sign up
bankofamerica.com sign in your* enroll
blogger.com sign in my create
craigslist.com login N/A sign up
deviantart.com login N/A become/join
ebay.com sign in my register
facebook.com login my sign up
flickr.com sign in your create
fotolog.com log in/login my join
friendster.com log in my sign up
go.com (espn) sign in my register
google.com sign in my create
hi5.com log in my join
imageshack.us login my signup
imdb.com login my register
live.com sign in my sign up
mininova.com login my register
msn.com sign in my sign up
myspace.com login my sign up
neopets.com login my sign up
photobucket.com log in my join
pogo.com sign in my register
rapidshare.com login my join
store.apple.com login* N/A create/set up
veoh.com log in my register
walmart.com sign in my create
wikipedia.org log in create
wordpress.com login my sign up
yahoo.com sign in my sign up
youporn.com login my register*
youtube.com log in my sign up

* Inconsistent

“My” is the clear winner over “Your”, with 27 mys, 3 yours, and 2 that avoid using possessive pronouns.

“Login” takes the edge over “Sign In”, 20-14. “Sign In”, however, seems to be more popular with the biggest of the big sites, like Yahoo, Microsoft’s sites, and Google. I’d say this is a tossup, and I have a feeling that in a few years signup with come to dominate. Of those using login, 13 use “login”, and 7 use “log in”, with the space.

There’s a plurality of choices for sign up, with “sign up” being used on 12 sites. 7 used join, 7 used register, 6 used create (an account), 1 used start, and 1 used enroll. This is not an independent choice, however, as “sign up” is often seen where “log in” is used, and sites that use “sign in” use something like “register”. AOL, Microsoft, and Yahoo use “sign in/sign up”. I suspect that some people think using such similar phrases would be confusing, and I agree, despite the appeal of the general consistency.

My preference is to use “my, “log in”, and “sign up”. “Join” seems ambiguous, “register” seems bureaucratic and expensive, while “create an account” just feels a little dorky.

Dishonorable Mention: The Apple Store, supposed paragon of usability and attention to detail, is the worst offender on this list in terms of mixing and matching the terms, often on the same page. They also fail miserably on one major point, there’s no logout button!

Scratching an Itch: The Open Data Bank

The Open Data BankEngineers, especially those of the software variety, have various types of projects to work on. Some pay the bills, some are for learning, some are to help others’ goals, and then there are the ones that we say “scratch an itch.”

It’s hard not to operate in a world of ideas without having a few of your own, and some ideas just keep popping up. If you’re lucky, someone else does it right and you can reap the benefits, but often you just have to go out and do it. These projects are often done at personal expense “to see if it works” or “because I can”, and not for fame or fortune. I have a few of these kicking around, and it was a new year’s resolution of mine to actual get some of them into the wild. So, as the first of these, I’d like to officially announce a new project that I’ve been working on (and one of the reasons for the lack of blog posts). The Open Data Bank.

The ODB is a simple idea. While tinkering with other projects, I’m often in need of data. Sometimes this is to test things out, sometimes it’s to get things started, but everytime it seems like I have to go and find it anew and coax it into some useful format. I assume that others like me have the same problem, and hopefully ODB will be a useful contribution to the tinkering ecosystem to complement other tools like open source libraries.

For the layman, the ODB is a place where we can put “open data”, that is to say, data that can be shared without restriction. Not only is the data open, but the formats it is shared in are open as well. Formats like XML and JSON don’t have to be licensed from anyone, and therefore people are free to write tools to read it.

If you’re interested in participating or just keeping track of the ODB, there’s a Google Group you can join and share info, ask questions, or offer ideas to improve it.

Generics: All or nothing?

I am a big fan of strong typing, so when Java 5 added support for generics, I started using them heavily. I don’t agree that that they “clean up” your code, because I see as many or more instances of type parameters, <Class>, as I used to see type casts, (Class). However, they do make code easier to read and follow.

I’ve also been using interfaces more and more over the years, and these days I’d say I use them on almost all of my beans. The lightweight multiple inheritance helps with organization, and when you’re dealing with libraries that monkey with the internal working of your code like proxied beans in Spring and Hibernate objects, interfaces are helpful if not required.

A while back, I inadvertently discovered a pitfall that had been plaguing a project of mine in a very confusing manner. Parameterizing a class should avoid class cast exceptions because of strong typing, but you have to be careful to keep it parameterized, or you can end up causing some very nasty runtime bugs. To illustrate, here is a simple example:

(forgive the formatting, WordPress’ editor is poor at handling code…

First we have a Person interface. People have IDs and vehicles.

package com.efsavage.generic;
import java.util.Set;
public interface Person<PK extends Comparable> {
public PK getId();
public void setId(PK id);
public Set<Vehicle> getVehicles();
public void setVehicles(Set<Vehicle> vehicles);
}

We also have a Vehicle interface, the fields of which are unimportant here:

package com.efsavage.generic;
public interface Vehicle { }

And we have an implementation of the Person interface:

package com.efsavage.generic;
import java.util.Set;
public class PersonImpl implements Person {
private Integer id;
private Set vehicles;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set getVehicles() {
return vehicles;
}
public void setVehicles(Set vehicles) {
this.vehicles = vehicles;
}
}

So now let’s write a little test:

package com.efsavage.generic;
import java.util.Set;
public class PersonTest {
public static void main(String[] args) {
Person me = new PersonImpl();
Person<Integer> you = new PersonImpl();
me.setId("5");
you.setId(5);
Set<String> myVehicles = me.getVehicles();
Set<Vehicle> yourVehicles = you.getVehicles();
}
}

This code compiles fine (though Eclipse will flag a few warnings). There’s two problems here.

Despite the fact that PersonImpl implements Person<Integer>, I’m able to set a string via me.setId(“5”), because I did not keep that parameter when I cast me to Person, without a parameter. I would have expected the parameter to be inferred here.

The other problem is that I’m able to cast myVehicles to Set<String>! This wasn’t even a parameter I defined, it’s right in Person. However, by using Person without the PK parameter, Java ignores all other parameters too!

I’m sure someone thought this was a good idea, and there’s a reasonable explanation deep in the JCP forums, but it just seems wrong to me, so be careful to check your parameters if you find weird class cast exceptions showing up in your logs.

Usernames

Usernames for most websites are based on UNIX conventions/standards. They are lowercase, usually begin with letters, and have no whitespace. Many sites offer a “display name” which is more flexible.

While discussing requirements for a new project, my first inclination was to do something similar, simply because “that’s how it’s done”, but someone suggested this method might be antiquated. After giving it a few days of thought, I tend to agree. “Old” user domains like AOL, Windows, and Slashdot have logins that have allowed spaces for years, yet most of even the latest, shiniest Web 2.0 sites go back to the 1970s for their guidelines.

We’ve even taken it a little further and not only can users use spaces, underscores, and dashes, these characters are ignored for purposes of uniqueness, because I’m guessing people’s brains will tend to stem these characters when it comes to memorizing them. So “Eric Savage” and “ericsavage” and “Eric_Savage” and even something like “Eri__c-SAVA g-_E” would all be the same.

When appearing in a URL or other machine-readable context, these characters are all changed to underscore and consecutive duplicates are eliminated, so the previous username would be “eric_savage”. Also, leading and trailing non-alphanumerics are stripped, otherwise we’d likely find users all naming themselves __alphadog so they appear first alphabetically. We could expand the list of which extra characters are allowed, but we’ll start off easy.

Questions:

    Can anyone think of good reasons for why you should stick to UNIX-style usernames?
  • Should users on a community site be able to change usernames? [I’m currently in the “no” camp]
  • If changeable, should the change history be public?
  • Most people like short usernames, some people prefer long ones. What do you think should be the limit? [I’m currently thinking 20]
  • Is a short limit too ethnocentric?

21st Century Game Changers

A post on the Freakonomics blog got me thinking. What inventions have genuinely improved, or even affected, my life. I drew up a list, and decided to constrain it to the 21st century, so things like the cellphone, the VCR, the CD, the ATM, instant messaging, and online banking aren’t on the list. Here they are, and where possible I put the approximate year I adopted them.

Major Improvement to Daily Life

  • Tivo (2000) – Definitely #1 on the list. I don’t consider myself a couch potato, but this completely unshackled me from the network’s arbitrary scheduling. It also make more shows enjoyable, or even watchable, by cutting out commercials.
  • RSS/Google Reader (2002, 2005) – RSS enabled me to keep track of a much broader set of sources, and Google Reader took RSS to the next level by making my subscriptions and unread articles available anywhere (including my phone).
  • Smartphone (2006) – I’m far more organized now that I have my full contact list and calendar on me at all times, as well as being backed up, plus last-resort internet access is a nice bonus.
  • TV shows on DVD (2003) – There’s now a new category of TV show, the ones I don’t even bother to Tivo and just wait for the DVD.

Minor Quality-of-Life Improvement

  • Netflix (2002) – Like they say, no more late fees.
  • Wifi (2004) – Adopted later than most geeks, has proven useful in many ways.
  • Wikipedia (2003?) – Coming from someone who used to read the encyclopedia for fun, Wikipedia is like crack.
  • Text Messaging (2006) – Late to the game here. Enables a new layer of communcation and makes me both more responsive and more proactive.
  • GPS (2007) – I waited a while for the price dip, and now consider GPS a mandatory item for my car.
  • mp3 player/iPod (2002/2004) – No more discman and CD cases is a good thing.
  • Digital Camera/DSLR (2001, 2004, 2007) – I’m too lazy to deal with film. I got my first digital in 2001, my first nice one in 2004, and my first digital SLR in 2007, each a vast improvement over the previous.
  • Firefox (2004) – Firefox has gone from lightweight security-minded browser to bloated, customizable security-minded browser, both of which I’ve found value in.
  • Eclipse (2002) – Java wins in my book because of Eclipse. Having a program that thinks for you enables you to think about the real problems.
  • Launchcast (now Yahoo! Music) (2002) – One of the earliest and still one of the best customized music services. If you’re not sold on Pandora and Last.fm it might be because they are are inferior versions of Launch.

(supposedly) Major Advances, Adopted by Me, Negligible Impact

  • Social Networks (2004) – I use LinkedIn as a sort of resume-light, and myspace to keep up with my sisters, and facebook as the site du jour, but they are all just curious diversions.
  • OS X (2005) – Scores high on sexiness. Scores low on stability & usability
  • XP/Vista (2003) – Windows 2000 made computers better and more useful. XP and Vista seem to just make them slower.

Major Advances, Unadopted by Me

  • VoIP/Skype – I don’t use landlines.
  • Fastlane/Speedpass – I still find the ease with which someone can track me disturbing, plus the lines these days are usually shorter at the cash lines.

There’s probably some that I missed, or just weren’t important enough to remember. My main question is, what’s next to get on the list, and where on the list will it end up?

Wish List: Session Moratorium

DetourA feature that the major open-source/free servlet containers (Tomcat, Jetty, Resin) lack, AFAIK, is the ability to tell the container to stop issuing new sessions, and more importantly, make this flag known to the HTTP server connector. One or more of Websphere, Weblogic, and ATG Dynamo (I forget which) has this ability, and it’s extremely useful for higher-volume websites.

How it works: Server Bank A is running, Server Bank B is dormant. When you have a new release, you push it to B. Once B is up and running (this can take a while with some advanced applications), you tell A to stop issuing new sessions, and the load balancers send all new traffic to B. Once traffic has bled off of A entirely, A becomes dormant, and is ready for the next release.

Why it’s valuable: You can do a release without interrupting any sessions. This was particularly valuable on the project we used it on, because there was plenty of time to pre-compile pages, and the transactions were relatively high-value ones, so it was worth the price of the commercial license to ensure that none were lost or interrupted.

Considering all of the containers are relatively close performance-wise, and feature-wise, I think this would be a “killer feature” for any OSS container that had it.

Enabling Buttons on Apple Keyboard in Windows

I recently picked up, and am liking, the new “wafer thin” aluminum keyboard from Apple. Its very small, I like the key action and it’s very solid considering it’s size and thickness. But, I use it on Windows, and there’s no driver available other than the standard keyboard one, so the extra keys like media controls aren’t enabled. I came across a freeware macro program called AutoHotKey that works very nicely, and wrote up a few little scripts for it. You can download AutoHotKey and run the scripts yourself, or you can download the compiled version here [enable_mac_aluminum.zip, 193KB] and just pop it into your Startup folder.

Commands:
Shift-F3: Print Screen
Shift-F4: Task Manager
Shift-F7: Previous Track (in Winamp or Yahoo! Music Jukebox)
Shift-F8: Pause/Play (in Winamp or Yahoo! Music Jukebox)
Shift-F9: Next Track (in Winamp or Yahoo! Music Jukebox)
Shift-F10: Mute/Unmute
Shift-F11: Volume Down
Shift-F12: Volume Up
Windows-s: Open http://www.efsavage.com 🙂

Here’s the entire script:

#s::Run www.efsavage.com
+F3::Send {PrintScreen}
+F4::Send, {SHIFTDOWN}{CTRLDOWN}{ESC}{SHIFTUP}{CTRLUP}
+F7::
IfWinExist ahk_class Winamp v1.x
{
ControlSend, ahk_parent, z ; Pause/Unpause
return
}
IfWinExist ahk_class YMPFrame
{
SetTitleMatchMode 2
IfWinNotActive, Yahoo! Music Jukebox
WinActivate
WinWaitActive, Yahoo! Music Jukebox
MouseClick, left, 29, 107
Sleep, 100
MouseClick, left, 112, 76
WinMinimize
return
}
return
+F8::
IfWinExist ahk_class Winamp v1.x
{
ControlSend, ahk_parent, c ; Pause/Unpause
return
}
IfWinExist ahk_class YMPFrame
{
SetTitleMatchMode 2
IfWinNotActive, Yahoo! Music Jukebox
WinActivate
WinWaitActive, Yahoo! Music Jukebox
MouseClick, left, 29, 107
Sleep, 100
MouseClick, left, 30, 77
WinMinimize
return
}
return
+F9::
IfWinExist ahk_class Winamp v1.x
{
ControlSend, ahk_parent, b ; Pause/Unpause
return
}
IfWinExist ahk_class YMPFrame
{
SetTitleMatchMode 2
IfWinNotActive, Yahoo! Music Jukebox
WinActivate
WinWaitActive, Yahoo! Music Jukebox
MouseClick, left, 29, 107
Sleep, 100
MouseClick, left, 148, 79
WinMinimize
return
}
return
+F10::Send {Volume_Mute}
+F11::Send {Volume_Down 3}
+F12::Send {Volume_Up}

Update: Reader Svolte points us to SharpKeys, which (by default) maps F13 to print screen. The advantage of doing this is that alt-print-screen (capture just active window) works, while I was unable to replicate with the AutoHotKey script.