Monday Sep 27, 2010


Since I no longer work for Sun/Oracle, this blog is closed; please visit my new personal blog at .

Friday Sep 24, 2010


It's time for a new adventure!

I joined Sun in 1996 and I've been here ever since -- including the Oracle acquisition six months ago. It's been a wonderful time. I've met many of the world's most talented engineers, I've had the chance to work on some interesting projects and I've learned a lot! I looked at my badge that I'm about to turn in (picture on left) and it has the original photo taken when I joined -- and I look like a kid!!

However, it's time to move on. I've chosen to take a new opportunity where I'll get to have even more fun. For now, I'd like to thank all my former Sun and Oracle coworkers for the great experiences you've given me and wish you luck with the future!

I feel privileged that so many of you have read my blog from time to time, and I would be honored if you'd follow me over to my new permanent blog:


Thursday Sep 23, 2010

Moving My Blog

I've decided to move my blog to a more permanent URL (I'm not sure how long will be around), and at the same time it would be nice to switch to a more feature-rich blogging platform. Therefore, effective immediately, the new url for my blog is:

I'm hoping most of you will update your links and follow me over there. I plan to start writing more actively again, and I have a number of new things I can talk about soon!

P.S. I've documented what I did to migrate Roller to Blogger here in case there are other users who have similar needs.

Tuesday May 11, 2010

Bay Area JUG Roundup 2010

If you live in the San Francisco bay area, I hope you can come to the Bay Area Java User Group Roundup 2010 tomorrow night! It is going to be held at the Oracle conference center, and both beer and dinner will be provided. There will be an update on the migration, and the Java Posse are going to record a live podcast. Note - you need to sign up in advance so visit the event details page.

Hope to see you there!

Monday Mar 01, 2010

Using Mercurial over ssh without typing the password

We're using Mercurial. Our release engineering servers run web servers, so we can browse our repositories, just like the public NetBeans ones at, and pull down new changesets anonymously. However, for authentication purposes, we also use ssh, so all pushes to the repository has to go through ssh.

$ cat .hg/hgrc
default =
default-push = ssh://

(P.S. Notice how there are 2 slashes in the SSH path and only one in the http path - if you forget about that Bad Stuff(tm) happens.)

This means that whenever I pull (or determine incoming changes via hg incoming) it executes immediately, but whenever I want to push (or determine outgoing changes), I need to supply a password. And let's just say typing my password is not easy, since the password requirements at Sun (and shortly, Oracle) are really strict - no nice, short and simple passwords here!

I've been putting up with it for a year now - after all, it's just a couple of seconds here and a couple of seconds there - but I knew it should be possible to fix this, since back in my hardcore Solaris days I had all this stuff configured correctly via the ssh key agent so that I could ssh from one account to the next. On the other hand, I've googled it (mercurial + ssh) a couple of times, and the information I've found has always been for doing more complicated things (1,2) than the simple authentication setup I wanted. So I just put it off.

I decided to bite the bullet and look into configuring it - and it was really trivial. I'm bummed I haven't tried earlier! I thought I'd write this up in case it helps anyone else in a similar situation.

The reason it's trivial, is that it turns out there is nothing specific about using Mercurial here. This is actually a case where Googling something was harmful! If I had just tried it, instead of searching for a recipe and getting confused, I would have had this set up a long time ago! Hopefully this blog entry will help anyone searching for "hg ssh passwords" ! Anyway... You just need to ensure that you can ssh directly into the system you are trying to push to, and if you can do that, then mercurial can do the rest. And this setup is easy and well documented.

First, you need to generate a local key.

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/tor/.ssh/id_rsa):
Created directory '/Users/tor/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/tor/.ssh/id_rsa.
Your public key has been saved in /Users/tor/.ssh/
The key fingerprint is:
... (omitted) ...

Next you need to copy this file to the server and call it ~/.ssh/authorized_keys. Actually, that file may already exist and you really want to append to it, not replace it. So first ensure the directory exists:

$ ssh mkdir -p .ssh

And finally copy your authentication key over to the server:

