OSGI for Beginners Using Maven with Equinox(HowTo)

I have struggled to understand what OSGI really means for a long time. It has been around since a very long time but not many people are aware of it. It has been hyped as a very complex technology to understand. Here is my attempt to make it simple for any Java Developer. In my view if you understand concept of Interface , JNDI or EJB( Or registering some service in some form)  you will understand OSGI. In short OSGI is a Container where you can register your services through interfaces and those can be accessed any time. Another benefit of OSGI is that all these services can be Installed/Uninstalled/Started/Stopped at runtime (i.e Code can be hot deployed at runtime ) rather than normal requirement we have where we have restart J2EE server. Similar to J2ee containers (Tomcat, WebSphere, Jboss , Weblogic ) OSGI also has container like Equinox( Which is base for Eclipse), Apache Felix …etc

In this article i’m going to explain OSGI with Eclipse Equinox container. Anyone who has Eclipse IDE installed on their machine has OSGI container also installed in Eclipse plugin’s folder.

Name of OSGI container jar file looks like   org.eclipse.osgi_<version>.jar

You can start OSGI like this

java -jar org.eclipse.osgi_3.5.2.R35x_v20100126.jar -console

Attached is sample screenshot of how i started my OSGI container ( Its analogous to starting tomcat)

Now that we started OSGI , let me start creation a HelloWorld OSGI Application using Maven. Lemme show you my project structure first and then display my pom.xml


Now i’ll display my pom.xml. My pom.xml has 2 more profiles added to create 2 more new modules(MathService and MathServiceClient) which will be later explained in this article

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.linkwithweb.osgi</groupId>
	<artifactId>HelloWorld</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>HelloWorld</name>
	<dependencies>
		<dependency>
			<groupId>org.osgi</groupId>
			<artifactId>org.osgi.core</artifactId>
			<version>4.2.0</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>HelloWorld-${version}</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.1</version>
				<configuration>
					<source>1.5</source>
					<target>1.5</target>
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<archive>
						<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
					</archive>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<profiles>
		<profile>
			<id>MathService</id>
			<build>
				<finalName>MathService-${version}</finalName>
				<plugins>
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-compiler-plugin</artifactId>
						<version>2.3.1</version>
						<configuration>
							<source>1.5</source>
							<target>1.5</target>
						</configuration>
					</plugin>

					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-jar-plugin</artifactId>
						<configuration>

							<excludes>
								<exclude>**/*.xml</exclude>
								<exclude>**/*.bsh</exclude>
								<exclude>**/*.properties</exclude>
							</excludes>
							<archive>
								<manifestFile>src/main/resources/MathService/META-INF/MANIFEST.MF</manifestFile>
							</archive>
						</configuration>
					</plugin>

				</plugins>
			</build>
		</profile>
		<profile>
			<id>MathServiceClient</id>
			<build>
				<finalName>MathServiceClient-${version}</finalName>
				<plugins>
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-compiler-plugin</artifactId>
						<version>2.3.1</version>
						<configuration>
							<source>1.5</source>
							<target>1.5</target>
						</configuration>
					</plugin>

					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-jar-plugin</artifactId>
						<configuration>

							<excludes>
								<exclude>**/*.xml</exclude>
								<exclude>**/*.bsh</exclude>
								<exclude>**/*.properties</exclude>
							</excludes>
							<archive>
								<manifestFile>src/main/resources/MathServiceClient/META-INF/MANIFEST.MF</manifestFile>
							</archive>
						</configuration>
					</plugin>

				</plugins>
			</build>
		</profile>
	</profiles>

</project>

Now if you observe pom.xml there are 3 different MANIFEST.MF defined for 3 different OSGI bundle’s we create.  Saying so lemme explain you that OSGI bundles are same as Java jar file with its configuration defined in Manifest file of standard jar. OSGI defined few entries in manifest file which are related to OSGi which are read by container to activate the bundle, thus avoiding learning of any new metadata format we generally have for other frameworks

Here is sample Manifest.MF i have defined for MathServiceClient

