Can I still use a service instance after ungetting it? - osgi

Is this a valid operation to do?
final IOSGiService service = (IOSGiService) bundleContext.getService(reference);
bundleContext.ungetService(reference);
service.executeSomeOperaton();
Will I be able to run the method executeSomeOperaton() safely every time?

You will have the object and you will be able to call functions on it. However, you cannot be sure that the object is still in the right state. What if the provider of the Service closes some resource that is necessary for that function work well?
You should not use services in this way. You cannot even be sure that the service is in the right state when you call the function on it even if you have not called unget(). You should use a technology like Felix Felix SCR. In that case your object will be deactivated if the reference is not available anymore, or if you specified reference to be dynamic, an unbind method will be called on your object. From that, you will know when the service is truly available.
Alternatives to use: Apache Felix iPojo, Apache Aries Blueprint or use a ServiceTracker to catch the events of the service that you use.
Update:
So in other words ungetting a service or not will do no difference at all, unless I really want to keep the service usage counter correct right?
There are cases where ungetting the service really matters. For example, if the Provider registered a ServiceFactory instead of the service object itself, it is possible to catch the unget event on the Provider side. In that case, resources might be freed as soon as the unget is called on the service.
As much as I remember all service references of the consumer bundle are retrieved (unget is called) when the consumer bundle is stopped (but I am not sure).

Related

Create A Service And Allow Only One Bundle To Hold That Service At any Time

I'm trying to create a service such that once it is created it only allows itself to be held by a single consumer/bundle at any one time. (If this is against the philosophy/specification of OSGi then that obviously provides a quick answer but reference to the OSGi specs. stating this would be appreciated.)
To implement such a requirement I implemented the ServiceFactory interface thinking that whenever there was a requirement for the service the getService(Bundle bundle, ServiceRegistration<S> registration) method would be called and it would be where I could determine if the Bundle was a new consumer or not and act accordingly.
It appears that this is not the case in the scenario I have tested this in.
Using a Apache Karaf and instantiating a consumer of the Service via Blueprint it would seem that the getService method is never called. Instead the consumer's binding method for the service is called directly but injecting a proxy service object.
While I understand that Blueprint uses proxies surely there is still the obligation of the ServiceFactory contract to fulfil even if it's a proxy object consuming the service?
Why do I want to do this?
I am attempting to wrap JavaFX and the Stage class and because JavaFX isn't OSGi friendly I am attempting to co-ordinate access to the Stage object. I'm aware that there are frameworks such as Drombler but a brief look at them made me think that it doesn't suit my use case. They appear too restrictive for my needs e.g. I don't necessarily wish to layout an application in the manner Drombler uses.
It depends what you mean by a consumer. ServiceFactory does give you the chance to create a separate instance of a service per bundle that calls getService on your service. It's not clear from your question but I suspect you weren't seeing the getService invoked multiple times because you were fetching the service from the same consumer bundle. In this case, ServiceFactory simply returns the same object repeatedly.
As for your general question about restricting access to a single consumer, no that really goes against the OSGi philosophy. I'm sorry I don't have a spec reference for you but the clue is in the name: it's a service that is available to all.
I'm aware that there are frameworks such as Drombler but a brief look at them made me think that it doesn't suit my use case. They appear too restrictive for my needs e.g. I don't necessarily wish to layout an application in the manner Drombler uses.
Please note that the layout of Drombler FX applications is pluggable so you can provide your own implementation tailored to your needs. This allows you to get the most out of Drombler FX and JavaFX.
While this feature is available for some time, there is now a new tutorial trail explaining it in more detail.

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

Single instance of an object per transaction

I have a use case, that theoretically seems to me as it would be a solved problem. But i'm not able to find a sure fired implementation.
I've created a RESTful API, using Apache CXF, Spring and Hibernate
This application encompasses a standard Service-Proxy-DAO layered structure
I need to instantiate a custom logger object at my service (or pre-service) layer and initialize a bunch of parameters which will remain constant, for the most part through every call that goes through my application layers and back.
How can i, for every individual service call, initialize this logger object once, and use it across all my layers without having to instantiate it everytime. Either i inject the initialized object in every class i need or something on those lines.
I don't want to use static blocks, or pass the object in method signatures.
Is there anything that i can use as a part of the Spring, CXF or other java framework that allows me to implement this use-case.
EDIT: I would define a transaction as a single call to a web service endpoint, from invocation to response.
ThreadLocal would be an ideal candidate to solve your problem.
UPDATE:
Creating a thread local that is available in all the places where this "shared" reference is required will give all these contexts access to this resource without having to pass the reference around.
see http://www.appneta.com/blog/introduction-to-javas-threadlocal-storage/ - looks like a good explanation of how to use thread local and also deals with your problem space.

OSGI Service reference

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.

OSGI bundle (or service)- how to register for a given time period?

Search did not give me a hint, how can i behave with the following situation:
I'd love to have 2 OSGI implementations of the same interface: one is regular, the other should work (be active/present/whatever) on the given time period (f.e for Christmas weeks :))
The main goal is to call the same interface without specifying any flags/properties/without manual switching of ranking. Application should somehow switch implementation for this special period, doing another/regular job before and after :)
I'm a newbie, maybe i do not completely understand OSGI concept somewhere, sorry for that of give me a hint or link, sorry for my English.
Using Felix/Equinox with Apache Aries.
The publisher of a service can register and unregister that service whenever it likes using the normal API. If it chooses then it can do so according to some regular schedule.
If there is another service instance that is available continuously, then the consumer of the service will sometimes see two instances of the service and sometimes see one. When there is only one instance available then it is trivial to get only that instance. When there are two instances then you need a way to ensure you get your "preferred" instance. The SERVICE_RANKING property is a way to do this. The getService method of a normal ServiceTracker will always return the higher ranked service, so this would appear to satisfy your requirement.
I have yet to see an OSGI container that at a framework level supports date/time based availability of services.
If I were you I would simply drop a proxy service in front of the two interface implementations and put the service invocation based on date logic in there.
I don't believe there is any framework support for what you are asking for.
If you are intent on avoiding service filters, you might try this.
Implement a PolicyService. This service is in charge of deciding which instance of your service should be registered at a given point in time. When its time for the policy service to switch implementations, it just uses the register/unregister apis as usual. You policy service implementation can read in a config file that specifies the date range to service implementation mapping. This will allow you to add new behavior by modifying your config file and installing a new bundle with the new service.
I agree with Neil that a service should only publish itself if it can actually be invoked. My solution to this problem would be to have all service producers be dependent on a "time constraint dependency". Whilst such a dependency is not available in the standard dependency frameworks (like Declarative Services, Blueprint, iPOJO) it is easily implemented with the Apache Felix Dependency Manager, which allows you to create your own types of dependencies. Note that writing such a new dependency once is some work, but if this is a core piece of your application I think it's worth it. Service consumers would not require any special logic, they would simply invoke the service that was there.
Ok, what i have finally done...
Implemented a common dispatcher bundle - and call any of services only thru it (therefore cron is not needed, when call is on-demand)
When dispatcher obtains request - it searches for interface in its own cache and -
When there are >1 service with the same ranking and both are equal (registered) - then
Dispatcher resolves needed service via own written #TimigPolicy annotation with "from" and "to" fields
For the given server new datetime() - dispatcher returns proper service instance
Much work, i should say :) But works nearly perfect :)
Thanks everybody for giving me hints, it was really helpful!!!

Resources