Crazy Java/Windows problem and some Scheming

May 12, 2009 at 8:34 pm (Java, Limelight, Ruby, Scheme, Week 8) (, , , , , )

As soon as I came in this morning, Micah asked for my help with a bug he’d been working on tracking down in some Java JNA code in the Limelight source. The gist of the code is that it was calling some native code in Windows DLLs, and about half the time, one of the API hooks didn’t get properly installed. We looked and looked, eventually doing some print statements looking for threading issues and other possibilities. Take a look at the code and see if you can spot the problem:

new Thread()
{
  public void run()
  {
    W32API.HINSTANCE appInstance = Kernel32.INSTANCE.GetModuleHandle(null);
    final User32.HHOOK keystrokeHook = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, new KeyboardHandler(), appInstance, 0);
    hookThreadId = Kernel32.INSTANCE.GetCurrentThreadId();
    MsgLoop();
    User32.INSTANCE.UnhookWindowsHookEx(keystrokeHook);
  }
}

Well, if you knew right away that the new KeyboardHandler() might sometimes get garbage collected before the Windows code gets around to calling it, then you’re lying. Just kidding! I am very impressed if so. Once we looked back on the problem, we could see how the problem might have happened, but it was really bizarre. The idea is that because we don’t hold onto a reference to the new KeyboardHandler() that we create, the garbage collector could think we’re all done with it, even though the Windows code really needs to hold onto it. We didn’t look in depth into how JNA translates the Java code into native Windows code, but Micah understands it, and I think he said it passes a function pointer to the Windows code in this case, so when Windows tries to callback to our Java code residing in that pointer, that code is no longer there. Wacky.

We also made an installer using install4j, which seemed really easy. I’m not sure how much setup Micah had already done, but we were able to drop in some custom icons and a splash screen really easily for our application, and it looks good on both Mac and Windows. I did my first work in Photoshop CS 3, and it was weird not so have the Save Optimized As.. option that I’m used to from Photoshop/ImageReady CS.

I spent some time this afternoon practicing recursion by writing methods to identify palindromes. I did it in Scheme, Ruby, and Java (in that order), all TDD, all in different editors. Of course, Ruby was the easiest and clearest by the end (negative array indexing helped out!), but Scheme wasn’t as hard as I’d expected. Things may be getting easier!

By the way, if anyone else is going through SICP and feeling like you need some more interesting assignments than reading the online book and watching the lectures, check out the sample programming assignments on the website. Even the first one (Exercise 11) might blow your mind if you’re like me and not so used to functional programming.

Here’s a taste:

(define foo6
  (lambda (x)
    (x (lambda (y) (y y))))

Give a Curried application of foo6 that evaluates to 3. Keep in mind this means that at some point you have to evaluate an expression which is a function applied to itself! Yikes. I’ll post my solution later, if anybody’s interested, but I don’t want to give it away too easily. I probably spent a good hour thinking this last one over, and learned to think in a different way in the process.

I need to find a new way of embedding code in this blog. Since it’s hosted on WordPress, I can’t include Javascript embeds of a Gist or Pastie, and I also don’t really have control over the styling. Any suggestions?

Advertisements

Permalink 1 Comment