OSGi facilitates producing and taking care of modular Java parts (termed bundles) that can be deployed in a container. As a developer, you use the OSGi specification and resources to create a person or far more bundles. OSGi defines the lifecycle for these bundles. It also hosts them and supports their interactions in a container. You can imagine of an OSGi container as roughly analogous to a JVM, with supplemental powers. Similarly, imagine of bundles as Java programs with one of a kind skills. Bundles operate within the OSGi container as shopper and server parts.
The OSGi alliance
OSGi started in 1999, and in contrast to many other specs the regular is not managed by Oracle, the Java Community Method, or the Eclipse Foundation. In its place, it is managed by the OSGi alliance.
How OSGi is distinctive
OSGi’s philosophy differs from that of other Java-based frameworks, most notably Spring. In OSGi, numerous programs can exist within just the exact same container: the OSGi bundle runtime atmosphere. The container assures every element is sufficiently isolated, and also has access to any dependencies it needs. OSGi can aid dependency injection, which is standardized by the Aries Blueprint project. In addition to offering OSGi’s inversion of handle (IoC) container, Aries supports regular Java frameworks like the Java Persistence API (JPA).
In OSGi, bundles can expose expert services that other bundles use. A bundle can also declare a model, and can define what other bundles it depends on. The runtime will then immediately load all of its bundles in buy of dependency. In OSGi, numerous versions of the exact same bundle can exist aspect by aspect, if that is demanded by bundle dependencies.
OSGi in Eclipse IDE and Equinox
OSGi has been all-around in some variety for a couple of a long time. It’s utilised for many nicely-acknowledged programs, from embedded mobile units to software servers and IDEs.
The popular Eclipse IDE is constructed on prime of OSGi. Eclipse’s implementation of the OSGi container is termed Equinox. It’s a good illustration for comprehending OSGi. Becoming based on OSGi indicates that Equinox is a modular system. It hosts a assortment of expert services that developers can include at will. Just about every of these gives a functionality that a developer may want in their IDE. You may include editors for Java and JavaScript, an app server, and a database connector. Just about every of these is carried out as an OSGi bundle that is included to the container and can interact with other expert services in the container.
Just lately, there’s been an uptick of desire in employing OSGi for the Online of Points (IoT). OSGi is a all-natural in good shape for this style of growth, which has a assortment of program parts managing aspect-by-aspect on units, without the need of necessarily being aware of about every other. An OSGi container supplies a easy and standardized way to host these dynamic program parts.
Utilizing OSGi in a Java project: Knoplerfish OSGi
We’ll do the job through an illustration software that will make OSGi principles far more concrete. Our illustration is based on the Knoplerfish OSGi runtime, which is utilised in many manufacturing deployments. Knoplerfish features a GUI and command-line interface (CLI) for taking care of the OSGi container and its bundles.
The to start with factor you’ll do is down load Knoplerfish. The recent model at the time of this crafting is Knoplerfish OSGi 6.one.three. You can switch that model with what ever is most recent when you go through this write-up.
Just after you’ve downloaded and put in Knoplerfish, use the CLI to fall into the listing wherever you downloaded the JAR file, and enter: java -jar framework.jar
. That will operate the executable JAR and you should really be greeted with a GUI window.
The Knoplerfish OSGi GUI
Knoplerfish OSGi’s GUI can appear frustrating at to start with, but the fundamentals are easy:
- At the prime of the screen is the menu.
- To the still left is the set of bundles that have been loaded into the runtime.
- To the proper is an information window.
- At the bottom is a text output console.
- At the pretty bottom is an enter console.
Determine one. A screenshot of the Knoplerfish OSGi GUI (simply click to enlarge)
Form aid
into the enter console if you want to see the aid possibilities.
Right before we shift into the illustration, just take a appear at the set of managing bundles. You will see a bundle termed HTTP Server
, which indicates that a bundle managing an HTTP server is up. Go to your browser, and check out http://localhost:8080. Confident plenty of, you will see a Knoplerfish world-wide-web site.
The ‘Hello JavaWorld’ bundle
Let’s use the OSGi runtime to build a easy bundle, which I will simply call Hello there JavaWorld
. This bundle outputs a concept to the console.
In Listing one, we use Maven to build the bundle. It has only a person dependency, which is provided by the OSGi alliance.
Listing one. OSGi dependency in the Maven POM
org.osgi
org.osgi.core
Now, we’re also likely to use a plug-in, courtesy of the Apache Felix project. This plug-in will take care of packaging the app as an OSGi bundle for use. Listing 2 demonstrates the configuration we’ll use.
Listing 2. OSGi Felix plug-in in the Maven POM
org.apache.felix
maven-bundle-plugin
genuine
org.javaworld.osgi
org.javaworld.osgi.Hello there
Now we can just take a appear at the easy class that will output a “Hello.”
Listing three. Hello there JavaWorld OSGi bundle
offer com.javaworld.osgi
import org.osgi.framework.BundleActivator
import org.osgi.framework.BundleContext
general public class HelloJavaWorld implements BundleActivator
general public void start off(BundleContext ctx)
Procedure.out.println("Hello there JavaWorld.")
general public void cease(BundleContext bundleContext)
Build the bundle by likely to the command line and typing mvn clear install
. This will output a JAR file containing the bundle. Now, go to the File
menu in the Knoplerfish GUI, and pick Add Bundle
. This will present a file browser. Discover the JAR we have just constructed and pick it.
Taking care of OSGi bundles in the container
In the output window of the Knoplerfish UI, you’ll see your “Hello, JavaWorld” concept appear. Click on on the bundle in the Knoplerfish GUI, and you can see the ID the container has assigned to it. When you are all set to cease the bundle, you could simply click the Cease menu product. A further way is to enter cease [bundle quantity]
on the command line. You can deal with bundles in the container employing either the GUI or the command line.
Now you have a sense of how a easy bundle performs in the OSGi container. Anyplace an OSGi container exists, you will discover the exact same simplicity in starting and halting bundles. OSGi makes an atmosphere and lifecycle for the bundle.
Bundle Interactions: Solutions and clientele
Next, we’ll appear at how bundles talk with every other.
The to start with factor we’ll do is create a company bundle. A company bundle is analogous to an EJB session bean: It supplies a element that can be accessed by other bundles by way of a distant interface. To create a company bundle, we want to present each an interface and an implementation class.
Listing 4. The company bundle interface
offer com.javaworld.osgi.company
general public interface WhatIsOsgi
general public Integer addNum(Integer x, Integer y)
Listing 4 is a easy interface. The only system is a addNum()
system that will do what it implies: return the addition of two numbers. The implementation shown in Listing five is equally easy but adds a couple of OSGi-unique approaches.
Listing five. The company bundle implementation
offer com.javaworld.osgi.company
general public class WhatIsOsgiImpl implements WhatIsOsgi, BundleActivator
personal ServiceReference ref
personal ServiceRegistration reg
@Override
general public Integer addNum(Integer x, Integer y)
return x + y
@Override
general public void start off(BundleContext context) throws Exception
reg = context.registerService(
WhatIsOsgi.class,
new WhatIsOsgiImpl(),
new Hashtable())
ref = reg.getReference()
@Override
general public void cease(BundleContext context) throws Exception
reg.unregister()
Let’s appear closer at what is going on in Listing five:
general public class WhatIsOsgiImpl implements WhatIsOsgi, BundleActivator
: Here we are utilizing the interface we established. Take note that we also put into practice theBundleActivator
interface, as we did with theHelloJavaWorld
illustration. The latter is due to the fact this bundle will activate alone.personal ServiceReference
: These are variables for the OSGi registration company and the bundle reference for this company, respectively.ref personal ServiceRegistration reg general public Integer addNum(Integer x, Integer y)
: This is the easy implementation of the include system.general public void start off(BundleContext context)
: This start off system is element of theBundleActivator
interface, and is executed by the container. In this illustration, we get a reference to the OSGi registration company and implement it to ourWhatIsOsgi
interface and implementation. The emptyHashtable
is for config params, which we are not employing listed here. We also get a reference to the company we have just established.general public void cease(BundleContext context)
: Here, we simply just unregister the company. This easy company just manages the barest elements of its lifecycle. Its major objective is to expose theaddNum
system to the OSGi container.
The OSGi shopper
Next up, let’s publish a shopper that can use the company. This shopper will once again make use of the BundleActivator
interface. It will also include the ServiceListener
interface, as shown in Listing 6.
Listing 6. The OSGi company shopper bundle
general public class OsgiClient implements BundleActivator, ServiceListener
personal BundleContext ctx
personal ServiceReference company
general public void start off(BundleContext ctx)
this.ctx = ctx
test
ctx.addServiceListener(this, "(objectclass=" + WhatIsOsgi.class.getName() + ")")
capture (InvalidSyntaxException ise)
ise.printStackTrace()
Listing 6 has a start off system that will include a company listener. This listener is filtered by the class name of the company we established in Listing five. When the company is updated, it will simply call the serviceChanged()
system, as shown in Listing 7.
Listing 7. serviceChanged system
general public void serviceChanged(ServiceEvent function)
int style = function.getType()
swap (style)
scenario(ServiceEvent.REGISTERED):
serviceReference = function.getServiceReference()
Greeter company = (Greeter)(ctx.getService(company))
Procedure.out.println("Adding 10 and one hundred: " + company.addNum(10, one hundred) )
break
scenario(ServiceEvent.UNREGISTERING):
Procedure.out.println("Provider unregistered.")
ctx.ungetService(function.getServiceReference()) // Releases reference to company so it can be GC'd
break
default:
break
Take note that the serviceChanged
method is utilised to figure out what function has transpired for a company we are interested in. The company will then respond as specified. In this scenario, when the REGISTERED
function appears, we make use of the addNum()
system.
The OSGi different
This has been a speedy introduction to OSGi, the Open Solutions Gateway Initiative. As you’ve seen through the Knoplerfish illustration, OSGi supplies a runtime atmosphere wherever you can define modular Java parts (bundles). It supplies a described lifecycle for internet hosting bundles in the shopper, and it supports bundles interacting as clientele and expert services within just the container. All of these abilities taken together present an fascinating different to regular Java runtimes and frameworks, specially for mobile and IoT programs.
Lastly, take note that the preceding write-up in the “What is: Java” series introduced the Java System Module Procedure, which gives a distinctive method to the exact same challenge of Java modularity.
This tale, “What is OSGi? A distinctive method to Java modularity” was at first printed by
JavaWorld.
Copyright © 2020 IDG Communications, Inc.