When Kevin Humphreys and I wrote the first version of GATE back in the 1990s we used Tcl/Tk, a nice clean scripting language with an extensible C API underneath. One of the innovative things that Tcl provided was a dynamic loading mechanism, and I used it to allow CREOLE plugins to be reloaded at run-time. A year or two after we'd released the system I could often be heard cursing my stupidity — the reloading system worked well when it was configured, but getting it to run cross-platform at user sites with diverse collections of underlying shared C libraries was a huge pain in the bum.
Fast forward 15 years or so and the class loader code that I put into GATE version 2 (the first Java version) also has some pain associated with it, and it is a real pleasure to see this post with all its carefull study and presentation. Even better, a new chunk of code to take away one of the gotchas with classloading and memory consumption in long-running server processes. Nice one Mark!
One other thing springs to mind — the design choices that we took for GATE 2 (around the turn of the millenium, with a first release in 2002) turned out to be pretty good, by and large (more luck than judgement on my part, of course). GATE has mushroomed orders of magnitude beyond our original plan in the intervening period, but despite a few creaking joints it still holds its own. That's a credit to several of the long-term inmates of the GATE team, and also to Java (and its later offshoots like Spring, Groovy and Grails). It's easy to get blinded by the Next Big Thing in computing, but if you stand on solid foundations (and keep working on reusability and refactoring) you can have your cake and eat it!
(And sorry for the cheesy title.)