Issue with service dynamism and blueprint - osgi

I have a non-blueprint bundle which provides a service via Declarative Service annotations.
I have another bundle, using blueprint, which contains a optional reference for this service and then injects this reference into a number of declared beans.
Starting up both within a Karaf container, the service is registered and the blueprint bundle can access it and use as intended. The configuration for the service providing bundle can be updated, and it is unbound and rebound again to the blueprint bundle which is perfect.
However, when the service providing bundle is restarted, or updated, the service is unbound but never rebound to the using bundle, so that the proxy object held by the blueprint reference never resolves to the service reference.
Sometimes restarting the blueprint bundle will fix this, but usually it requires a full framework restart to get it working again.
I do not get the same behavior when a non-blueprint bean is consuming the service via declarative services.
Has anyone had any similar issues with using a mix of DS and blueprint to provide/consume services?

Blueprint is not dynamic. It has a "damping" proxy which tries to wallpaper over service dynamism but does not always provide what is needed. In general, I would always use DS over Blueprint.

Related

Karaf retrieve a service object / reference from bundle context

In Karaf version 3.0.3 i was able to retrieve the ServiceReference object using the below code
ServiceReference serviceReference =
(ServiceReference) bundleContext.getServiceReference(CustomService.class.getName());
But in Karaf 4 this code returns null. My service is started i was able to see the service in the service list.
Note: i am trying to retrieve a service which is loaded as a wrapped bundle
If you are sure that your service is started then the reason is that service provider and your service client above see different instances of the CustomService class.
Maybe you have two bundles that export that package. Or the package is embedded into the provider or client too. Another reason might be that you retrieve the service reference before the service comes up. Do you do this in the Activator?
If yes .. then this is a bad practice as you can run into timing problems. Better use a ServiceTracker or DS or blueprint.
You can check for duplicate exports using this command:
package:exports -d

Why use #Component annotation with each service in CQ

I am bit confused about following things. I understand #Service and #Component annotations are main annotations when we define a component or a service in OSGi. I am referring to http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/scr-annotations.html and What is the difference between OSGi Components and Services
Questions:
A service can not be created without #Component annotation, why is that?
I understand once we define a service its life-cycle is managed by OSGi differently but what are the advantages of doing so?
How do we use class defined as #Component as service can be accessed via sling.getService(ServiceName.class)
A service can be published without a #Component annotation, but you have to do it programmatically. If you use the annotation then you benefit from the automatic metadata generation in the build tool, and also from the Declarative Services runtime framework. This simplifies a lot of things. If you want to do it with low-level code you have to write an implementation of BundleActivator, declare that with the Bundle-Activator manifest header, call context.registerService etc. Bottom line: just use the #Component annotation!
Simple: laziness. When a component is a service then it can be instantiated lazily "on-demand", i.e. only when consumer first tries to use the service. Non-service components, on the other hand, usually do other kinds of things inside themselves, e.g. running a web server or a GUI or a polling thread, whatever. These need to be running all the time, rather than on-demand.
3. I didn't understand this question.
A component that is not published as a service cannot be accessed from outside the bundle. If you want it to be accessible then it has to be a service. In case you think this is useless, consider a component that creates an HTTP server. It opens port 80 and responds to network requests from the outside world. So it does something useful even though it's not a service and not accessible from other bundles. This kind of component is like a bridge between your application and the outside world; whereas services are a bridge between one part of your application and another part.
OSGi is the one where bundles are installed and manages. Everything that needs to be there in OSGi has to be a component be it simple component, a service or servlet. That is why we need to use #Component with service also.
Services are singleton. Everything that needs to be managed for Singleton class and using reference of service is done by OSGi. Nothing has to be done from our side. So everything is automatically managed.
You dont access components like that. Components are independently used. Quoting example from different post:
Suppose you want to a write Server component that sits on socket and responds to requests over TCP/IP. When the component starts, it opens the socket and creates the thread(s) required to serve clients. When it stops, it closes the thread(s) and socket

OSGi Services: Requesting a Bundle's/Component's Referenced Services

I’m currently “struggling” with OSGi services, or to be more specific, with the wiring between the services. I’m aware of the basics of DS, SCR and the general strategies for a component instance to acquire services. Anyway, here is my problem:
Following DS, components declare e.g. their provided and consumed services in a XML-file. In my case, I’m interested in the “consumed/referenced” services of a particular component (which are declared by the “Reference” tag in the component’s XML-file).
E.g. consider a running OSGi-application: a bunch of bundles collaborating with each other based on services (DS). Now, I want to pick a particular bundle and query all its references to the services it (may) consume - no matter if these services are currently available or not.
Referring to Apache Felix GoGo shell commands, like inspect requirements *, I do get information about the imported packages etc. but not a complete overview about the consumed services (-> both currently consumed services and services the component is waiting for).
I’ve read about the Framework API which provides insight in the registration, modification and deregistration of service but apparently, it does not provide the information about what services bundles are waiting for. Following the OSGi core specification, this could be achieved by a Listener Hook.
Isn’t there a way, where I just can query e.g. the SCR to get all referenced services of a specific bundle? Obviously, the SCR is supposed to read the bundle’s Service-Component-XML-file and to “register” some kind of “Service Tracker” to track the consumed/referenced services – hence the information of a bundle’s consumed/referenced services should somehow be available, shouldn’t it?
It would be great if you could help me with this.
Thanks,
Don
Checkout xray, http://softwaresimplexity.blogspot.com/2012/07/xray-again.html, from Peter Kriens.

OSGi Declarative Service referencing non Declarative Service

I have a system declaring services "the old way", using activator methods.
Now I'm writing a new bundle using Declarative Services.
Is it possible to reference a service that is not published using the Declarative Services technique in my new bundle?
There is no "the old way" to publish you services into OSGi Service Registry. There is only one way with BundleContext.registerService(). You can do it manually from you activator, or Declarative Services / Blueprint engines can do it for you.
In your DS descriptor you just define references to services that are available in Service Registry.
Yes, it is possible. When you reference a service from a DS component, you don't need to worry about that service's internal implementation.
The other service may be another DS component, or it may be a Spring-DM component, or it may be published with explicit calls to the OSGi APIs. You don't care. It's just a service.

OSGI Embedded Equinox - Bundle to access pojos not instantiated in osgi framework

I have a server side application and want to embed an osgi framework into for dynamic bundle loading.
Suppose I want to expose a QuoteImpl implementing IQuote(instantiated as part of the server container bootstrap/Spring) to be used by different Bundles.
Q1. Is there a clean way of exposing server-application instances to Bundles ? (btw because of legacy it is not possible to make server code into bundle :) and donot want to make entire application osgi'ed.
Tried exposing via a service and bundle to cast into an IQuote. Not sure I am doing it well but fails with unresolved compilation problems as IQuote resides in the core app projects as opposed to the bundle project. any ideas?
Yes the way to do this is with a service. The "host" application would publish the service and the bundles inside OSGi would consume the service in the normal way.
The key to get this working is that the service API (i.e. the package containing IQuote) must be exported by the host application through the system bundle exports. You can control this by setting the org.osgi.framework.system.packages.extra property when you create the embedded OSGi framework. I wrote a blog post on this subject that should help you get started (look for the heading "Exposing Application Packages").
You state that you have compilation problems. To fix those it's necessary to know how you have structured your projects and build system.
This is how I embedded Equinox OSGi runtime in my Java class. I suppose you could do the same. https://github.com/sarxos/equinox-launcher/blob/master/src/main/java/com/github/sarxos/equinox/Launcher.java

Resources