Adopting technologies because you can, or because they're the latest or because they seem the flavour of the month often adds complexity to a project for little gain. A technology should address and fix a problem and justify it's existence.
OSGi has already had a reasonably long and established life, since 1999. I want to discuss why OSGi is around today and the look at the existing problems it addresses.
In complex software projects a properly modularized system enables:
- Parallel development of modules by teams who need no understanding of the internals of other modules.
- Reuse of modules by different apps.
- Maintenance of 1 module without affecting others.
The Java language goes a long way to solving these problems, however, problems do still exist.
The OO encapsulation model is very focused on instance variables and methods. By restricting access to variables and preferring access via getters and setters, a developer can enforce a usage policy over a classes content. However, this only helps at the class and object level. Post compilation, classes are usually aggregated into JAR files for deployment into a Java environment, when at runtime, it is considered to be another modular unit. There isn't any granularity in terms of which parts of a JAR can or cannot be used by other JARS . A JAR is either on the classpath and visible, or not. Nothing at runtime is policing modularity/accessibility/visibility between JARs in a similar way to how instance variables and methods are between classes; i.e. there is no meaning or mapping of public and private visibility for JAR files.
JAR files can consist of multiple packages and, if the JAR represents a cohesive function, there is typically a need for classes in one package to access classes in another which then requires public accessibility. An example would be package 'x.y.z' and package 'x.y.z.impl' in the same JAR, an approach often taken to try to isolate the implementation away from it's contractual interface. However, this is only convention, there are no restrictions here, so immediately, all classes in both packages are visible to classes in any other JAR.
As code and projects grow in size and function there will be an natural interface split, where some interfaces will be considered/declared as external and are to be used by other components/modules, whereas others are indended to be internal and should only be used by internal code. Java has no easy way of controlling the split between API and SPI interfaces and as a result, they are handled by Java in the same way, meaning SPIs are an artificial definition applied by the developer but policed/enforced by nobody, as anyone can use them.
JARs lack the capacity to scope the visibility of what they contain, they also lack the capacity to declare their own fine grain dependencies, such as packages. Many jars have implicit dependencies on other jars that means these jars cannot be installed or moved around independently. If they are installed without dependencies being present then the first time there is any indication of a problem is at runtime when the code is actually invoked.
The global Java classpath is a flat structure that doesn't allow for classes with common names. If two classes with the same package and class name exist in different JARs the client cannot be sure which one they will get back as the classpath is a flat list and will return the first matching classname simply because it was higher on the global classpath. A common example of the global Java classpath's inability to accommodate multiple classes with the same name and package structure is when multiple versions of a class/component are present. There can be multiple versions available on the classpath, but again, only the first will ever be loaded.
As code and projects grow in size and function there will be an natural interface split, where some interfaces will be considered/declared as external and are to be used by other components/modules, whereas others are indended to be internal and should only be used by internal code. Java has no easy way of controlling the split between API and SPI interfaces and as a result, they are handled by Java in the same way, meaning SPIs are an artificial definition applied by the developer but policed/enforced by nobody, as anyone can use them.
JARs lack the capacity to scope the visibility of what they contain, they also lack the capacity to declare their own fine grain dependencies, such as packages. Many jars have implicit dependencies on other jars that means these jars cannot be installed or moved around independently. If they are installed without dependencies being present then the first time there is any indication of a problem is at runtime when the code is actually invoked.
The global Java classpath is a flat structure that doesn't allow for classes with common names. If two classes with the same package and class name exist in different JARs the client cannot be sure which one they will get back as the classpath is a flat list and will return the first matching classname simply because it was higher on the global classpath. A common example of the global Java classpath's inability to accommodate multiple classes with the same name and package structure is when multiple versions of a class/component are present. There can be multiple versions available on the classpath, but again, only the first will ever be loaded.
So, the above list of problems with the existing Java behaviour can all be fixed by features of OSGi. I will describe how in my next blog post (perhaps 'OSGhow' :o) ), however, some/most/all of these may not be problems in everyone's deployment environment today. Essentially, I believe that using OSGi allows a developer to better achieve the Parallel development of modules, reuse of modules and the maintenance and management of modules.
when you said Nothing at runtime is policing the accessibly between the classes, what about the Java Access Modifiers, is't this a patch for a bad design?. could you give a example where a very clear solution is osgi?
ReplyDeleteand when you said Java has no easy way of controlling the split between API and SPI interfaces. Why do you not separate the interfaces and the implementation in different project? separate the API and API would fix the problem?
I find great OSGi, but still don't get it enough, could you give me or recommend, some book, site, anything where i could clear my doubts?
Thanks
Francisco
Hi Francisco,
ReplyDeleteThanks for reading and commenting. The Java access modifiers, such as private, public etc, police code at compile time rather than runtime. However, have you found that quite a few of your classes should be public to a range of classes/packages/jars, but private to others? This is where OSGi fits.
Lets take an example: Imagine a collection of packages containing a collection of classes all contained within a JAR file. This JAR may be a component in a larger system. It will contain some classes it wants to expose to other JARs or components, and some classes that should remain internal. These internal classes, perhaps utility classes for the component, are marked as 'public' so that all classes in the same component can make use of their function, irrespective of which package they are in. This function is internal function that should only be used in the component or JAR it exists in. But nothing restricts any other class in the flat Java classpath to access that function. This is where OSGi steps in.
OSGi can mark JARs with metadata to protect the code within. JARs with appropriate OSGi metadata (OSGi bundles), police which packages can and cannot be accessed outside of the JAR, as the metadata specifies which packages are exposed and which are not, among other things.
Separating the API and SPI interfaces does make good programming sense. However, APIs and SPIs are typically coupled which means there is a level of interaction between them. In other words, they are both marked as 'public' to enable them to talk to each other. Referring to my previous point, this does not add any policing once the code is in runtime and both interfaces are public and accessible.
I'm constructing an youtube Enterprise OSGi channel which will host short overviews and presentations based around OSGi. I will launch the channel next week and post the links here.
Thanks -- Simon