$ scp .ssh/
Password: 100% 422 0.4KB/s 00:00

That's it! Now try logging in again:

$ ssh

On my Mac, this actually pops up the system authentication dialog:

Not only can I enter my password in the dialog, but I can tell it to remember this key in the keychain, and from now on, the system supplies the password to ssh when it wants to log in to hosts.

$ ssh
Identity added: details omitted
Last login: Mon Mar 1 19:22:18 2010

And now, the whole point of this exercise -- I can run "hg out" and "hg push" (as well as scripts which operate over multiple mercurial repositories) without the need to type that annoying password again. On the other hand, how will I remember it now that I'm not repeating it like a mantra dozens of times per day?

$ hg out
comparing with ssh://
searching for changes
no changes found

P.S. Here's a copy of my own authentication keys in case that helps you configure your own system. Please don't use these to log into our system.

Monday Jul 06, 2009

Back from Vacation

I'm back from a nice but short vacation. We didn't have a detailed itinerary - we just took one day at a time and decided where to head next. We spent several days in the old Gold Rush country in the Sierra foothills - there were many things to see, such as museums, mines and caverns, and a preserved whole gold rush town with original buildings, a no-cars main road and all employees wearing authentic clothing. From there we visited the central coast and went to several of the original Missions, and ended up seeing the 4th of July fireworks from the beach in Santa Barbara. While I was gone I see that NetBeans 6.7, and Virtual Box 3.0 have both been released. Both should help me as I get back to work...

Tuesday May 12, 2009 least my house didn't burn down!

As I was working yesterday my laptop felt kinda wobbly. I didn't think too much about it. But it started getting annoying. I lifted the laptop and looked under it to make sure my laptop wasn't accidentally sitting on top of a USB cable or something like that. Nope.

A little while later I was getting really annoyed - so I flipped the computer all the over to see what was up. And to my surprise my battery was completely warped. It looks like it had "exploded" sometime this weekend. Check out how warped it is:

A couple of years ago one of my Apple power supplies would make humming noices now and then, and one day I happened to be looking at it when it shot some sparks! Luckily I had a floor mat so any previous sparks hadn't ignited the carpet. I got that adapter replaced. But I'm definitely thankful neither incident caused fires!

Monday Apr 27, 2009

Nice touch, Skype!

I work from home, so I rely heavily on Instant Messaging and IRC to communicate with my co-workers, and for video conferencing I use Skype.

I sometimes make typing mistakes. And if the typo is particularly embarrassing, to the extent that I want to fix it to show that I know better,
I usually write something like this:

12:00 I agre.
12:00 s/agre/agree/

Anybody with vi experience or even sed experience will recognize the second line as a search/replace command, so I'm really saying "I said agre but I meant agree". It's reflex at this point - I'll do it for the most minor accident.

I usually only use Skype for video conferencing, not instant messaging. But I just discovered, by accident, that Skype does something wonderful. Instead of showing my substitution command, it applies it to the previous line, instantly, on both sides of the conversation! Look at this:

Ugh, typo, reflexively type s/foo/bar


Instead of adding my correction command to the log for the viewer to interpret, it just edited the previous command in place. If I can type this quickly enough, perhaps the reader won't notice!

Chatzilla, Adium, Others - Please please please do this too!

P.S. On the topic of terminal conventions.... I like using \^H's as a "just kidding" device:

12:00 Ok, I'll slap\^H\^H\^H\^H tell him about it.

Anyone who's logged into terminals with wrong tty settings will recognize the \^H's as failed backspaces... And I don't want IM clients processing these :)

Tuesday Dec 23, 2008

VirtualBox Rocks!

In order to get code coverage to work seamlessly in the presence of the Rake build tool, I had to do some pretty ugly tricks - a lot of path manipulation that surely won't work on Windows. Rather than just getting bug reports, I'll need to debug through it to find the troublespots and fix them.

I don't have a Windows machine. I have a Solaris desktop box, and a Mac laptop. And since I don't have any short term plans to go in to the office (I work from home most of the time) I don't want to wait to look into this until my next chance to stop by a computer lab with Windows machines.

