Skip to main content
Jump to: navigation, search

Difference between revisions of "Gyrex/Learning Material/Develop OSGi DS"

(Fixed some expression errors)
Line 2: Line 2:
  
 
This article will show you how to use OSGi Declarative Services in Gyrex. As a example the GreetingService will be implemented and can be used in later tutorials to let the consumer "greet". Using Declarative Services the GreetingService will be made available in the OSGi framework. To make this possible an OSGi DS component has to be created. A well structured pattern provides the service as an interface which will be re-implemented in a component class. This class keeps the reference to the real implementation and only delegates to it.  
 
This article will show you how to use OSGi Declarative Services in Gyrex. As a example the GreetingService will be implemented and can be used in later tutorials to let the consumer "greet". Using Declarative Services the GreetingService will be made available in the OSGi framework. To make this possible an OSGi DS component has to be created. A well structured pattern provides the service as an interface which will be re-implemented in a component class. This class keeps the reference to the real implementation and only delegates to it.  
The hole sample-project with all classes described later in the article you can find [[media:Sample.service.zip|here (zip-file).]]
+
You can find [[media:Sample.service.zip|here (zip-file)]] the whole sample-project with all classes described later in the article.
  
 
=== Requirements  ===
 
=== Requirements  ===
  
The OSGi Declarative Services Tutorial requires a already setup Gyrex target plattform as well as Java 6 or Java 7 runtime environment. <br>  
+
The OSGi Declarative Services Tutorial requires a working Gyrex target plattform as well as Java 6 or Java 7 runtime environment. <br>  
  
 
''This tutorial was created using eclipse Indigo Service Release 2.'' <br>
 
''This tutorial was created using eclipse Indigo Service Release 2.'' <br>
Line 22: Line 22:
 
<pre>Bundle-ActivationPolicy: lazy
 
<pre>Bundle-ActivationPolicy: lazy
 
</pre>  
 
</pre>  
Note that there has to be a space line below the text. [[Image:Manifest mf.jpg|border|center|Your MANIFEST.MF should look like this after adding the packages]] <br>  
+
Please notice the empty line at the end of the text. This is absolutely required [[Image:Manifest mf.jpg|border|center|Your MANIFEST.MF should look like this after adding the packages]] <br>  
  
 
Furthermore you have to add dependencies in the ''MANIFEST''. Switch to register ''Dependencies'' to section ''Automated Management of Dependencies''. There you have to add following packages: [[Image:Added packages.jpg|thumb|Added packages]]  
 
Furthermore you have to add dependencies in the ''MANIFEST''. Switch to register ''Dependencies'' to section ''Automated Management of Dependencies''. There you have to add following packages: [[Image:Added packages.jpg|thumb|Added packages]]  
Line 31: Line 31:
 
*org.eclpse.osgi.services
 
*org.eclpse.osgi.services
  
With this packages you will be able to start the server at the end of this tutorial with the OSGi framework in which your bundle is available. You still need to implement your service. To do this you have to create a new package with the same name as your project with a right-click on ''src'' in your project selecting ''New -&gt; Package''. This package will contain at least 4 classes. In this example there are:  
+
With these packages you will be able to start the server at the end of this tutorial with the OSGi framework in which your bundle is available. You still need to implement your service. To do this you have to create a new package with the same name as your project with a right-click on ''src'' in your project selecting ''New -&gt; Package''. This package will contain at least 4 classes. In this example they are:  
 
<pre>sample.service.GreetingService  
 
<pre>sample.service.GreetingService  
 
sample.service.GreetingServiceImpl  
 
sample.service.GreetingServiceImpl  
 
sample.service.GreetingServiceProvider  
 
sample.service.GreetingServiceProvider  
 
sample.service.GreetingServiceComponent  
 
sample.service.GreetingServiceComponent  
</pre> ''GreetingService'' is an interface providing methods. This methods later will be implemented by several separate bundles, which can be later added dynamically to the running system. Therefore this class wouldn't be placed in the same bundle as the classes implementing the interface, but in a seperate bundle. In this example there are three methods to be implemented.  
+
</pre> ''GreetingService'' is an interface providing methods. These methods will be implemented later by several separated bundles, which can be added dynamically to the running system. Therefore this class should not be placed in the same bundle as the classes implementing the interface, but in a separated bundle. In this example there are three methods to be implemented.  
 
<pre>Colleytion&lt;String&gt; getGreetings()  
 