Manifest-Version: 1.0
Bundle-Name: MathServiceClient
Bundle-Activator: com.linkwithweb.osgi.service.client.MathServiceClientActivator
Bundle-SymbolicName: MathServiceClient
Bundle-Version: 1.0.0
Import-Package: org.osgi.framework,com.linkwithweb.osgi.service

If you observe above manifest file you can observer that all the entries except Manifest-Version are OSGI specific entries. These are the entries which define how to deploy a bundles what all it is dependent on and what are extension points it exposes for other services to consume.. etc

Having explained this lemme first explain a HelloWorld bundle with its MANIFEST.MF and Activator class and its installation into Equinox OSGI Container

/**
 * 
 */
package com.linkwithweb.osgi;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

/**
 * @author Ashwin Kumar
 * 
 */
public class HelloActivator implements BundleActivator {
	public void start(BundleContext context) {
		System.out.println("Hello World");
	}

	public void stop(BundleContext context) {
		System.out.println("Goodbye All");
	}
}
Manifest-Version: 1.0
Bundle-Name: HelloWorld
Bundle-Activator: com.linkwithweb.osgi.HelloActivator
Bundle-SymbolicName: HelloWorld
Bundle-Version: 1.0.0
Import-Package: org.osgi.framework

Now run “mvn clean package” to build our bundle

It will create HelloWorld-0.0.1-SNAPSHOT.jar in target folder and we can install that into Equinox to test. Here is the image which shows how to install and start our HelloWorld into Equinox

install file:K:\Ashwin\OSGI\MavenProject\target\HelloWorld-0.0.1-SNAPSHOT.jar

If you observe above screenshot you can use install command to install the bundle and use the start command on bundle id to start the bundle

On start of Bundle start method of Activator class is called and while stopping bundle stop method of Activator is called and so you are seeing HelloWorld

Congratulations you have learned basics of OSGI and you have just deployed your first bundle.

Now lemme explain my second part of article which explains how to Expose and Consume services of modules

Exposing and Consuming Services

To explain this i’ll take a very simple example where i’ll publish a service which can add 2 numbers

Here is the code which does that

First we need to define an Interface which we are thinking of exposing to external bundles

/**
 * 
 */
package com.linkwithweb.osgi.service;

/**
 * @author Ashwin Kumar
 * 
 */
public interface MathService {

	/**
	 * @param a
	 * @param b
	 * @return
	 */
	public int add(int a, int b);
}

Now the implementation Class

/**
 * 
 */
package com.linkwithweb.osgi.service;

/**
 * @author Ashwin Kumar
 *
 */
public class MathServiceImpl implements MathService {

	/* (non-Javadoc)
	 * @see com.linkwithweb.osgi.service.MathService#add(int, int)
	 */
	public int add(int a, int b) {
		// TODO Auto-generated method stub
		return a+b;
	}

}

Now Activator class which register’s this service with OSGI container

/**
 * 
 */
package com.linkwithweb.osgi.service;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

/**
 * @author Ashwin Kumar
 * 
 */
public class MathServiceActivator implements BundleActivator {
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
	 */
	public void start(BundleContext context) {
		MathService service = new MathServiceImpl();
		// Third parameter is a hashmap which allows to configure the service
		// Not required in this example
		context.registerService(MathService.class.getName(), service, null);
		System.out.println("Math Service Registered");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) {
		System.out.println("Goodbye From math service");
	}
}

Here is the manifest file which exposes service

Manifest-Version: 1.0
Bundle-Name: MathService
Bundle-Activator: com.linkwithweb.osgi.service.MathServiceActivator
Bundle-SymbolicName: MathService
Bundle-Version: 1.0.0
Import-Package: org.osgi.framework
Export-Package: com.linkwithweb.osgi.service

If you observe this we are Exporting some packages so that they can be consumed later. Also all the package that we are thinking of importign have to be defined here

Use the following command to build the jar file

mvn -PMathService package

and Here is image which displays how to Install and Run the service

Now lemme explain how to implement consumer

/**
 * 
 */
package com.linkwithweb.osgi.service.client;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import com.linkwithweb.osgi.service.MathService;