So, I decided to dust off the VirtualBox instance I installed and tested a while back. Back then, it worked fine - but was a bit painful to use. Actually, it was my fault. I never went and "finished" my installation. Turns out, after installing Windows on the virtual machine, there is some additional software shipped with VirtualBox that can be installed into Windows to make things work more smoothly.
For example, a special mouse driver makes the Mac mouse also work as the Windows mouse. There's support to share file systems. This is a huge benefit. I simply mapped my working source tree that I have already checked out, edited and built, as a new Windows drive! I didn't have to go and install Mercurial, Python, check out the whole NeBeans source tree, build it, etc. I could simply open up drive Z:, and run the NetBeans IDE from within Windows!

Another cool thing these special tools add is "seamless mode". I'm running the Windows applications running as if they are regular Mac applications on my Mac desktop! So I can debug through my Windows instance of NetBeans while at the same time having my Mac mail and instant messaging programs part of the screen. Look at the below screenshot (click for full size) -- I have the Mac doc on the left, and the Windows doc on the bottom - as well as a mixture of Mac and Windows (uhm) windows on the desktop!

There's my mailtool again... Last year I posted a screenshot showing how I had 13,000 unread mails, but plans to finally catch up. I guess I didn't put that high enough up on my priority list. The above screenshot shows how I'm up to 56,000 unread mails now. Ugh. Oh well, at least the number of unread mails addressed directly to me is decreasing.

Wow. Installation was flawless. It's working beautifully. And it's free. And it's open source. Wow. Oh, and it runs on many other platforms as well.

As I wrote this blog entry I looked up the VirtualBox home page to I could link to it, and I discovered a news blurb:

New Dec 17, 2008

VirtualBox 2.1.0 released!

Sun today released VirtualBox 2.1.0, a major update with exciting new features: among them better 64-bit support, hardware virtualization on the Mac, 3D acceleration, easier networking on Windows and Linux plus full VMDK/VHD support including snapshots. See the ChangeLog for a detailed list of changes.

I just installed it and took it for a quick spin, and things are looking great.

P.S. One little tip: Installing the Guest Additions into Windows is easy - there's a menu item in the Device menu, "Install Guest Additions...". I tried it, and it popped up an installer inside Windows. But since I was in the middle of applying service packs to Windows, I dismissed it so I could deal with it after my service pack upgrade reboot. But when I tried it later, it didn't work! Uh oh, is this incompatible with service pack 3 I wonder? Nope, it's much simpler than that. What "Install Guest Additions..." does, is mount a new CD-ROM into Windows. I'm guessing Service Pack 3 turns off auto-run! Probably a security thing. So all I had to do was open the computer folder, and click on the CD-ROM there to run the installer.

Oh, one other tip: The default RAM allocated to the virtual machine is pretty small: 512Mb. In the Settings for the machine you can crank it up bigger - I set it to 2 Gb. That makes the machine run quite a bit faster under load since it's not continually swapping to disk for virtual memory.

Friday Oct 31, 2008

Mercurial Tip: Checking in regularly with uncommitted changes in your clone

NetBeans, like OpenJDK and OpenSolaris, uses the Mercurial distributed version control system. I'm a big fan of of distributed version control. However, one thing that drives me nuts is this error message:

% hg merge
abort: outstanding uncommitted changes

This isn't just going to be a rant - I've finally found a solution which is working extremely well for me. I've suggested it to some other developers who have also reported that it works well for them, so I thought I would share it with you.

The reason I run into this all the time is my preferred style of work:

  • I like to work on many things simultaneously. If while working on something, I come across a bug and I spot the problem, I just fix it right there and add a test for it. When I get ideas, I might go and put @todo tasks for myself, or leave editorial comments in various source files. I might also work on a couple of larger tasks simultaneously. Yes, I know the preferred Mercurial idiom for this is to have multiple clones, one for each task - but that isn't my preferred way of doing it. Each NetBeans clone is huge and takes a while to both clone and build - and I would have to switch my IDE editing context between these large source trees all the time.

  • I like to check things in in logical chunks with a message that pertains to that particular change. This means I often check in a subset of the edited files in the tree.

  • I like to check in code regularly rather than leaving all files edited until I'm ready to check everything in.

  • I like to keep up to date. I'm using the bits I'm working on and I report problems when I see them so I want to make sure these are truly new and current bugs. Therefore, I update to the tip at least every day.

