osgi multiple versions of service - jboss

i have osgi services service-1.0.0.jar and service-1.1.0.jar they are implementation of service-api-1.0.0.jar
both these service-1.0.0.jar and service-1.1.0.jar have same service name and packages.
service are registered by bundle-activator
lets assume bundle activator is com.abc.xyz.MyActivator - 1.0.0 and 1.1.0
issue I am facing is when I deploy these services and lookup using service tracker and filter on version I want, I always get same implementation regardless of what version chosen.
this makes me believe that what i am trying to achieve is not doable.
I need multiple implementation of service packaged in separate bundles with difference of version and be able to choose dynamically at runtime.
I am trying this in jboss-6.1.1 eap
if i keep different package name in versions looks like it is able to understand that these are 2 different services but when package names are same i get same service implementation.
am i doing something wrong? has anybody tried this?
is it correct that OSGI allow you to deploy multiple versions of service?
UPDATE After using unique package names for MyActivator in 1.0.0 and 1.1.0 looks like the services are able to maintain the uniqueness.
Does that mean Activators has to unique across bundles?

I assume that service-api-1.0.0.jar exports the package which defines the service interface. In that case, it sounds like you have two implementations of the same version of the service. Not different implementations of different versions of the service. So from a service user point of view, the services are that same: they are from the same service api package version.

I think you are using the OSGi services in a strange way. As a client you should not look into the implemention bundles to determine versions or other informations.
Instead you should use the service interface and service properties to distinguish between services.
So for example you can have a property version and publish the first service with version=1 and the second with version=2. Then you can filter for this property to get a specific service.
Using reflection is also a rather unusual thing. Better try to provide classes in the interface package that you use to exchange data between client and service. This will make the client less dependent on the service impl.

If you have multiple implementations of the same service API, and a client queries for an implementation of the service API, it could get any of the implementations. And that's good because the client shouldn't care.
Say for example you have a Greeting interface with multiple implementations registered as services, possibly by multiple bundles. If a client asks OSGi for a Greeting service then OSGi will simply pick one. After all, if you just ask for a Greeting without specifying anything else then you should accept any implementation. Clients certainly shouldn't care which particular bundle the service comes from: this is the nature of decoupling.
Incidentally, when this happens OSGi normally chooses the implementation that was registered first (actually the one with the lowest service.id, which is an ever-incrementing number, so it's effectively the same thing). This is probably why you see OSGi consistently choosing one particular service.
If your client needs to distinguish between service implementations then you can add properties to the published services and filter on those services. For example one bundle could publish a Greeting service with property language=en_US (i.e. US English) and another could publish a Greeting service with language=de. If your client only wants greetings in English then it can use a filter like (language=en*).

Related

Service Fabric: Plugins vs. Application Types

I'm developing a Service Fabric-based trading platform that will host hundreds of different long-running trading algorithms, all of which conform to a common interface and share a good deal of common code but can be vastly different in their internal specifics. I could model each of the different algos as an application type (which I'd dynamically load) but given the large number of different algos I have to wonder if in makes more sense to create a single Plugin Runner application type then implement the algos as plugins.
In a related question, I understand how to implement a plugin architecture, in general, but I'm not quite sure where one would place the actual plugins in order to be discoverable by an instance running on Service Fabric.
Anyway, thanks for your help....
Both approaches can work I think. Using lots of Application Types adds the (significant) overhead of running lots of processes, but allows you to use and upgrade multiple versions of the same algorithm running simultaneously.
Using the plugin approach requires you to deal with versioning yourself.
Using the Application approach probably requires some kind of request router, while the
plugin service could make it's own decisions (if it's stateless).
You can create a Stateful service that acts as the plugin repository, or mount a file share, or use a database, no restrictions from the platform here. You can use naming conventions to locate the proper plugin.
The following approach could work if an application upgrade is acceptable to you when changing the set of plugins needed for a given application instance.
Recall that Service Fabric apps must be packaged before deployment or upgrade. Using either msbuild tasks or Powershell, you could copy your plugin dlls to the plugin runner service's code package as a post-packaging step prior to the app upgrade. Then your plugin dlls would be available to the service at startup using Assembly.Load and the code package's path, available in your service implementation's Context.CodePackageActivationContext.GetCodePackageObject("Your-Code-Package-Name").Path property. The code package's name is defined in ServiceManifest.xml, and is named Code by default.

Can two version of resteasy & jetty be loaded in same JVM

I have a very typical problem. I am using in-house developed platform which uses Jetty server and rest easy to provide a wrapper over REST framework. When they did that they made lot of tweaks for some specific scenes.
Now problem is that when I developed a REST based service with raw interfaces of rest easy and embed my jetty server in same JVM. My service can receive the request but response is always 500 server error.
I feel the in-house framework is intercepting the response doing some security validations so my response doesn't reach.
I was wondering if there is a way to use the different rest easy version and run in same JVM. I have tried to embed a jetty server and added a normal Servlet and I can access it but I can't achieve the same with my rest based servlet.
Any Idea how could I load two versions of rest easy on same JVM ?
What you can't have is two applications in the same web application context, since you are supposed to define only one class implementing javax.ws.rs.Application.
But that shouldn't be a problem, as long as classes live in different ClassLoaders. Each web application context must be in isolation of other contexts, each defining its own ClassLoader.
You can perform all kinds of class loading manipulation in Jetty: https://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading
In conclusion, as long as you use different jar files of RESTEasy in each web context, you should be able to run two REST applications using different RESTEasy versions in the same JVM process.