<pre>Colleytion&lt;String&gt; getGreetings()  
 
void processGreetings()  
 
void processGreetings()  
 
void sayHello(final String greeting)  
 
void sayHello(final String greeting)  
 
</pre>  
 
</pre>  
With this methods the consumer can "greet" (''sayHello''), get a list of all sended greetings (''getGreetings'') and process greetings, which just en The real implementation of the interface are in the class ''GreetingServiceImpl''. The delegation to this methods is done by the class ''GreetingServiceComponent''. There is a implementation of the methods, too. But only to delegate to the referenced "real" implementation. Further Methods are implemented to start/activate and stop/deactivate components. The ''GreetingServiceProvider'' provides the access to the ''GreetingService'' instance.  
+
With these methods the consumer can "greet" (''sayHello''), get a list of all sent greetings (''getGreetings'') and process greetings, which just en The real implementation of the interface are in the class ''GreetingServiceImpl''. The delegation to these methods is done by the class ''GreetingServiceComponent''. There is also an implementation of the methods, but it only delegates to the referenced "real" implementation. Further Methods are implemented to start/activate and stop/deactivate components. The ''GreetingServiceProvider'' provides the access to the ''GreetingService'' instance.  
  
[[Image:Create component def.jpg|thumb|Type in necessary data]] Once you have implemented your classes now you have to tell the OSGi framework, that you have implemented a new component to use. It is necessary to tell the framework which interface you provide and which class the interface provide. In order to do this create an new folder in your project called '''"OSGI-INF"''' and then create an OSGi DS component there. ''Right-click'' on this folder ''-&gt; New -&gt; Other''. Type in '''"Component Definition"''' and select the shown option. On next page the parent folder should be '''"sample.service/OSGI-INF"'''. The file name in this example is '''"greeting-service.xml"'''. In ''Component Definiton Information'' the Name is '''"sample.service.component"''' and the class is the '''"sample.service.GreetingServiceComponent"''', which is the called class and delegates to the real implementation. By clicking on ''Finish'' this file will be created, too. <br> After you opened this file switch to the register ''Source''. There, methods activate and deactivate have to be added. [[Image:Greeting service xml.jpg|border|center|Your greetings-service.xml should looks like this now]] <br> At the end you have to tell your ''MANIFEST.MF'' that there is a Service-Component. Open the ''MANIFEST.MF'' and switch to the register ''MANIFEST.MF'' and add following line if it isn't allready done:  
+
[[Image:Create component def.jpg|thumb|Type in necessary data]] Once you have implemented your classes, you have to tell the OSGi framework that you have implemented a new component to use. It is necessary to tell the framework which is the interface that you provide and which class the interface provides. In order to do this, create an new folder in your project called '''"OSGI-INF"''' and then create an OSGi DS component there. ''Right-click'' on this folder ''-&gt; New -&gt; Other''. Type in '''"Component Definition"''' and select the shown option. On the next page the parent folder should be '''"sample.service/OSGI-INF"'''. The filename in this example is '''"greeting-service.xml"'''. In ''Component Definiton Information'' the name is '''"sample.service.component"''' and the class is '''"sample.service.GreetingServiceComponent"''', which is the called class, and delegates to the real implementation. By clicking on ''Finish'' this file will be created too. <br> After you opened this file, switch to the register ''Source''. There, methods activate and deactivate have to be added. [[Image:Greeting service xml.jpg|border|center|Your greetings-service.xml should looks like this now]] <br> At the end you have to tell your ''MANIFEST.MF'' that there is a Service-Component. Open the ''MANIFEST.MF'', switch to the register ''MANIFEST.MF'' and add the following line if it isn't already done:  
 
<pre>Service Component: OSGI-INF/greetings-service.xml
 
<pre>Service Component: OSGI-INF/greetings-service.xml
 
</pre>  
 
