Here we are with our first episode of this new series about OSGi.
Before entering the details of our use cases, we first need to give a brief definition of what OSGi is, and what it has tried to accomplish over the years.
You can think of OSGi as an additional layer which can be put on top of Java, and provides a set of functionalities to help you develop an application as a modular and dynamic system.
We already used the terms modular and dynamic twice, so they should be quite important, right? Let's see what we mean with them. In this post we will start with the first one.
An application can be defined modular if it is built of small pieces, each one in charge of a particular function. Following the principle of separation of concerns, classes that provide two different functionalities should be the most decoupled as possible, and one class should be in charge of one simple task, instead of trying to fit all the logic into the same block of code.
Modularity is often associated with the world of micro services, which can be seen as the units of code which are in charge of a specific functionality. Services are often described with interfaces, and are all that should be accessible from outside, providing a contract of what is possible to achieve with them, by keeping the implementation (which can be seen as the code which does the actual work), hidden. The final consumer of a service does not need to wonder how we achieved a particular result, as long as it is the result he/she is expecting from the contract.
Prior to Java 9, there was no real modularity in Java. For instance, if you wanted only certain packages to be able to access some other package, this was not possible. You could only make a single class visible or not outside its package, using the Java access modifiers, but once it was declared as
public, then it could be accessed by every other package.
I said prior to Java 9, because with Java 9 things have started to go towards modularity. The Java Platform Module System (JPMS) was introduced. Now you have the possibility to encapsulate packages, meaning to hide some of them to the outside world, while exporting some others. At the same time you can make a package available only for certain other packages, introducing an additional level of encapsulation which, for sure, helps in building a modular application.
If you want to create a modular application in Java now, what you need to do is to add a
module-info.java file in the root folder of your project, which specifies which are the packages you want to export, which are the ones that your module needs, and some other directives to describe whether your module provides a certain implementation for a service or whether it defines a certain interface. Of course is still up to you to really write a modular application, in the sense of separating the different functionalities into multiple services. If you want to know more about the JPMS, check out our Bits of Java post about it!
OSGi also comes with its modular layer, whose building blocks are OSGi bundles. These, like modules in Java now, are collections of packages, which can be exported to be used by other bundles or can remain private, to hide implementation details. The equivalent of the
module-info.java file, would be the
MANIFEST.MF, which is a file that needs to be packaged in your
.jar and which provides some meta information about your bundle.
Well, up to now it looks like OSGi is not doing anything new compared to Java 9, right? Well, modularity was a native characteristic of OSGi, which existed long before Java 9. But there is also something else which is possible with OSGi, and which makes it quite peculiar (and cool).
Be patient, and next week we will discuss the second keyword, dynamic, which describes OSGi, and you will see how things will become interesting!