I've been writing a JNI wrapper that requires the creation of a native thread and I've set things up using a JNI_OnLoad() function to initialise the DLL and create an event handling thread thread. I also used the JNI_OnUnload() function to kill the thread and clean up the DLL, but what was puzzling me was that although JNI_OnLoad() was being called OK, JNI_OnUnload() was never being called, and because the thread was attached to the JVM via a call to AttachCurrentThread(), the JVM would never exit as it still had an active thread. A simple workaround was to attach the thread to the JVM as a daemon thread using AttachCurrentThreadAsDaemon as daemon threads don't keep the JVM alive, but that still meant the DLL wasn't being cleaned up properly.
Google revealed a post on the Java Forums which explained that the ClassLoader was keeping a reference to the class containing the native code wrapping the DLL, and that was preventing the JNI_OnUnload() function from being called. The post also explains that if you make a call to System.runFinalizersOnExit() then the finalizer for the ClassLoader will be called on exit and that in turn will call the native code's JNI_OnUnload() method, and a simple experiment proves that is indeed the case. However the System.runFinalizersOnExit() method is deprecated:
This method is inherently unsafe. It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock.
In light of this it appears that although JNI_OnLoad() is useful, JNI_OnUnload() is less than useful. There is a workaround, which is to register a native exit callback using Runtime.addShutdownHook() and do the cleanup that way, but it's kind of broken that JNI_OnUnload() doesn't actually do what it is supposed to, and even more odd that the JNI documentation is completely silent as to why it doesn't actually work. I think I feel a bug report coming on ;-)
Picked this tip up off slashdot - some websites (e.g. the Washington Post) insist on making you register to read their content, even if the content is actually free - the assumption is that they only want the registration so they can harvest your email address and use it for marketing purposes, and as someone who gets huge volumes of spam already (despite 500+ a day caught by the corporate filters, 40-50 still get through) I'm very loathe to give out my email address when I don't have to. Although there are services such as BugMeNot which allow you to create a throw-away email address for registration and to look up already registered addresses, the webmasters of the sites that require registration cotton on to these pretty fast and block them.
However, these selfsame sites obviously want google to index them, so they allow the google search robot in without requiring registration. Enter the User Agent Switcher plugin for Firefox. I've used this in the past to get access sites that insist you use Internet Explorer to view them, but you can add an entry to make your browser look like it is the google bot. In the Description field put whatever you want to identify the entry, and in the User Agent field put the string
googlebot/2.1 (+http://www.google.com/bot.html), you can leave the rest of the fields empty. Switch to the new User Agent string and hey presto, all that content you couldn't previously access is visible. Unlike the disposable email address arms race, I don't see how this can be circumvented without making the content invisible to Google as well.