It turns out that the above requirements are tricky to fulfill with a default setup. Here's what happens.

  • I'm working on something and a high priority bug comes in. I find and fix it. I check in just the fix for this one problem. I
    still have many other edited files in my clone since I was in the middle of something else.

  • Since it's a high priority bug, I want to push it. However, when I do, I get this:

    % hg push
    pushing to https://tor:\*\*\*
    searching for changes
    abort: push creates new remote heads!
    (did you forget to merge? use push -f to force)

    This tells me that somebody has checked in something since my last pull. That happens a lot with a project like NetBeans
    where there are checkins every few minutes.

  • No problem - I'll just pull down their changes, merge, and push again, right?

    % hg pull && hg update
    pulling from
    searching for changes
    adding changesets
    adding manifests
    adding file changes
    added 1 changesets with 1 changes to 1 files (+1 heads)
    (run 'hg heads' to see heads, 'hg merge' to merge)
    abort: crosses branches (use 'hg merge' or 'hg update -C')

  • Ah, I couldn't just update, I have to merge since I have checked in changesets of my own. Let's do that:

    % hg merge
    abort: outstanding uncommitted changes

    !@#@%\*#%$%&\*$ ! Now, if I have dozens of changes, what do I do? When I first started using Mercurial, I would either
    try to finish my other changes and check them in and then try the merge again, or if I really wasn't ready to do that,
    I would copy the contents of my modified files to another location, hg revert the changes, and try again.

  • It's not unreasonable of Mercurial to insist that you cannot merge with uncommitted changes. When it's merging, it will think
    file modifications in the clone are your manual edits to resolve any merge conflicts. However, it does make using
    my workflow difficult.

    The Solution

    It's really very simple: Use two clones. Do all your work in clone "main", and all your merging and pushing from clone "sync".
    Let's say the main repository is "master", and your two clones are "main" and "sync":

    To get set up, either clone the master repository twice, or, you can clone your main locally, but be sure to update
    the "parent" reference in your sync clone such that it points to the master instead of your working clone
    (I do that by copying main/.hg/hgrc to sync/.hg/hgrc.)

    Here's the new workflow:

    1. As before, work in main. Edit files at will, and check in logical changesets as needed.

    2. When you want to push a changeset, go to your sync clone, and pull your new changesets from your working clone:

      % cd ../sync
      % hg pull ../main && hg update

      At this point, it's best to try a build/test as well, to make sure changeset is complete. If you're working
      on many things in parallel, it's possible that your changeset is depending on a change in a file you haven't
      checked in yet.

    3. Now pull in the new changes from the master, and merge these:

      % hg fetch

      (Or if don't have the fetch extension installed, do it manually - hg pull && hg merge && hg ci -m "Merge").

    4. If something went wrong with the merge - no problem. You can just go and nuke the entire sync clone
      and try again! Your modified files, and your new changesets, are still sitting completely unaffected in the main
      clone. Just clone sync again and try more carefully :)

    5. Now you can push your merged changesets to the master repository:

      % hg push

    6. ...and now you can pull these changes back into your main repository:

      % hg pull ../sync && hg update

      This will give you all the tip changes into your working clone, but without the risk of causing multiple heads that you
      have to merge. You've already merged your local changesets over in the sync clone, and therefore there is no
      conflict between your local changesets and the new changesets in the tip!

    This process may seem tricky, but it's trivial once you try it:

    Work in main, push and merge in sync, and pull back into main.

    Finally, I want to call attention to item #4. Doing it this way means that it's trivial to try again if something wrong happens
    during the merge. I've had a couple of merges where I've really mucked things up. Unfortunately, this was in my tree that contained
    the changesets that I cared about. In the end I had to go and manually copy out the files I wanted to check in and try again. With
    the above approach, if something goes wrong, just nuke the sync clone and try again.

    This is the reason I'm suggesting this approach to anyone using Mercurial, not just people who want to work with edited files.
    Especially when you're new to distributed version control systems or Mercurial, it's great to be able to go back if you make
    a mistake. Just make sure you know what you're doing before you submit that final hg push command to push everything
    back to the master repository!