/**
 * @author Ashwin Kumar
 * 
 */
public class MathServiceClientActivator implements BundleActivator {
	MathService service;
	private BundleContext context;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
	 */
	public void start(BundleContext context) {
		this.context = context;
		// Register directly with the service
		ServiceReference reference = context
				.getServiceReference(MathService.class.getName());
		service = (MathService) context.getService(reference);
		System.out.println(service.add(1, 2));
	}	/*
	 * (non-Javadoc)
	 * 
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) {
		System.out.println(service.add(5, 6));
	}
}

And now manifest file

Manifest-Version: 1.0
Bundle-Name: MathServiceClient
Bundle-Activator: com.linkwithweb.osgi.service.client.MathServiceClientActivator
Bundle-SymbolicName: MathServiceClient
Bundle-Version: 1.0.0
Import-Package: org.osgi.framework,com.linkwithweb.osgi.service

Now here is how we create package and install

mvn -PMathServiceClient package

Source code have been checkedin to following location

https://linkwithweb.googlecode.com/svn/trunk/osgi-tutorials/MavenProject

 

Njoy creating OSGI bundles . Main benefit is you can redeploy your bundles/services at runtime.

Mail me incase you have any doubts

About these ads

31 Responses to OSGI for Beginners Using Maven with Equinox(HowTo)

  1. Joao Assuncao says:

    Hi,
    I admit the service oriented approach is one of the strong points in OSGI but you forgot to mention another one that I feel is very important when you have to deal with an application with tons of dependencies. OSGi solves the problem of “Jar Hell”.
    An example. Suppose you use two libraries, libX and libY, in your application. Let’s also assume each one of them has a dependency in libZ, but with different versions. libX depends on libZ 2.0 and libY depends on libZ 1.0
    If libZ 2.0 is incompatible with libZ 1.0 you might end with a difficult issue to solve when you use both of them in the same application.
    OSGI can handle this kind of problems. When you use the Import-Package, you can specify a version for the java package. This will be used by the OSGI classloader to find the correct bundle/jar.
    In my previous example, if the libraries libX, libY and libZ were OSGi compatible it would be possible to have all of them loaded in the same JVM without issues:
    libZ 1.0 would use Export-Package org.libz; version=1.0
    libZ 2.0 would use Export-Package org.libz; version=2.0
    libX would use Import-Package org.libz; version=2.0
    libY would use Import-Package org.libz; version=1.0
    OSGI also brings a stronger concept of modularity to java applications. Only packages exported using Export-Package can be used outside of the bundle.

  2. Peter Koller says:

    Good post, thank you. It would even be better if you
    removed all that generated Javadoc and TODO noise. It makes examples hard to read.

  3. Hi there would you mind letting me know which web host you’re utilizing? I’ve loaded your blog in 3 different browsers
    and I must say this blog loads a lot faster then most.
    Can you suggest a good hosting provider at a fair price? Thanks a lot,
    I appreciate it!

  4. Write more, thats all I have to say. Literally, it seems as though you relied on the video
    to make your point. You definitely know what youre talking
    about, why waste your intelligence on just posting videos to your weblog when you could be
    giving us something enlightening to read?

  5. I have read so many content about the blogger lovers however
    this paragraph is really a pleasant article, keep it up.

  6. What’s up Dear, are you actually visiting this site daily, if so after that you will definitely get nice know-how.

  7. That is really attention-grabbing, You’re an overly professional blogger. I’ve joined your rss feed and stay up for in quest of extra of your great
    post. Also, I’ve shared your web site in my social networks

  8. You really make it seem so easy along with your presentation but I in
    finding this topic to be really something that I feel I’d never understand. It seems too complicated and very large for me. I’m looking ahead for your next put
    up, I will try to get the grasp of it!

  9. Extraordinarily pleased with the success of her method,
    Alicia Pennington knew she had to share it with the millions of women worldwide who want
    to increase their chances of conceiving the baby boy or girl they want.
    Gifts of pink booties may be premature (no pun intended) for
    Kim Kardashian and Kanye West. There’s absolutely no science behind this tip, but folk medicine gurus have long believed that eating chocolate increases the chance that you will get a baby girl.

  10. www.demul.nl says:

    Hi there, its good piece of writing about media print, we all understand
    media is a wonderful source of facts.

  11. Hey! This is kind of off topic but I need some advice from an established blog.
    Is it hard to set up your own blog? I’m not very techincal but I can figure things out pretty quick. I’m thinking about creating my own but I’m not sure where to start. Do you have any tips or suggestions? Cheers

  12. Woah! I’m really loving the template/theme of this blog. It’s simple, yet
    effective. A lot of times it’s hard to get that “perfect balance” between user friendliness and visual appeal. I must say you’ve done a amazing
    job with this. Also, the blog loads very quick for me on Chrome.
    Exceptional Blog!

  13. Inez says:

    I read this article completely regarding the comparison of latest
    and previous technologies, it’s remarkable article.

  14. Selma says:

    Every weekend i used to go to see this website, as i wish
    for enjoyment, for the reason that this this web page conations in fact good funny stuff too.

  15. Hi I am so thrilled I found your webpage, I really found you by error, while I was researching on Aol for something else, Regardless I am here now and would just like
    to say cheers for a remarkable post and a all round enjoyable blog (I also love the
    theme/design), I don’t have time to read through it all at the minute but I have book-marked it and also added in your RSS feeds, so when I have time I will be back to read a lot more, Please do keep up the awesome work.

  16. What’s up, yup this piece of writing is genuinely nice and I have learned lot of things from it concerning blogging. thanks.

  17. Hi there i am kavin, its my first time to commenting anyplace, when i read this piece of writing i thought i could also make comment due to this good article.

  18. seo experts says:

    With havin so much written content do you ever run into any problems
    of plagorism or copyright violation? My blog has a lot of exclusive content I’ve either authored myself or outsourced but it appears a lot of it is popping it up all over the web without my permission. Do you know any ways to help protect against content from being stolen? I’d truly appreciate it.

  19. This site was… how do I say it? Relevant!
    ! Finally I have found something that helped
    me. Many thanks!

  20. For me all the manifest files are looking like as you shown. but while i am trying to deploy the bundle MathServiceClient-0.0.1-SNAPSHOT.jar on eclipse virgo dependency failure is happening. The error message looks is “An Import-Package could not be resolved. Resolver error data . Caused by missing constraint in bundle
    constraint: “

  21. Hello colleagues, pleasant article and nice urging commented here, I am
    really enjoying by these.

  22. Hurrah, that’s what I was searching for, what a material! present here at this blog, thanks admin of this web page.

  23. android apps says:

    You’ve made some decent points there. I checked on the net for more information about the issue and found most people will go along with your views on this website.

  24. It is not my first time to go to see this web site, i am visiting this web site dailly and take fastidious information from here everyday.

  25. Have you ever thought about including a little
    bit more than just your articles? I mean, what you say is valuable and all.

    However imagine if you added some great photos or videos to give your posts
    more, “pop”! Your content is excellent but with images and clips, this website could definitely be one of the
    best in its niche. Wonderful blog!

  26. What i don’t understood is actually how you’re not really
    much more smartly-liked than you may be now. You are so intelligent.
    You understand thus significantly in relation to this matter, made me in my view believe it from numerous various angles.
    Its like women and men are not involved until it’s one thing to do with Girl gaga!

    Your own stuffs outstanding. Always take care of it up!

  27. Zandra says:

    Good blog you’ve got here.. It’s hard to find good quality writing like yours these days.
    I seriously appreciate individuals like you! Take care!!

  28. Merrill says:

    Howdy! This post couldn’t be written much better!
    Reading through this post reminds me of my previous roommate!
    He continually kept preaching about this. I am going to forward this information to him.
    Pretty sure he’ll have a very good read. I appreciate you for sharing!

  29. Reinaldo says:

    When some one searches for his required thing, therefore he/she wishes to be available that in detail, thus that thing is maintained over here.

  30. continuously i used to read smaller articles or reviews which as well clear their motive, and that is also happening with this
    post which I am reading now.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 28 other followers

%d bloggers like this: