When we read about OSGI, we get confused by the various terminologies like modular application, dynamic components, microservices, libraries, reusable components, OSGI bundle, features and etc. So here, in this blog, we are not gonna care about it. We’ll just see an simple application which can be deployed in JBOSS Fuse.
What are we gonna do?
Let’s say a user is logging in to an application like amazon or filpkart. You need to fetch and display the products that you want to suggest to the user to purchase, in home page. Our application is a restful web service to get all the products with its id, name, company name. We are gonna make two jar file, one for rest API and one for the actual service which has the real implementation.
Products module:
Let’s first look at the actual implementation without the rest API. Later we’ll see how to create the rest API jar and how it make use of the actual implementation jar. Click here to download the code base of this module.
How does it differ from the traditional jar or library file?
MANIFEST.MF and blueprint.xml are making the differences. Even though we get a jar file while building this project, we call this jar file by the name OSGI bundle, because of these two files.
MANIFEST.MF and blueprint.xml are making the differences. Even though we get a jar file while building this project, we call this jar file by the name OSGI bundle, because of these two files.
blueprint.xml
Below is the blueprint.xml of our implementation jar.
<?xml version="1.0" encoding="UTF-8"?>
<blueprint
xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi_schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<bean id="productServices" class="com.flexy.products.services.ProductServicesImpl">
<property name="productDao" ref="productDao"/>
</bean>
<bean id="productDao" class="com.flexy.products.repository.ProductDaoImpl"/>
<service ref="productServices" interface="com.flexy.products.services.IProductServices"/>
</blueprint>
Note down this service definition. We will access this service from rest API jar.
MANIFEST.MF
Next, the MANIFEST.MF file. We won’t have this file in our project. This file will be generated and placed inside the jar under the META-INF folder, while building the application. To add this file in your jar, we should have the below maven plugin in your pom.xml.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>products</Bundle-SymbolicName>
<Import-Package>
org.osgi.service.blueprint,
java.text,
java.util,
org.slf4j
</Import-Package>
<Export-Package>
com.flexy.products.services,
com.flexy.products.model
</Export-Package>
</instructions>
</configuration>
</plugin>
Once we build this module, we get the below MANIFEST.MF file inside the jar.
Manifest-Version: 1.0
Bnd-LastModified: 1475582457289
Build-Jdk: 1.7.0_75
Built-By: arunv
Bundle-ManifestVersion: 2
Bundle-Name: User Products
Bundle-SymbolicName: userproducts
Bundle-Version: 1.0.0.6
Created-By: Apache Maven Bundle Plugin
Export-Package: com.flexy.userproducts.services;uses:="javax.ws.rs,javax
.jws,com.flexy.products.model,com.flexy.products.services,org.slf4j";ve
rsion="1.0.0.2"
Import-Package: com.fasterxml.jackson.jaxrs.json;version="[2.4,3)",com.f
lexy.products.model;version="[1.0,2)",com.flexy.products.services;versi
on="[1.0,2)",javax.jws,javax.ws.rs;version="[2.0,3)",javax.ws.rs.core;v
ersion="[2.0,3)",org.osgi.service.blueprint;version="[1.0.0,2.0.0)",org
.slf4j;version="[1.7,2)"
Import-Service: com.flexy.products.services.IProductServices;multiple:=f
alse
Tool: Bnd-1.50.0
Service element vs Export-Package:
The service element in blueprint.xml and these export packages may look like both have the same responsibilities. But both are completely different and each has its own responsibility. The classes inside the exported packages can be imported in other modules as we do in traditional way. If the class depends on any other class like dependency injection, we have to do this ourselves in our own module. But we can use the service classes without worrying about its implementation and its dependencies.You can get the better clarity when you look at the reference element of blueprint.xml, which we’ll see in a min,
The service element in blueprint.xml and these export packages may look like both have the same responsibilities. But both are completely different and each has its own responsibility. The classes inside the exported packages can be imported in other modules as we do in traditional way. If the class depends on any other class like dependency injection, we have to do this ourselves in our own module. But we can use the service classes without worrying about its implementation and its dependencies.You can get the better clarity when you look at the reference element of blueprint.xml, which we’ll see in a min,
User Product Module:
Now we will see how to use this jar file in the rest API jar. Click here to download the code base of this module.
blueprint.xml
As we mentioned above, this rest API is also a OSGI bundle. Let’s look at it’s blueprint.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<blueprint
xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns_jaxrs="http://cxf.apache.org/blueprint/jaxrs"
xmlns_cxf="http://cxf.apache.org/blueprint/core"
xsi_schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd">
<jaxrs:server id="userProductService" address="/userproducts">
<jaxrs:serviceBeans>
<ref component-id="userproducts"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>
</jaxrs:providers>
</jaxrs:server>
<cxf:bus>
<cxf:features>
<cxf:logging />
</cxf:features>
</cxf:bus>
<bean id="userproducts" class="com.flexy.userproducts.services.UserProductServiceImpl">
<property name="productServices" ref="productServices"/>
</bean>
<reference id="productServices" interface="com.flexy.products.services.IProductServices"></reference>
</blueprint>
The reference element is used to mention the service which we want to use from the dependent jars.
Now we have a question where to mention or configure the dependency jar. That’s features.xml and we can also call features repository. We can have n number of features repository and each repository can have n number of feature. feature is again a confusing word. It’s nothing but a jar or library or dependency or OSGI bundle.
Now we have a question where to mention or configure the dependency jar. That’s features.xml and we can also call features repository. We can have n number of features repository and each repository can have n number of feature. feature is again a confusing word. It’s nothing but a jar or library or dependency or OSGI bundle.
features repository:
We can keep this features.xml file wherever we want, add it in the feature repository. But here, we kept it along with our project. Below is our features.xml,
<?xml version="1.0" encoding="UTF-8"?>
<features name="userproductfeature-1.0.0-1" >
<feature name="products" version="1.0.0-2" resolver="(obr)">
<bundle dependency="true">mvn:com.flexy/products/1.0.0-2</bundle>
</feature>
</features>
Summarizing the items which we should note it down,
features.xml – feature or dependency repository to specify the dependent jar.
META-INF/MANIFEST.MF
Import packages – to specify the dependent packages.
Export packages – classes inside the packages can be used by other bundles or jars.
blueprint.xml
service – registering a service in the OSGI service registry. This service can be accessed by other OSGI bundles using reference element.
reference – find the service in service registry and get the bean.
There are lot to know about the deployment and advantages of it. But adding too much in a single article will make us tired. So we will try to explore more and publish more in the next article.
For Javascripts, visit http://flexydevcenter.blogspot.com/