I first started to look into the Inversion of Control pattern only to reduce coupling between my classes. When I was “shopping around” for some IoC library, some described themselves as “microkernels”. I admit that Java is also a virtual machine, but I always though that a kernel is primarily for hardware abstraction and running multiple processes at once (at least since the 90s).
Yet those IoC libraries kept describing modules as “services”. In a way, a Singleton is a service, but in that sense lifecycle is restricted to initialization ordering, since once a Singleton-like service is loaded it stays in memory.
Actually, “service” or “process” patterns, that is run-time design, are orthogonal to “linking” patterns, that is coupling design. Naively I was focused only on coupling because in my UI-centric designs there are only a single thread, the UI event thread, other service threads being exceptional to some “progress bar” operations.
Only when I started designing code that heavily depended on multiple long-running dependent threads that I realized how much IoC libraries, including the core Spring Framework library, were not very good at handling service lifecycle. What if I want to cleanly unload an optional service? What if I want to load two versions of the same service at the same time? I can’t bash those libraries too much since dealing with lifecycle events for unloading modules is difficult to properly implement. Why do you think that even in the latest version of Firefox you still can’t unload a plug-in without restarting the whole process?
This is why I consider OSGi as a “real” microkernel. As in a real kernel, modules have independent classloaders. Modules can be loaded and unloaded at any time because only weak service references are kept. And it is almost assumed that each service represents one or more long running threads. So, a service reference (thead) plus it’s own classloader roughly equals a “process” in the Java Virtual Machine running OSGi as its microkernel.
IoC can still be used with OSGi, especially as a way of linking all those service references together with some simple XML configuration and no additional code, using the Spring Dynamic Modules for OSGi Service Platforms library. That way, I transformed my Singletons as module plus service “processes” for OSGi in no time.
Still, a problem remained: All those service treads (and in my case, thread pools) need to talk to each other. That felt like a huge design problem for me that would push me to my limits, yet I was sure somebody else already though about it before. Then, I contemplated this old book on my shelf about System V programming…
Published on July 4, 2010 at 07:14 EDT
Older post: Our National Moving Day
Newer post: IPC between services in the JVM: Part 3 of 4