Wednesday Nov 21, 2007

Quick Hi

No screenshot-of-the-week this time; I'm taking the week off since the kids are out of school for whole the week. I'm having a lot of fun!

Meanwhile, Cindy Church has been busy creating more demo videos on
First, there's the classical

weblog tutorial
and then there's showing how to

write and run unit tests
in the IDE (where I'm incidentally also
using the Dark Pastels color theme I've discussed previously on this blog). We recently met and
recorded more material, so there are more screencasts in the pipeline. P.S.: Both screencasts are also available in higher definition as downloadable Quicktime files - see the "QuickTime format of this screencast" hyperlinks near the bottom.

Ok, back to vacation!

Friday Apr 20, 2007

Upcoming Gigs

It's been a busy month, and it's only going to get busier. Here are some public speaking events that are coming up - I hope you can make it to some of them:

  • I will be speaking at the SD Forum Ruby Conference this weekend, at the San Jose tech museum, with JRuby developer Nick Sieger
  • I have a technical session coming up at JavaOne, TS-9972, along with Martin Krauskopf who is developing the Ruby debugger for NetBeans. It's Thursday afternoon the week of JavaOne.
  • I will also be speaking at NetBeans Day in a Ruby session along with JRuby developers Tom Enebo and Charlie Nutter
  • The JavaPosse also has several appearances - there's our BOF Tuesday night at 10pm, we'll be the "lunch entertainment" at NetBeans Day, and we're also planning to do a live episode the following week at the Silicon Valley JUG.
  • Finally, I was recently interviewed on the SDN channel regarding the NetBeans Ruby support. You can find the episode here (you can also subscribe to the SDN via iTunes, it's a video podcast). My segment is about 16 minutes into it, following sections on NetBeans 6 by Tim Boudreau and a Matisse demo by Roman Strobl.

P.S. Another demo tutorial for the NetBeans Ruby on Rails support was just published - it's here. Along with Roman's demo, these are now shipping as sample applications, so you can download the applications themselves and play with the bits.

Sunday Jul 23, 2006

Hot hot hot!

It's unbelievably hot where I live! 111 degrees Fahrenheit in the shade - that's 44 degrees Celsius. My thermometer said 115 F, and I can believe that since I live in a part of town that is hotter than downtown where the official temperature is taken.

This of course is not conducive to working! Unfortunately, there is nothing good on TV - and I've seen all the movies in the movie theaters that according to critics are worth seeing. Not a large percentage might I add.

At least we get cool nights in California, so I can spend the morning hours web surfing a bit until it gets unbearable. Oliver Widder has posted a cartoon related to coding styles (a frequent topic on my blog). A number of people have expressed an interested in this, so it will probably be the topic of an upcoming Java Posse episode.

P.S. My favorite drink to consume in the heat is the Mojito. It's made with ice, mint, rum, lime, and sugar. Unlike the original recipe (google it), I actually blend all the ingredients in a blender such that you get pureed mint leaves in the drink. This gives it a stronger mint flavor - which is a good thing!

Tuesday Jul 11, 2006

The Trouble With Password Entry Pads...

The problem with password entry pads is this:

Gee, do you think my password has any 2's in it? How about 9's?

I've had my digital token card for nearly ten years now. Amazingly, I've never had to change the battery. Anyway, while having token cards is an important part of security, this Slashdot story shows that even these schemes are becoming targets for phishing scams.

Monday Jun 26, 2006

Happy 10

Today is my 10 year anniversary at Sun Microsystems. When I joined June 26th 1996 I started working on Sun WorkShop, Sun's C, C++ and Fortran IDE. It's been IDEs ever since, most recently Creator and now, Semplice.

Here's to another exciting 10!


Tor Norbye


« February 2017