How does using the javax.ws.rs-api-2.0.jar works at runtime as it is only the API

We were working on creating a RESTful service. We have thought of using frameworks like jersey or cxf. But apparently we found that just using the javax.ws.rs-api-2.0.jar and the related annotations, we can get the service working.
Question is:
How does it work? Is it dependent on the application servers?
What if we application server does not support or have the implementation of the API?
If it is dependent on application servers, can I find out the library which the server is using especially tomcat?
EDIT 1
This question is invalid. javax.ws.rs-api-2.0.jar is just an API. Using this jar does not suffice. It will not give compilation errors.
But at run-time, you need providers which will implement the rs-api. And thus we need the frameworks like jersey or cxf.
In our application, these jars were added to the war during ant-build from external location and that is why it confused us.
I am closing this question.

Is there a way to know when and in what plug-in Eclipse service is registered?

It's nice that Eclipse uses service oriented architecture more and more, but am I only the developer who sees the lack of knowledge of by what plug-in and at what stage service is registered as a problem?
Consider example:
IServiceLocator someServiceLocator = ...
SomeService someService = (SomeService)someServiceLocator.getService(SomeService.class);
// oops, someService is null
Possible reasons to why someService is null are:
Some plug-in that registers this service doesn't present or not loaded
Service wasn't registered yet
How should one resolve this? Are there any tools?
Thanks.
The short answer: there are no tools available.
For the complete list of services and where they are registered do "Call Hierarchy" on ServiceLocator.registerService(Class api, Object service).
For a good list of the available global services, look at Workbench.initializeDefaultServices(). There are some additional services that are only available at the window or workbench part level.
If you want to know what plugins are installed and started, you can use the OSGI console and see the state of the plugins.
So if you are looking for a service "XService", find the plugin which contains the service and look for the plugin state on the OSGI console.
Start you application with -console option and type ss on the osgi console. This is not straight forward but works.

OSGi : How can a Service auto discover client bundles deployed at runtime?

I have a scenario where during the system install time, a few services were deployed on to the OSGi container and these services will be listening for other bundles that provide data and are dynamically installed and uninstalled at runtime.
These data providers do not expose any services and should not even invoke services; my idea is to enable the pre-deployed services to listen for the event of installation of these data provider bundles and if the pattern matches, then process and persist the data into the data store.
For example I have a WidgetService which will listen for installation or uninstallation event of Widget data provider bundles, ShppingCartService that will listen for the installation/uninstallation events from ShoppableItem data provider bundles, etc.
This helps me to keep the processing and persisting logic be centralized and my data providers need not write any code to make their data processed. All that is expected from the data provider bundles is the Service Name/id, Service Version,PreRequisites, and the data that they need to publish.
I have read several articles on OSGi that explain dynamic pluggability of services and the clients able to discover or discard services based on their availabity; however, those are all talking about scenarios where clients are to be intelligent to discover and execute the services they are interested in.
My intention is to make client completely unaware of any service discovery, for that matter any code. All that the client passes is the info about the service the client is interseted in, the dependencies, and the data; the client should be completely dumb.
Is this possible in OSGi? I'm ready to consider this architecture even at the cost of extending a few of the OSGi core framework classes!
I have found some what, may be, remotely related question on stack overflow at :
Discovering Bundle MetaData with out installing the bundle
However, I want a hook or an event that will call my respective service when one or more data provider bundles have been installed. These data provider bundles can be interested in any of the services that are installed in the system. I'm even ready to write a central bunle repository manager/listener kind of stuff that will listen to any bundle installation and invoke my Service facade that will decide which service to execute based on the meta data provided by the data provider bundle.
I'm just starting OSGi, so need a little direction on how to move forward...
I'll be really thankful to you guys/girls :) if you can help me achieve this!
I have a doubt deep in my mind that this may not be readily available in OSGi, and even if that is true I'm ready to spend time and extend the framework to achieve this. All I need is a few guidelines and a clear direction. Who knows, if OSGi is really lacking this functionality, then it would be a very useful add-on to a future OSGi spec.
You might have a look at section 4.7 (Events) of the OSGi Core spec. The Framework raises BundleEvents when there is a change in the lifecycle of a bundle, e.g. when it is installed or uninstalled. What you need to do is to implement a BundleListener, which then will receive the events, so your service can react on the changes.
I have described a design pattern that I call "OSGi Mediator", which may be a solution to your problem.
The items you want to mediate would only require to register with the service registry; all the dependencies could be managed by your mediator implementation.