What is OSGi? A different approach to Java modularity
OSGi facilitates developing and taking care of modular Java elements (named bundles) that can be deployed in a container. As a developer, you use the OSGi specification and applications to build a single or far more bundles. OSGi defines the lifecycle for these bundles. It also hosts them and supports their interactions in a container. You can think of an OSGi container as approximately analogous to a JVM, with supplemental powers. Also, think of bundles as Java apps with one of a kind skills. Bundles operate inside of the OSGi container as shopper and server elements.
The OSGi alliance
OSGi commenced in 1999, and in contrast to several other specs the standard is not managed by Oracle, the Java Community Procedure, or the Eclipse Foundation. Instead, it is managed by the OSGi alliance.
How OSGi is various
OSGi’s philosophy differs from that of other Java-dependent frameworks, most notably Spring. In OSGi, a number of apps can exist in just the similar container: the OSGi bundle runtime ecosystem. The container guarantees each and every element is adequately isolated, and also has obtain to any dependencies it necessitates. OSGi can guidance dependency injection, which is standardized by the Aries Blueprint challenge. In addition to giving OSGi’s inversion of control (IoC) container, Aries supports standard Java frameworks like the Java Persistence API (JPA).
In OSGi, bundles can expose companies that other bundles use. A bundle can also declare a variation, and can determine what other bundles it relies upon upon. The runtime will then quickly load all of its bundles in order of dependency. In OSGi, a number of versions of the similar bundle can exist aspect by aspect, if that is needed by bundle dependencies.
OSGi in Eclipse IDE and Equinox
OSGi has been all over in some form for a pair of decades. It is used for several effectively-identified apps, from embedded cell equipment to software servers and IDEs.
The common Eclipse IDE is designed on top rated of OSGi. Eclipse’s implementation of the OSGi container is named Equinox. It is a wonderful illustration for comprehending OSGi. Currently being dependent on OSGi usually means that Equinox is a modular platform. It hosts a variety of companies that developers can increase at will. Each individual of these features a functionality that a developer could possibly need to have in their IDE. You could possibly increase editors for Java and JavaScript, an app server, and a database connector. Each individual of these is carried out as an OSGi bundle that is added to the container and can interact with other companies in the container.
Not long ago, there is been an uptick of curiosity in employing OSGi for the World-wide-web of Factors (IoT). OSGi is a pure suit for this form of growth, which has a variety of computer software elements managing aspect-by-aspect on equipment, with out essentially being aware of about each and every other. An OSGi container presents a simple and standardized way to host these dynamic computer software elements.
Making use of OSGi in a Java challenge: Knoplerfish OSGi
We’ll get the job done via an illustration software that will make OSGi ideas far more concrete. Our illustration is dependent on the Knoplerfish OSGi runtime, which is used in several creation deployments. Knoplerfish involves a GUI and command-line interface (CLI) for taking care of the OSGi container and its bundles.
The first thing you will do is download Knoplerfish. The current variation at the time of this creating is Knoplerfish OSGi 6.1.three. You can exchange that variation with no matter what is most current when you browse this posting.
Soon after you’ve downloaded and mounted 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 must be greeted with a GUI window.
The Knoplerfish OSGi GUI
Knoplerfish OSGi’s GUI can appear overwhelming at first, but the principles are simple:
- At the top rated of the display screen is the menu.
- To the remaining is the established of bundles that have been loaded into the runtime.
- To the suitable is an details window.
- At the bottom is a textual content output console.
- At the really bottom is an enter console.
Determine 1. A screenshot of the Knoplerfish OSGi GUI (click to enlarge)
Type enable
into the enter console if you want to see the enable choices.
Ahead of we shift into the illustration, get a glance at the established of managing bundles. You will see a bundle named HTTP Server
, which usually means that a bundle managing an HTTP server is up. Go to your browser, and check out out http://localhost:8080. Confident more than enough, you will see a Knoplerfish website web site.
The ‘Hello JavaWorld’ bundle
Let’s use the OSGi runtime to make a simple bundle, which I will simply call Hi there JavaWorld
. This bundle outputs a information to the console.
In Listing 1, we use Maven to make the bundle. It has only a single dependency, which is supplied by the OSGi alliance.
Listing 1. 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 challenge. This plug-in can take treatment of packaging the app as an OSGi bundle for use. Listing two demonstrates the configuration we’ll use.
Listing two. OSGi Felix plug-in in the Maven POM
org.apache.felix
maven-bundle-plugin
correct
org.javaworld.osgi
org.javaworld.osgi.Hi there
Now we can get a glance at the simple class that will output a “Hello.”
Listing three. Hi there JavaWorld OSGi bundle
offer com.javaworld.osgi
import org.osgi.framework.BundleActivator
import org.osgi.framework.BundleContext
public class HelloJavaWorld implements BundleActivator
public void start(BundleContext ctx)
Process.out.println("Hi there JavaWorld.")
public void prevent(BundleContext bundleContext)
Construct the bundle by likely to the command line and typing mvn clean up set up
. This will output a JAR file that contains the bundle. Now, go to the File
menu in the Knoplerfish GUI, and select Insert Bundle
. This will offer a file browser. Discover the JAR we have just designed and select it.
Running OSGi bundles in the container
In the output window of the Knoplerfish UI, you will see your “Hello, JavaWorld” information surface. Click on the bundle in the Knoplerfish GUI, and you can see the ID the container has assigned to it. When you are prepared to prevent the bundle, you could click the Stop menu product. Another way is to enter prevent [bundle variety]
on the command line. You can manage bundles in the container employing either the GUI or the command line.
Now you have a perception of how a simple bundle performs in the OSGi container. Anyplace an OSGi container exists, you will come across the similar simplicity in starting and stopping bundles. OSGi produces an ecosystem and lifecycle for the bundle.
Bundle Interactions: Companies and purchasers
Up coming, we’ll glance at how bundles connect with each and every other.
The first thing we’ll do is build a services bundle. A services bundle is analogous to an EJB session bean: It presents a element that can be accessed by other bundles via a remote interface. To build a services bundle, we need to have to offer equally an interface and an implementation class.
Listing four. The services bundle interface
offer com.javaworld.osgi.services
public interface WhatIsOsgi
public Integer addNum(Integer x, Integer y)
Listing four is a simple interface. The only system is a addNum()
system that will do what it indicates: return the addition of two quantities. The implementation revealed in Listing 5 is similarly simple but adds a pair of OSGi-distinct approaches.
Listing 5. The services bundle implementation
offer com.javaworld.osgi.services
public class WhatIsOsgiImpl implements WhatIsOsgi, BundleActivator
personal ServiceReference ref
personal ServiceRegistration reg
@Override
public Integer addNum(Integer x, Integer y)
return x + y
@Override
public void start(BundleContext context) throws Exception
reg = context.registerService(
WhatIsOsgi.class,
new WhatIsOsgiImpl(),
new Hashtable())
ref = reg.getReference()
@Override
public void prevent(BundleContext context) throws Exception
reg.unregister()
Let’s glance nearer at what is going on in Listing 5:
public class WhatIsOsgiImpl implements WhatIsOsgi, BundleActivator
: Here we are applying the interface we produced. Take note that we also put into practice theBundleActivator
interface, as we did with theHelloJavaWorld
illustration. The latter is since this bundle will activate alone.personal ServiceReference
: These are variables for the OSGi registration services and the bundle reference for this services, respectively.ref personal ServiceRegistration reg public Integer addNum(Integer x, Integer y)
: This is the simple implementation of the increase system.public void start(BundleContext context)
: This start system is element of theBundleActivator
interface, and is executed by the container. In this illustration, we acquire a reference to the OSGi registration services and apply it to ourWhatIsOsgi
interface and implementation. The vacantHashtable
is for config params, which we aren’t employing listed here. We also get a reference to the services we have just produced.public void prevent(BundleContext context)
: Here, we merely unregister the services. This simple services just manages the barest things of its lifecycle. Its major purpose is to expose theaddNum
system to the OSGi container.
The OSGi shopper
Up coming up, let us produce a shopper that can use the services. This shopper will yet again make use of the BundleActivator
interface. It will also increase the ServiceListener
interface, as revealed in Listing 6.
Listing 6. The OSGi services shopper bundle
public class OsgiClient implements BundleActivator, ServiceListener
personal BundleContext ctx
personal ServiceReference services
public void start(BundleContext ctx)
this.ctx = ctx
test
ctx.addServiceListener(this, "(objectclass=" + WhatIsOsgi.class.getName() + ")")
capture (InvalidSyntaxException ise)
ise.printStackTrace()
Listing 6 has a start system that will increase a services listener. This listener is filtered by the class name of the services we produced in Listing 5. When the services is up-to-date, it will simply call the serviceChanged()
system, as revealed in Listing seven.
Listing seven. serviceChanged system
public void serviceChanged(ServiceEvent function)
int form = function.getType()
swap (form)
case(ServiceEvent.REGISTERED):
serviceReference = function.getServiceReference()
Greeter services = (Greeter)(ctx.getService(services))
Process.out.println("Introducing 10 and a hundred: " + services.addNum(10, a hundred) )
crack
case(ServiceEvent.UNREGISTERING):
Process.out.println("Provider unregistered.")
ctx.ungetService(function.getServiceReference()) // Releases reference to services so it can be GC'd
crack
default:
crack
Take note that the serviceChanged
method is used to identify what function has happened for a services we are interested in. The services will then respond as specified. In this case, when the REGISTERED
function seems, we make use of the addNum()
system.
The OSGi choice
This has been a brief introduction to OSGi, the Open Companies Gateway Initiative. As you’ve seen via the Knoplerfish illustration, OSGi presents a runtime ecosystem wherever you can determine modular Java elements (bundles). It presents a defined lifecycle for web hosting bundles in the shopper, and it supports bundles interacting as purchasers and companies in just the container. All of these abilities taken with each other offer an appealing choice to standard Java runtimes and frameworks, especially for cell and IoT apps.
Eventually, note that the earlier posting in the “What is: Java” series introduced the Java Platform Module Process, which features a various approach to the similar challenge of Java modularity.
This tale, “What is OSGi? A various approach to Java modularity” was originally published by
JavaWorld.
Copyright © 2020 IDG Communications, Inc.