The "One Laptop Per Child" project has a great device ready to ship, but there's no Java on there. Let's think about working together to put Java on OLPC!
Over the next week or two, EclipseZone will be running a series of short posts on OSGi. Taken together they should form a smooth path into mastering the art of OSGi programming, but each post will introduce just one new technique and it should be possible to work through in under ten minutes. Also, we want to show how simple OSGi development can be, so we will not be using Eclipse for development - just a text editor and the basic command line tools will do. So, welcome to the "Getting started with OSGi" series.
Actually this first post will be a little longer than the others, because we need to set up a very basic working environment. Before getting started, we need an OSGi framework to run on. There are three open source implementations to choose from:
Apache Felix
,
Knopflerfish
, and
Equinox
. The code we're going to write will be identical no matter which one you choose, but the instructions for running it will be a little different. Since this is EclipseZone we will use Equinox, the runtime that Eclipse itself is built on. You can pull a copy of it right out of your existing Eclipse installation: just find the file
org.eclipse.osgi_3.2.1.R32x_v20060919.jar
and copy it to an empty directory (NB the version string might be a little different depending on what version of Eclipse you have). If you don't have a copy of Eclipse anywhere, then you can download just that Jar file from
http://download.eclipse.org/eclipse/equinox/
.
To keep the commands short, let's rename the Jar file to
equinox.jar
. Now bring up a Command Prompt in our development directory and run the command
> java -jar equinox.jar -console
In a few seconds, the
osgi>
prompt should appear. Congratulations, you are now running OSGi!
The
osgi>
prompt gives us access to commands in Equinox to control the framework. If you like, type
help
to see a list of commands, and have a play with them. Done that? Now type
ss
. This is the most frequently used command; it stands for "short status" and it shows us the list of bundles that are installed, and what their current status is. (A "bundle" is a module in OSGi terminology. Or if you are an Eclipse developer, you may know them as plug-ins; bundles and plug-ins are basically the same things.)
Equinox should print out the following:
Framework is launched.
id State Bundle
0 ACTIVE system.bundle_3.2.1.R32x_v20060919
This tells us that there is one bundle installed and active, and it is the System Bundle. This is a special bundle in OSGi that is always present, and it represents the framework itself.
Now, we're going to write our own bundle. In the same directory as before, create a file called
HelloActivator.java
and copy the following code into it:
A bundle also needs a manifest file that declares various metadata about the bundle, e.g. its name, version, etc. So create a file called
HelloWorld.mf
and copy the following text into it.
Make very sure
that this file ends with a blank line, otherwise the
jar
command line tool will truncate the file.
Going back into the OSGi console, type
install file:HelloWorld.jar
. The reply should be
"Bundle id is 1"
. Type
ss
again and you will see the following:
Framework is launched.
id State Bundle
0 ACTIVE system.bundle_3.2.1.R32x_v20060919
1 INSTALLED HelloWorld_1.0.0
Our HelloWorld bundle is installed... but it's not yet active. We'll look into what these states mean in a later post, but for now we just need to start the bundle by typing
start 1
. The "1" is the ID of the bundle from the first column. When you do this you should see the message "Hello EclipseZone Readers!". Now type
stop 1
and you will see "Goodbye EclipseZone Readers!". Repeat this until you get bored. Don't forget to do
ss
occasionally to see the state of the bundle changing.
What's happening here? Our code implements the
BundleActivator
interface, allowing the framework to notify us of important lifecycle events. When the bundle is started, the framework calls the
start
method, and when the bundle is stopped, the framework calls the
stop
method. The other thing going on here is the line in the manifest file
"Bundle-Activator: HelloActivator"
, which tells the framework which class in our bundle is the activator. Normally the name we give is a fully-qualified class name, but we were lazy and used the default package.
And that concludes our first installment. See you next time.
There's an article in the pipeline (should be later this week) on a comparison of Equinox extensions and services; and I suspect it will be touched on in the near future in this series too
OSGi is a very interesting framework, since it can be used on anything on which you can run a JVM - from the smallest embedded devices to the largest servers.
Thanks for this short introduction, Neil.
If you want to play a bit more before Neil writes his next post, have a look at the Equinox QuickStart Guide. It explains a bit more about how to configure Equinox and how to have your bundle started automatically when you start Equinox.
1. Yes you can name the manifest file whatever you like during the build process, as long as you refer to it by that name when constructing the Jar. It always ends up as MANIFEST.MF inside the Jar though.
2. Bundle-Name is a human-readable description of the bundle, which can contain spaces. Bundle-SymbolicName is really more like the ID of the bundle. It cannot contain spaces, and in Eclipse it usually looks like a Java package name, eg "org.eclipse.core.runtime".
3. No, you can only have one or zero activators. Well, you can have multiple classes that implement the BundleActivator interface, but only one of them is THE activator for the bundle.
True, though it's fairly easy to use THE activator to chain together multiple other 'activator'-like classes. In fact, you can even use a custom entry in the manifest to achieve that, like:
Dear Neil,
I have some problems with your tutorial.
I created the class HelloActivator.java and the manifest file HelloWorld.mf, compiled the java file and generated the jar file.
I had success in install the bundle in equinox, but when I try to start the bundle the follow exception appear:
org.osgi.framework.BundleException: The activator HelloActivator for bundle HelloWorld is invalid
...
Nested Exception:
java.lang.IllegalAccessException: Class org.eclipse.osgi.framework.internal.core.AbstractBundle can not access a member
of class HelloActivator with modifiers ""
...
Nested Exception:
java.lang.IllegalAccessException: Class org.eclipse.osgi.framework.internal.core.AbstractBundle can not access a member
of class HelloActivator with modifiers ""
Getting started with OSGi: Your first bundle
At 9:15 PM on Feb 6, 2007, Neil Bartlett
wrote:
Actually this first post will be a little longer than the others, because we need to set up a very basic working environment. Before getting started, we need an OSGi framework to run on. There are three open source implementations to choose from: Apache Felix , Knopflerfish , and Equinox . The code we're going to write will be identical no matter which one you choose, but the instructions for running it will be a little different. Since this is EclipseZone we will use Equinox, the runtime that Eclipse itself is built on. You can pull a copy of it right out of your existing Eclipse installation: just find the file
org.eclipse.osgi_3.2.1.R32x_v20060919.jarand copy it to an empty directory (NB the version string might be a little different depending on what version of Eclipse you have). If you don't have a copy of Eclipse anywhere, then you can download just that Jar file from http://download.eclipse.org/eclipse/equinox/ .To keep the commands short, let's rename the Jar file to
equinox.jar. Now bring up a Command Prompt in our development directory and run the commandIn a few seconds, the
osgi>prompt should appear. Congratulations, you are now running OSGi!The
osgi>prompt gives us access to commands in Equinox to control the framework. If you like, typehelpto see a list of commands, and have a play with them. Done that? Now typess. This is the most frequently used command; it stands for "short status" and it shows us the list of bundles that are installed, and what their current status is. (A "bundle" is a module in OSGi terminology. Or if you are an Eclipse developer, you may know them as plug-ins; bundles and plug-ins are basically the same things.)Equinox should print out the following:
This tells us that there is one bundle installed and active, and it is the System Bundle. This is a special bundle in OSGi that is always present, and it represents the framework itself.
Now, we're going to write our own bundle. In the same directory as before, create a file called
HelloActivator.javaand copy the following code into it:import org.osgi.framework.*; public class HelloActivator implements BundleActivator { public void start(BundleContext context) { System.out.println("Hello EclipseZone Readers!"); } public void stop(BundleContext context) { System.out.println("Goodbye EclipseZone Readers!"); } }A bundle also needs a manifest file that declares various metadata about the bundle, e.g. its name, version, etc. So create a file called
HelloWorld.mfand copy the following text into it. Make very sure that this file ends with a blank line, otherwise thejarcommand line tool will truncate the file.Now open a new Command Prompt (because we want to leave OSGi running) and build the Jar with the following commands:
Going back into the OSGi console, type
install file:HelloWorld.jar. The reply should be"Bundle id is 1". Typessagain and you will see the following:Our HelloWorld bundle is installed... but it's not yet active. We'll look into what these states mean in a later post, but for now we just need to start the bundle by typing
start 1. The "1" is the ID of the bundle from the first column. When you do this you should see the message "Hello EclipseZone Readers!". Now typestop 1and you will see "Goodbye EclipseZone Readers!". Repeat this until you get bored. Don't forget to dossoccasionally to see the state of the bundle changing.What's happening here? Our code implements the
BundleActivatorinterface, allowing the framework to notify us of important lifecycle events. When the bundle is started, the framework calls thestartmethod, and when the bundle is stopped, the framework calls thestopmethod. The other thing going on here is the line in the manifest file"Bundle-Activator: HelloActivator", which tells the framework which class in our bundle is the activator. Normally the name we give is a fully-qualified class name, but we were lazy and used the default package.And that concludes our first installment. See you next time.
14 replies so far (
Post your own)
Re: Getting started with OSGi: Your first bundle
Hey Neil, this is good stuff. I'm looking forward to the rest of the series. Will you be covering OSGi services too?charlie
Re: Getting started with OSGi: Your first bundle
There's an article in the pipeline (should be later this week) on a comparison of Equinox extensions and services; and I suspect it will be touched on in the near future in this series tooAlex.
Re: Getting started with OSGi: Your first bundle
Thanks Charlie. Yes, I will definitely be covering services soon.Neil
Re: Getting started with OSGi: Your first bundle
OSGi is a very interesting framework, since it can be used on anything on which you can run a JVM - from the smallest embedded devices to the largest servers.Thanks for this short introduction, Neil.
If you want to play a bit more before Neil writes his next post, have a look at the Equinox QuickStart Guide. It explains a bit more about how to configure Equinox and how to have your bundle started automatically when you start Equinox.
Re: Getting started with OSGi: Your first bundle
Thanks to Neil, this is a good tutorial and it kicks me started with OSGi/Equinox easily!Can we name the manifest file anything we like instead of HelloWorld.mf?
What does the Bundle-Name and Bundle-SymbolicName means to OSGi framework?
Can we have multiple activator classes in one bundle?
Re: Getting started with OSGi: Your first bundle
Hi wolverine.my,1. Yes you can name the manifest file whatever you like during the build process, as long as you refer to it by that name when constructing the Jar. It always ends up as MANIFEST.MF inside the Jar though.
2. Bundle-Name is a human-readable description of the bundle, which can contain spaces. Bundle-SymbolicName is really more like the ID of the bundle. It cannot contain spaces, and in Eclipse it usually looks like a Java package name, eg "org.eclipse.core.runtime".
3. No, you can only have one or zero activators. Well, you can have multiple classes that implement the BundleActivator interface, but only one of them is THE activator for the bundle.
Neil
Re: Getting started with OSGi: Your first bundle
True, though it's fairly easy to use THE activator to chain together multiple other 'activator'-like classes. In fact, you can even use a custom entry in the manifest to achieve that, like:and then read/process that in the Bundle's activator
public void start(BundleContext context) { String others = context.getBundle().getHeaders(). get("Alex-Other-Activators"); String[] activators = others.split(","); for(int i;i=0;i<activators.length) { // do something with activators[i] } }Of course, it's usually far easier to implement by just delegating calls out from the start() method instead
Alex.
Re: Getting started with OSGi: Your first bundle
Good work!Thanks.
Re: Getting started with OSGi: Your first bundle
Does any body know where can I find more about Equinox console commands syntaxes?Thanks in Advance
Ali
Re: Getting started with OSGi: Your first bundle
Ali,Did you try typing "help"?
Regards
Neil
Re: Getting started with OSGi: Your first bundle
Yes, it doesn't contain syntax.Re: Getting started with OSGi: Your first bundle
Dear Neil,I have some problems with your tutorial.
I created the class HelloActivator.java and the manifest file HelloWorld.mf, compiled the java file and generated the jar file.
I had success in install the bundle in equinox, but when I try to start the bundle the follow exception appear:
org.osgi.framework.BundleException: The activator HelloActivator for bundle HelloWorld is invalid
...
Nested Exception:
java.lang.IllegalAccessException: Class org.eclipse.osgi.framework.internal.core.AbstractBundle can not access a member
of class HelloActivator with modifiers ""
...
Nested Exception:
java.lang.IllegalAccessException: Class org.eclipse.osgi.framework.internal.core.AbstractBundle can not access a member
of class HelloActivator with modifiers ""
What can I do to resolve this problems?
Thanks.
Re: Getting started with OSGi: Your first bundle
I forget to say that I'm using the org.eclipse.osgi_3.3.2.R33x_v20080105 equinox version.Thanks.
Re: Getting started with OSGi: Your first bundle
I tried with Eclipse 3.3 and it works as well.Make very sure that this file ends with a blank line, otherwise the jar command line tool will truncate the file.