OSGi facilitates creating and handling modular Java components (named bundles) that can be deployed in a container. As a developer, you use the OSGi specification and tools to make one particular or far more bundles. OSGi defines the lifecycle for these bundles. It also hosts them and supports their interactions in a container. You can consider of an OSGi container as roughly analogous to a JVM, with additional powers. Likewise, consider of bundles as Java applications with distinctive qualities. Bundles operate within the OSGi container as customer and server components.
The OSGi alliance
OSGi began in 1999, and as opposed to lots of other specs the typical is not managed by Oracle, the Java Community Procedure, or the Eclipse Foundation. Instead, it is managed by the OSGi alliance.
How OSGi is distinct
OSGi’s philosophy differs from that of other Java-based mostly frameworks, most notably Spring. In OSGi, a number of applications can exist within the similar container: the OSGi bundle runtime natural environment. The container assures each individual element is sufficiently isolated, and also has entry to any dependencies it demands. OSGi can help dependency injection, which is standardized by the Aries Blueprint venture. In addition to providing OSGi’s inversion of command (IoC) container, Aries supports typical Java frameworks like the Java Persistence API (JPA).
In OSGi, bundles can expose companies that other bundles use. A bundle can also declare a version, and can outline what other bundles it relies upon on. The runtime will then immediately load all of its bundles in buy of dependency. In OSGi, a number of versions of the similar 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 few of many years. It is utilised for lots of effectively-known applications, from embedded cellular products to application servers and IDEs.
The common Eclipse IDE is designed on major of OSGi. Eclipse’s implementation of the OSGi container is named Equinox. It is a great instance for comprehension OSGi. Remaining based mostly on OSGi usually means that Equinox is a modular platform. It hosts a variety of companies that builders can include at will. Each individual of these delivers a capacity that a developer could want in their IDE. You could include editors for Java and JavaScript, an app server, and a database connector. Each individual of these is applied as an OSGi bundle that is additional to the container and can interact with other companies in the container.
A short while ago, there is been an uptick of interest in making use of OSGi for the Internet of Points (IoT). OSGi is a normal healthy for this type of growth, which has a variety of software program components working aspect-by-aspect on products, with no automatically knowing about each individual other. An OSGi container presents a simple and standardized way to host these dynamic software program components.
Employing OSGi in a Java venture: Knoplerfish OSGi
We’ll operate as a result of an instance application that will make OSGi concepts far more concrete. Our instance is based mostly on the Knoplerfish OSGi runtime, which is utilised in lots of output deployments. Knoplerfish includes a GUI and command-line interface (CLI) for handling the OSGi container and its bundles.
The initial matter you are going to do is obtain Knoplerfish. The present version at the time of this producing is Knoplerfish OSGi 6.1.three. You can change that version with regardless of what is most present when you study this post.
Immediately after you’ve downloaded and mounted Knoplerfish, use the CLI to drop into the listing wherever you downloaded the JAR file, and enter: java -jar framework.jar
. That will operate the executable JAR and you really should be greeted with a GUI window.
The Knoplerfish OSGi GUI
Knoplerfish OSGi’s GUI can seem to be frustrating at initial, but the basics are simple:
- At the major of the screen is the menu.
- To the left is the set of bundles that have been loaded into the runtime.
- To the suitable is an facts window.
- At the bottom is a text output console.
- At the very bottom is an input console.
Type assistance
into the input console if you want to see the assistance choices.
Ahead of we move into the instance, just take a appear at the set of working bundles. You are going to see a bundle named HTTP Server
, which usually means that a bundle working an HTTP server is up. Go to your browser, and look at out http://localhost:8080. Absolutely sure plenty of, you will see a Knoplerfish net site.
The ‘Hello JavaWorld’ bundle
Let’s use the OSGi runtime to create a simple bundle, which I will call Hi JavaWorld
. This bundle outputs a message to the console.
In Listing 1, we use Maven to create the bundle. It has only one particular dependency, which is offered by the OSGi alliance.
Listing 1. OSGi dependency in the Maven POM
org.osgi
org.osgi.core
Now, we’re also going to use a plug-in, courtesy of the Apache Felix venture. This plug-in takes treatment of packaging the app as an OSGi bundle for use. Listing two reveals the configuration we’ll use.
Listing two. OSGi Felix plug-in in the Maven POM
org.apache.felix
maven-bundle-plugin
real
org.javaworld.osgi
org.javaworld.osgi.Hi
Now we can just take a appear at the simple course that will output a “Hello.”
Listing three. Hi JavaWorld OSGi bundle
package deal com.javaworld.osgi
import org.osgi.framework.BundleActivator
import org.osgi.framework.BundleContext
community course HelloJavaWorld implements BundleActivator
community void start out(BundleContext ctx)
Method.out.println("Hi JavaWorld.")
community void prevent(BundleContext bundleContext)
Make the bundle by going to the command line and typing mvn cleanse set up
. This will output a JAR file that contains the bundle. Now, go to the File
menu in the Knoplerfish GUI, and find Add Bundle
. This will offer a file browser. Come across the JAR we’ve just designed and find it.
Managing OSGi bundles in the container
In the output window of the Knoplerfish UI, you are going to see your “Hello, JavaWorld” message surface. Simply click 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 prevent the bundle, you could click on the Stop menu product. Another way is to enter prevent [bundle range]
on the command line. You can manage bundles in the container making use of possibly the GUI or the command line.
Now you have a feeling of how a simple bundle will work in the OSGi container. Everywhere an OSGi container exists, you will locate the similar simplicity in commencing and halting bundles. OSGi generates an natural environment and lifecycle for the bundle.
Bundle Interactions: Solutions and customers
Following, we’ll appear at how bundles communicate with each individual other.
The initial matter we’ll do is make a service bundle. A service bundle is analogous to an EJB session bean: It presents a element that can be accessed by other bundles by means of a remote interface. To make a service bundle, we want to offer equally an interface and an implementation course.
Listing 4. The service bundle interface
package deal com.javaworld.osgi.service
community interface WhatIsOsgi
community Integer addNum(Integer x, Integer y)
Listing 4 is a simple interface. The only method is a addNum()
method that will do what it implies: return the addition of two figures. The implementation proven in Listing five is similarly simple but adds a few of OSGi-distinct methods.
Listing five. The service bundle implementation
package deal com.javaworld.osgi.service
community course WhatIsOsgiImpl implements WhatIsOsgi, BundleActivator
non-public ServiceReference ref
non-public ServiceRegistration reg
@Override
community Integer addNum(Integer x, Integer y)
return x + y
@Override
community void start out(BundleContext context) throws Exception
reg = context.registerService(
WhatIsOsgi.course,
new WhatIsOsgiImpl(),
new Hashtable())
ref = reg.getReference()
@Override
community void prevent(BundleContext context) throws Exception
reg.unregister()
Let’s appear closer at what is occurring in Listing five:
community course WhatIsOsgiImpl implements WhatIsOsgi, BundleActivator
: In this article we are implementing the interface we made. Be aware that we also implement theBundleActivator
interface, as we did with theHelloJavaWorld
instance. The latter is mainly because this bundle will activate alone.non-public ServiceReference
: These are variables for the OSGi registration service and the bundle reference for this service, respectively.ref non-public ServiceRegistration reg community Integer addNum(Integer x, Integer y)
: This is the simple implementation of the include method.community void start out(BundleContext context)
: This start out method is section of theBundleActivator
interface, and is executed by the container. In this instance, we get a reference to the OSGi registration service and apply it to ourWhatIsOsgi
interface and implementation. The vacantHashtable
is for config params, which we are not making use of below. We also get a reference to the service we have just made.community void prevent(BundleContext context)
: In this article, we basically unregister the service. This simple service just manages the barest features of its lifecycle. Its major objective is to expose theaddNum
method to the OSGi container.
The OSGi customer
Following up, let us create a customer that can use the service. This customer will yet again make use of the BundleActivator
interface. It will also include the ServiceListener
interface, as proven in Listing 6.
Listing 6. The OSGi service customer bundle
community course OsgiClient implements BundleActivator, ServiceListener
non-public BundleContext ctx
non-public ServiceReference service
community void start out(BundleContext ctx)
this.ctx = ctx
attempt
ctx.addServiceListener(this, "(objectclass=" + WhatIsOsgi.course.getName() + ")")
capture (InvalidSyntaxException ise)
ise.printStackTrace()
Listing 6 has a start out method that will include a service listener. This listener is filtered by the course identify of the service we made in Listing five. When the service is current, it will call the serviceChanged()
method, as proven in Listing 7.
Listing 7. serviceChanged method
community void serviceChanged(ServiceEvent party)
int type = party.getType()
switch (type)
case(ServiceEvent.REGISTERED):
serviceReference = party.getServiceReference()
Greeter service = (Greeter)(ctx.getService(service))
Method.out.println("Introducing 10 and 100: " + service.addNum(10, 100) )
split
case(ServiceEvent.UNREGISTERING):
Method.out.println("Support unregistered.")
ctx.ungetService(party.getServiceReference()) // Releases reference to service so it can be GC'd
split
default:
split
Be aware that the serviceChanged
method is utilised to ascertain what party has transpired for a service we are interested in. The service will then respond as specified. In this case, when the REGISTERED
party seems, we make use of the addNum()
method.
The OSGi alternative
This has been a swift introduction to OSGi, the Open Solutions Gateway Initiative. As you’ve witnessed as a result of the Knoplerfish instance, OSGi presents a runtime natural environment wherever you can outline modular Java components (bundles). It presents a described lifecycle for internet hosting bundles in the customer, and it supports bundles interacting as customers and companies within the container. All of these capabilities taken with each other offer an fascinating alternative to typical Java runtimes and frameworks, especially for cellular and IoT applications.
Finally, note that the former post in the “What is: Java” collection released the Java System Module Method, which delivers a distinct tactic to the similar obstacle of Java modularity.
This story, “What is OSGi? A distinct tactic to Java modularity” was initially posted by
JavaWorld.
Copyright © 2020 IDG Communications, Inc.