</pre>  
[[Image:Debug configuration.jpg|thumb|Edit Debug Configurations]] To Start the server now, you have to setup the debug configurations. To accomplish this right-click on your project, choose ''Debug As -&gt; Debug Configurations..''. Right-clicking on ''Eclipse Application'' an choosing ''New'' opens the page to set up the configuration. To set up a name just type it in the box ''Name''. In the section ''Program to Run'' select ''Run an application'' and '''org.eclipse.gyrex.boot.server'''. After switching to the register ''Arguments'' you have to add '''"-console"''' to the ''Program arguments'' in order to be able to monitor the state of the components. [[Image:Debug configuration 2.jpg|border|center|Add "-console" to the program arguments.]] <br> With clicking ''Apply'' and then ''Debug'' the server will start. Now open the console view where you can monitor all necessary bundles are starting. Once you read the line: ''[Worker-0] INFO o.e.jetty.server.AbstractConnector - Started SelectChannelConnector@0.0.0.0:3110'' first press ''Enter'' and you can issue a few console commands to check your components state. Possible commands are: [[Image:Console output.jpg|thumb|Console output]]  
+
[[Image:Debug configuration.jpg|thumb|Edit Debug Configurations]] To Start the server now, you have to setup the debug configurations. To accomplish this, right-click on your project, choose ''Debug As -&gt; Debug Configurations..''. Right-clicking on ''Eclipse Application'' an choosing ''New'' opens the page to set up the configuration. To set up a name just type it in the box ''Name''. In the section ''Program to Run'' select ''Run an application'' and '''org.eclipse.gyrex.boot.server'''. After switching to the register ''Arguments'' you have to add '''"-console"''' to the ''Program arguments'' in order to be able to monitor the state of the components. [[Image:Debug configuration 2.jpg|border|center|Add "-console" to the program arguments.]] <br> With clicking ''Apply'' and then ''Debug'' the server will start. Now open the console view where you can monitor that all the necessary bundles are starting. Once you read the line: ''[Worker-0] INFO o.e.jetty.server.AbstractConnector - Started SelectChannelConnector@0.0.0.0:3110'' first press ''Enter'' and you can issue a few console commands to check your components state. Possible commands are: [[Image:Console output.jpg|thumb|Console output]]  
  
*'ss '+name - shows all bundlesof "name", there state and ID ('ss sample')  
+
*'ss '+name - shows all bundles of "name", their state and ID ('ss sample')  
 
*'start '+id - starts the bundle called by id ('start 297')  
 
*'start '+id - starts the bundle called by id ('start 297')  
 
*'stop '+id - stops the bundle called by id ('stop 297')  
 
*'stop '+id - stops the bundle called by id ('stop 297')  
 
*'ls' - shows all available components
 
*'ls' - shows all available components
  
At this point this tutorial finishs. Now you have implemented a component in OSGi Declarative Services with the possibilty to change the state of it. It's the basis to implement whole OSGi frameworks. How it's said at the beginning, an interface normaly is separated in an extra bundle from which you want to access the real implementations dynamicaly according the scenario. This will be shown in a next tutorial.
+
This tutorial ends at this point. Now you have implemented a component in OSGi Declarative Services with the possibilty to change the state of it. This is the basis to implement whole OSGi frameworks. Like we said at the beginning, an interface is normally separated in an extra bundle from which you want to access the real implementations dynamicaly according to the scenario. This will be shown in a next tutorial.

Revision as of 08:25, 19 June 2012

Gyrex
Website
Download
Community
Mailing ListForumsIRCmattermost
Bugzilla
OpenHelp WantedBug Day
Contribute
Browse SourceProject Set File

This article will show you how to use OSGi Declarative Services in Gyrex. As a example the GreetingService will be implemented and can be used in later tutorials to let the consumer "greet". Using Declarative Services the GreetingService will be made available in the OSGi framework. To make this possible an OSGi DS component has to be created. A well structured pattern provides the service as an interface which will be re-implemented in a component class. This class keeps the reference to the real implementation and only delegates to it. You can find here (zip-file) the whole sample-project with all classes described later in the article.

Requirements

The OSGi Declarative Services Tutorial requires a working Gyrex target plattform as well as Java 6 or Java 7 runtime environment.

This tutorial was created using eclipse Indigo Service Release 2.

Tutorial

Select Plug-In Project
The first step is to create a new plug-in project by clicking File -> New -> Other. Typing in "Plug-In Project" and select the shown option. After clicking Next, give your project a name like "sample.service". In the section Target Platform select "Equinox" as the OSGi framework. At this time we don't need an Activator so deselect it on the next page. Here you also can give a special name for your plug-in. On the next page you can choose, whether you want to create the plug-in with templates, but just remove the check mark on this page. Clicking Finish on the next page the project will be created.
Now it's required to import some packages. To do so open the MANIFEST.MF of your project. You will find this file in the folder META-INF. Switch to the register MANIFEST.MF and add following lines:
Import-Package: org.apache.commons.lang;version="[2.4.0,3.0.0)", 
                org.apache.commons.lang.time;version="[2.4.0,3.0.0)", 
                org.eclipse.gyrex.cloud.environment;version="[1.0.0,2.0.0)";resolution:=optional,
                org.osgi.service.component;version="[1.2.0,2.0.0)",
                org.slf4j;version="[1.6.0,2.0.0)"

