Home

News: OSGi: Addressing the Deficiencies of Inversion of Control (IoC)

  1. Read the article: OSGi: A Proven Approach for Modular Development

    Rod Johnson's comments on the applicablilty of OSGi created a firestorm of comments and interest from TheServerSide (TSS) community, prompting TSS to start digging deeper into the technology and search out the insights of some of the industry's experts. The current plan is to corral a series of article on the topic, from both the detractors and advocates of the technology, while throwing in a useful tutorial and expert tip on the subject when the timing is right.

    The first salvo in this OSGi discussion comes from Peter Kriens of the OSGi alliance, as he provides some background on the history of OSGi, and some insights on why an uninitiated Enterprise Java developer might initially have some reservations when looking at how OSGi tackles the topic of modularity.

    Of course, the preamble of the article is simply an appetized, whereas the ensuing discussion about indirection, loose coupling and the deficiencies of the Inversion of Control (IoC) mentality is the meat. Pontificating on the manner in which IoC frameworks like Spring achieve their end goals, Peter states the obvious when he says: "The problem is that IoC requires us to give up control in our code, the only place where we actually have full knowledge of the internal details."

    Indeed, that always has been one of the more peculiar curiosities about how modern applications are developed. Inversion of Control often seems more like an application has lost control. But does the OSGi approach have the capacity to address this devilish little detail of IoC? Peter is confident that OSGi unequivocally does.

    You can read Peter's insights into the topic here:

    OSGi: A Proven Approach for Modular Development

  2. The culprit is the IoC configuration as it concentrates (and thus couples) the implementation details, for example the XML in Spring.

    Sigh. It would really help if Peter included small yet complete example built with OSGI- and DI-way. And the article would benefit from explaining issues and benefits in terms of those specific examples.

    Without that I'm having a hard time to understand the stated issues, or categorize statements as an issues. And keep wondering if my DI applications are alike to Peter's ones.

  3. > Without that I'm having a hard time to understand the stated issues

    From a brief read of the article, it looks to be that Peter is saying that modularity is broken if anything other than the module itself needs to know the implementation class for an interface / service. i.e. putting FooImpl inside a Spring DI xml is a violation.

    His stated solution is to use names published to a broker; the service module registers the implementation class FooImpl under name "Foo", and the client module looks for the service under "Foo".

    The thing that then prevents this from becoming a pure service locator (with its known issues) is that the names that the client and service modules use are then injected via DI.

    At least, this is my reading of what he wrote.

    Andrew

  4. Yup![ Go to top ]

    Good summary! Thanks.

  5. Andrew: you're almost there but not quite. We don't register an implementation class FooImpl under the name Foo... we register an actual instance object under the name Foo. Of course that object in an instance of a class that extends the interface Foo.

    The neat thing about this is it allows the produce to control initialisation. With traditional DI, the producer has to produce an object on demand, whenever the DI container feels like asking for it. If there is any initialisation that needs to be done (e.g. starting up a database, waiting for a socket connection, etc) then we have to supply a partially initialised object and then internally handle all the extra states that arise from this. It can get quite complex.

    With OSGi services, the producer only registers objects when it wants to. Therefore it only needs to register fully initialised objects, and those objects know they will only be invoked by consumers when they are in their initialised state. If some external event causes the object to be in an invalid state, we can just remove it from the registry, and know that clients will no longer try to invoke it.

  6. We don't register an implementation class FooImpl under the name Foo... we register an actual instance object under the name Foo.

    On a tangent - it seems like people are using different definitions of the term "modularity". Some of these intrinsically include concepts like information hiding, others just focus on separating out the public interface of a module.

    Do you know of a page or definition that succinctly captures the definition of "modular"? Does it just boil down to an enforced separation of public interface and private implementation?

  7. Definition[ Go to top ]

    I've never been able to find a good definition of modularity but I recognize it when I see it. For me, modularity is different rules on the inside of a module than on the outside. It usually goes with explicit sharing with other modules. The identity aspect of modules allows you handle dependencies.

  8. Not clear[ Go to top ]

    Sorry it is not well understood. I tried to shy away from OSGi specific examples as I want to show that IoC requires access to internal module details. I.e. that most of the problems reported with OSGi are not OSGi specific, it is just the messenger. Same problems will occur in any module system, for example Jigsaw.

    The litmus test is if you can rename an implementation class without changing ANYTHING outside your module.

    In Spring all control is delegated to a more or less central XML file that needs to know all your imlementations.

     

  9. Re: Not clear[ Go to top ]

    The litmus test is if you can rename an implementation class without changing ANYTHING outside your module.

    In Spring all control is delegated to a more or less central XML file that needs to know all your imlementations.

    You know you can use annotations in combination with scanning to wire up all dependencies in Spring without specifying any classes in the XML configuration?

  10. Re: Not clear[ Go to top ]

    The litmus test is if you can rename an implementation class without changing ANYTHING outside your module.

    In Spring all control is delegated to a more or less central XML file that needs to know all your imlementations.

    You know you can use annotations in combination with scanning to wire up all dependencies in Spring without specifying any classes in the XML configuration?

    If a developer uses annotations to define which concrete class to use for DI, doesn't it changing the annotation to use a different concrete class?

  11. Annotations[ Go to top ]

    Johan,

    Spring's annotations are about the injection sites in the client code. However, the creating of the actual beans to be injected are still defined in the XML, violating the providers privacy. So annotations alleviate only one half of the violations. And this at the cost of a new language implemented in Annotations or annotations of annotations ...

    In OSGi, both the provider as well as the client can fully hide implementation details and only export a service. I.e. OSGi is peer-to-peer where Spring XML is centralized.

    Peter Kriens

     

  12. Cameron in my opinion the most serious problem of IoC is the VIRAL nature of current IoC approaches and frameworks, for instance to get injected an attribute with a singleton object, the lifecycle of the container class must be also managed by the IoC container this usually drives you to publish your container class also as a singleton because this is the most simple scope and because this new class is managed by your IoC framework then any class referencing your container class again needs to get managed by the IoC container too...

    In the end of the day your system becomes a singleton plague usually throwing away all your OOP good patterns no very much different to C programming or the old days of GWBASIC plagued of global variables (the only option those days).

    I think we need a saner Smart Service Locator pattern, something like:

    MyService obj = MyServiceLocator.get( this );

    Note the "this" parameter, the class MyServiceLocator KNOWS what is the best implementation acording the object provided, and it returns a singleton or a temporal (request) object etc.

     

     

  13. Service Locator[ Go to top ]

    Jose,

    You just described OSGi µservices ...

  14. Service Locator[ Go to top ]

    Jose,

    You just described OSGi µservices ...

    Nice to know :)

    Interesting your view of the mixed factory-listener pattern that OSGi provides

    By the way, this is the refinement of the "Smart Service Locator", just an over simplified version of OSGi :) 

     MyService service = MyServiceLocator.get( this, otherParam1, otherParam2...);

     

     

  15. OSGi Use Cases[ Go to top ]

    As the article above expresses, the metaphor of a 'broker' is clearly a pattern that is different from that of a trusted manager (the best metaphor I can draw for IoC). While both are means of isolating 'dependencies', the question is more subtle than OSGi vs. Spring's dependency injection suggests. We could start by breaking down the assumption made in the article that IoC is equivalent to dependency injection. However, injecting dependency goes further that the relatively simple notion that you can trust your manager to delegate back to your help is needed. It is more akin to you trusting a manager to acquire the services of a peer one does not know well enough, and really does not want to know. At the very least you need to assume your peer also trusts your manager, and the manager knows both of you.

    For a different point of comparison against the IoC pattern, consider SAX XML parsers vs. StaX. SAX certainly follows the inversion of control pattern, but it's counterpoint is not the modularity we find in OSGi, it is an event driven approach where the consumer potentially assume greater responsibility for the handling of all kinds of events. There is no 'broker' as such in StAX, unless one counts a common event handling mechanism.

    In an ideal world events require even less in the way of mutual understanding between the parties than a traditional broker. A broker has a tendency to require a contract for either counterparty to a transaction. This is true in finance, and it is certainly true in the OSGi pattern described above. Each party need only know about the contract with the broker, and is isolated from the other party in by virtue of the presence of an intermediary. The contract becomes unnecessary 'scaffolding' under circumstances where otherwise that level and nature of isolation would not be needed.

    So 2 points:

     1) Inversion of control does not equate to dependency injection

     2) There are other means of decoupling code. Some are venerable, such as models of the world expressed in terms of events. There are others.

    On the others: I remain fond of layered (or stratified as we Lisp-heads called them) architectures. But that is a quirky example these days. More mainstream, messaging has also shown much success. And of course there are religious wars that might put the Middle East to shame over REST.

    Perhaps we all have a tendency to loose track of the interesting questions concerning what makes each style, framework, or pattern different. OSGi isolates service very effectively. Spring is proven, and lubricates testing. Event driven models drive most user interaction. Messaging delivers reliable integration to the enterprise. Web services and REST now dominate where consumers are in the mix.

    Any takers to point out what I have missed in this rich fabric?

  16. @Legal