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
Related
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.
We are using Axis2 and Rampart for SOAP web services. When a normal client invokes the stub, the SOAP message is properly created ( with WS-Security headers ) and serviced at the server. When we wrap the client ( along with the WS Stub and dependencies ) in a bundle and execute under OSGi ( Felix Karaf ) the header is not generated and this results in the Server returning a SoapFault.
The things that I have tried are
Confirmed that the mar file is being accessed and rampart is "engage"d in OSGi
Confirmed the version of all the jars being used
Checked the SOAP message that is sent - noticed two differences
the message from the standard client had the namespaces declared and abbreviated while the OSGI version had the namespaces in every node
the OSGI message did not have the WS-Security Header
I have used a composite OSGI bundle which includes all the dependent non-OSGI jar files within the one bundle.
Edit 1 - after further investigation through the axis2 / rampart code
I debugged the code side by side within OSGI and directly on JVM and noticed that the point of divergence is where axis engine while loading the "Security" handler invokes rampart and rampart goes with the default policy file instead of the mar file that was specified in "axis.repo.path". I was then looking at the loading of the policy by rampart - noticed it was not loading the configured policy but could not identify the issue.
Any insights would be appreciated.
Regards
Hari
I guess that ws-security is implemented using some kind of plugin mechanism in Axis. Probably this mechanism is not working in OSGi.
I suggest to try CXF instead. It works very well in OSGi.
Before I call service from another bundle I would like to search for this service availability because I will get NPE.
What is the proper way to search for a service?
ServiceReference serviceReference = bc.getServiceReference(someclass.class.getName());
if (serviceReference == null)
{
throw new RuntimeException("Missing service someclass, please start bundle <name>");
}
else
{
kernelsManager = (someclass) bc.getService(serviceReference);
}
I would like to shutdown the framework if the service is not found. What is the proper to to do this? Can I improve somehow the above example?
This is not as easy as that in OSGi. As the bundle containing the service could be started after the bundle using the service you should account for that dynamic. Simply checking if the service is present at a single point in time is not good enough.
You can achieve this by using a ServiceTracker. If the service is added you initialize your own class that depends on it. If it goes down you stop it. If you have more than one service dependency this is quite complicated though.
So in bigger cases better use a framework like Declarative Services or blueprint that automates this for you.
As an addition to the answer by Christian, note that shutting down the framework simply because a service is unavailable, is bad practice. OSGi is dynamic by design, meaning that services may come and go, so your bundle should be able to deal with the situation that a service is not (yet) available or disappears and re-appears. Otherwise, I really don't see the purpose of using OSGi in the first place.
I am new to osgi and have very little experience with it. I have an osgi bundle which exports a bean as osgi service using in the config xml file. I want to use that service in another osgi bundle. Can anybody tell me how to do that? I am using maven and felix osgi.
It doesn't matter how the OSGi service is exported, using blueprint or smth else - since it is an OSGi service, your bundle can get it from the OSGi service registry.
For this you must:
Import its package in your bundle manifest, in order to declare the dependency.
You have to add
Import-Package: com.acme.theservicepackage
in META-INF/Manifest.mf
in your Activator class, you have to get the service from the service registry using your bundle context:
timeRef = bc.getServiceReference(TimeService.class.getName());
if (timeRef != null) {
timeService = (TimeService) bc.getService(timeRef);
}
Then you simply use the timeService (or whatever interface your service is using) by calling its methods, whatever they are.
There are many details here, you can use the helper ServiceTracker class instead, or blueprint, or declarative services... But since you seem to be new to OSGi, I have left it as simple as possible and have shown the most basic way to do it.
There are demos here for the basic OSGi services.
Do you want to use the service with blueprint? Your description "config xml" sounds a bit like it might be blueprint. In this case you can use
I have a full example on my website:
http://www.liquid-reality.de/x/DIBZ
The example shows how to export and import a service using blueprint.
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