Add following line to the MANIFEST.MF, too.

Bundle-ActivationPolicy: lazy
Please notice the empty line at the end of the text. This is absolutely required
Your MANIFEST.MF should look like this after adding the packages

Furthermore you have to add dependencies in the MANIFEST. Switch to register Dependencies to section Automated Management of Dependencies. There you have to add following packages:
Added packages
  • org.slf4j.api
  • org.apache.commons.lang
  • org.eclipse.gyrex.cloud
  • org.eclipse.osgi
  • org.eclpse.osgi.services

With these packages you will be able to start the server at the end of this tutorial with the OSGi framework in which your bundle is available. You still need to implement your service. To do this you have to create a new package with the same name as your project with a right-click on src in your project selecting New -> Package. This package will contain at least 4 classes. In this example they are:

sample.service.GreetingService 
sample.service.GreetingServiceImpl 
sample.service.GreetingServiceProvider 
sample.service.GreetingServiceComponent 
GreetingService is an interface providing methods. These methods will be implemented later by several separated bundles, which can be added dynamically to the running system. Therefore this class should not be placed in the same bundle as the classes implementing the interface, but in a separated bundle. In this example there are three methods to be implemented.
Colleytion<String> getGreetings() 
void processGreetings() 
void sayHello(final String greeting) 

With these methods the consumer can "greet" (sayHello), get a list of all sent greetings (getGreetings) and process greetings, which just en The real implementation of the interface are in the class GreetingServiceImpl. The delegation to these methods is done by the class GreetingServiceComponent. There is also an implementation of the methods, but it only delegates to the referenced "real" implementation. Further Methods are implemented to start/activate and stop/deactivate components. The GreetingServiceProvider provides the access to the GreetingService instance.

Type in necessary data
Once you have implemented your classes, you have to tell the OSGi framework that you have implemented a new component to use. It is necessary to tell the framework which is the interface that you provide and which class the interface provides. In order to do this, create an new folder in your project called "OSGI-INF" and then create an OSGi DS component there. Right-click on this folder -> New -> Other. Type in "Component Definition" and select the shown option. On the next page the parent folder should be "sample.service/OSGI-INF". The filename in this example is "greeting-service.xml". In Component Definiton Information the name is "sample.service.component" and the class is "sample.service.GreetingServiceComponent", which is the called class, and delegates to the real implementation. By clicking on Finish this file will be created too.
After you opened this file, switch to the register Source. There, methods activate and deactivate have to be added.
Your greetings-service.xml should looks like this now

At the end you have to tell your MANIFEST.MF that there is a Service-Component. Open the MANIFEST.MF, switch to the register MANIFEST.MF and add the following line if it isn't already done:
Service Component: OSGI-INF/greetings-service.xml
Edit Debug Configurations
To Start the server now, you have to setup the debug configurations. To accomplish this, right-click on your project, choose Debug As -> Debug Configurations... Right-clicking on Eclipse Application an choosing New opens the page to set up the configuration. To set up a name just type it in the box Name. In the section Program to Run select Run an application and org.eclipse.gyrex.boot.server. After switching to the register Arguments you have to add "-console" to the Program arguments in order to be able to monitor the state of the components.
Add "-console" to the program arguments.

With clicking Apply and then Debug the server will start. Now open the console view where you can monitor that all the necessary bundles are starting. Once you read the line: [Worker-0] INFO o.e.jetty.server.AbstractConnector - Started SelectChannelConnector@0.0.0.0:3110 first press Enter and you can issue a few console commands to check your components state. Possible commands are:
Console output
  • 'ss '+name - shows all bundles of "name", their state and ID ('ss sample')
  • 'start '+id - starts the bundle called by id ('start 297')
  • 'stop '+id - stops the bundle called by id ('stop 297')
  • 'ls' - shows all available components

This tutorial ends at this point. Now you have implemented a component in OSGi Declarative Services with the possibilty to change the state of it. This is the basis to implement whole OSGi frameworks. Like we said at the beginning, an interface is normally separated in an extra bundle from which you want to access the real implementations dynamicaly according to the scenario. This will be shown in a next tutorial.

Back to the top