73979

Declarative OSGi Services

Question:

I have a question about declarative OSGi Services. I have the following interface :

public interface PrintService { public void print(); }

and its implementation:

public class PrintServiceImpl implements PrintService { @Override public void print() { System.out.println("Hello from PrintServiceImpl!"); } }

OSGI-INF/component.xml :

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="service"> <implementation class="service.PrintServiceImpl"/> <service> <provide interface="print.PrintService"/> </service> </scr:component>

MANIFEST.MF :

Service-Component: OSGI-INF/component.xml

After I install the service and start it nothing happend. How can I activate it and print "<em>Hello from PrintServiceImpl!</em>" to console.

Answer1:

Why do you expect your print method to be invoked? It is part of the interface of the service, so it will not be invoked until you can a client that binds to it and calls it.

If you type the services command in the console you should see that your bundle is publishing the print.PrintService service; this means that your component is working. If you don't see this then you may be missing something like the SCR bundle as suggested by Tom Seidel in the comments above.

Answer2:

You should make explicit that you want you service to start when the bundle is started. Otherwise, it will be instantiated lazily, and give that no other service requires the PrintService, it will not be instantiated at all.

You can control your service lifecycle (with regard to the bundle lifecycle) using the attributes enabled and immediate. enabled is trivial: indicates whether your service is enabled or not when the bundle is started. immediate indicates whether this service is lazy ot not. immediate="true" will start your service <em>immediatly</em>, immediate="false" will apply lazy instantiation (i.e. wait until some other service requests this service as a dependency)

e.g.

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="PrintService" activate="activate" deactivate="deactivate" modified="modified" enabled="true" immediate="true">

As Chris mentioned, if you want your service to do something when it's activated, you should add some code to the activate lifecycle method (note that the name of the method can be specified in the component descriptor like it was done explicitly above)

protected final void activate() { print(); }

Answer3:

Perhaps you want to do the print from your activate method?

public class PrintServiceImpl implements PrintService { protected final void activate() { System.out.println("Hello from PrintServiceImpl!"); } protected final void deactivate() { System.out.println("Goodbye from PrintServiceImpl!"); } ... }

Otherwise, Neil's answer is the right one: you want a client that uses the service via ServiceTracker or <reference> and explicitly invokes the print() method.

Answer4:

All the answers above are correct. Now to have something like printing something on the shell you could write something like:

public interface PrintService { public void print(); }

Implentation:

public class PrintServiceImpl implements PrintService { @Override public void print() { System.out.println("Hello from PrintServiceImpl!"); } }

component.xml:

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="service"> <implementation class="service.PrintServiceImpl"/> <service> <provide interface="print.PrintService"/> </service> </scr:component>

And now you could use a Command to call your print method:

public class PrintCommand implements Command { private PrintService printer; public void setPrinter(PrintService printer) { this.printer = printer; } public void unsetPrinter(PrintService printer) { this.printer = null; } @Override public void execute(String line, PrintStream arg1, PrintStream arg2) { printer.print(); } @Override public String getName() { return "print"; } @Override public String getShortDescription() { return "just a printer"; } @Override public String getUsage() { return "print"; } }

And your component.xml should have a new entry:

<component name="PrintCommand"> <implementation class="PrintCommand"/> <service> <provide interface="org.apache.felix.shell.Command"/> </service> <reference name="printer" interface="PrintService" bind="setPrinter" unbind="unsetPrinter" cardinality="1..1" policy="static" /> </component>

The Command Interface is part of Apache Felix Shell and if you now run Felix and type help in your console you will see all registered commands and there is the PrintCommand as well print. If you now type print in the shell you will see the text.

Answer5:

Did you ever get this working? For me it was that the Eclipse .ds bundle just hadn't started yet, and as such the service wasn't registered (yet). When I started it manually my service was registered correctly.

Recommend

  • jQuery: Disable onclick event using off() not working
  • Updating running animations smoothly
  • Can't see Resources namespaces in ASP.NET MVC application
  • Getting IP address, port and connection type from a socket fd
  • Describe relationship in maximo 7.5
  • Android video crop using ffmpeg
  • Visual Studio Publish - Include folder that is not added to Project
  • In WPF,MVVM should ViewModel be involved in opening a window, e.g. About-window?
  • Check when an animation has ended in SVG
  • Cannot access sitecore item field via API
  • ReactJs.net server side render failing after publish
  • Create function that can pass a parameter without making a new component
  • Request response issues in biztalk
  • How to get listview position?
  • cordova is not defined - cordova.js has already been loaded :: Ionic
  • Clear fused location provider's location for testing
  • Spring Cloud Microservice Architecture Confusion
  • Connect .sks to skscene.h
  • Transactional Create with Validation in ServiceStack Redis Client
  • azure media services - The request body is too large and exceeds the maximum permissible limit
  • How to test if a URL from an Eclipse bundle is a directory?
  • Admob requires api-13 or later can I not deploy on old API-8 phones?
  • Unity3D & Android: Difference between “UnityMain” and “main” threads?
  • Handling un-mapped Rest path
  • Jenkins: How To Build multiple projects from a TFS repository?
  • PHP - How to update data to MySQL when click a radio button
  • How do I fake an specific browser client when using Java's Net library?
  • Does CUDA 5 support STL or THRUST inside the device code?
  • When should I choose bucket sort over other sorting algorithms?
  • How do you troubleshoot character encoding problems?
  • Apache 2.4 - remove | delete | uninstall
  • Run Powershell script from inside other Powershell script with dynamic redirection to file
  • Cannot Parse HTML Data Using Android / JSOUP
  • PHP: When would you need the self:: keyword?
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • Understanding cpu registers
  • How do I configure my settings file to work with unit tests?
  • How to get Windows thread pool to call class member function?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Binding checkboxes to object values in AngularJs