OSGI bundles and multiple jvms - osgi

osgi (equinox 3.6) framework while loading bundle creates bundle meta files in specified bundle directory . we are working on spawning multiple jvm's . Can we use bundle folder where my previous jvm has created ? I meant can we install all bundles once and use them for many applications?

It's a bit difficult to work out what you're asking... but it sounds like you want to share the OSGi storage directory between multiple separate OSGi frameworks running in different JVMs. This is not possible.

a) Yes you can share the same location URL among frameworks
b) You cannot share the framework bundle storage area/bundle cache (org.osgi.framework.storage property)
You know there is a special reference: schema for OSGi frameworks? This allows you to install frameworks quicker. Just prefix a URL with reference: scheme.
reference:file://....

Related

How to use dependent bundles in different container in Fabri8?

I am trying to understand the capabilities of Fabric8's container management.
I just want to clarify weather the following scenario can be achieved by using Fabric8 in JBossFuse.
I have created simple 2 bundles (tick, tock bundles inspired by the : http://kevinboone.net/osgitest.html).
Simply Tick bundle is exporting a package and Tock bundle is importing it. In another words, Tock Bundle depends on the Tick Bundle.
These 2 bundles are working perfectly when deployed in a single container (say in a one child container in JBoossFuse).
Then I have created a cluster by using the fabric8 and added its containers to the Fabric Ensemble as well.
And I have created 2 profiles. TickProfile contains the Tick bundle and Tock profile contains the Tock bundle.
I have deployed above 2 profiles in 2 different containers as follows,
Then it is not working properly because Tock bundle cannot resolve its dependency of Tick Bundle which is exposed by Tick Bundle (because those bundles are in two different containers).
I thought this is possible with fabric8 but it seems it cannot.
It would be really appreciated if someone can tell me whether there is any way of achieving this.
Thanks.
No this is not possible. Package export and import on OSGi level is bounded to the JVM. This means bundles in different JVMs will not be able to import each others classes.
The only OSGi concept that supports clustering are Services. The OSGi specification calls that Remote Services.
See: https://wiki.eclipse.org/Tutorial:_Building_your_first_OSGi_Remote_Service
Eclipse implementation: https://wiki.eclipse.org/OSGi_Remote_Services_and_ECF
Apache implementation: http://cxf.apache.org/distributed-osgi.html

How to share resources of a OSGI bundle to other bundles

How can resource of a bundle be shared with other bundle(but not just one)?
For example I don't want to duplicate the images or properties file to all bundles, instead I want to access them from a single place.
I tried to use Fragment-Host, but there is not possible to specify multiple bundles(at least I do not know how)
eg:
<!-rest of the pom-->
<instructions>
<Fragment-Host>
com.bundlehost
</Fragment-Host>
</instructions>
As Dmytro notes, you can use OSGi API methods to access the resources in any bundle. However the harder question is this: how do you know from which bundle to access these resources, and how do you know where they are located within the bundle?
If you just make assumptions or hard-code the answer, then you end up with a very brittle system and a hidden coupling between the bundles. Then when somebody deploys your bundles into an application but doesn't include the resource bundle, everything breaks. This defeats the point of modularity.
You can use Bundle.getEntryPaths() and Bundle.getEntry() to get bundle resources. To read content use URL.openStream()
You can also use normal package imports and exports to ensure the resources are on the class path of the consuming bundle. See, for example, access common property file inside bundle with osgi.

Does Apache Felix FileInstall works for dynamic configuration of an application?

I am trying to develop an application that can be configured by its users. I need the configuration to be done by installing/updating/stopping/uninstalling bundles. All this should be of course done dynamically during the run-time of the application.
I found a nice framework which is Apache Felix FileInstall that provides a directory in which it seems to add a bundle when you add the bundle file in the directory (update, and remove bundles similarly).
But I can see that this method does not work in my case. I need to have the bundles in the directory but to stop or even uninstall them by my application. And I want to install them when it is appropriate. This is how I am expecting the configuration of my application to be done.
Is what I am trying to achieve supported by Apache FileInstall? Am I making any wrong assumptions about this framework? What are other possible ways that would help me if Apache FileInstall is not enough? Thanks.
You don't need FileInstall for this, just use the OSGi APIs. You specifically mentioned installing, updating, stopping and uninstalling; these are supported with the following API calls respectively:
BundleContext.installBundle
Bundle.update
Bundle.stop
Bundle.uninstall
Incidentally these are exactly the same methods that are called by FileInstall to implements its directory-based bundle management.

Restlet converter registration in OSGI environment

We run Restlet 2.1 in an OSGi environment (Equinox) as bundle (ie. not as library within a bundle). The problem is that the Restlet Engine does not detect helpers (like converters) that are provided by Restlet extensions. Specifically, the EngineClassLoader#getResources() call does not return any result. The extensions are also deployed as OSGi bundles in the target platform.
Is automatic converter registration actually supposed to work within OSGi environments?
In fact, Restlet supports such feature thanks to a dedicated activator (see the Activator class in the package org.restlet.engine.internal).
This activator introspects bundles to find out the following things:
servers corresponding to registered servers
servers corresponding to registered clients
authenticators corresponding to registered clients
converters
Be aware that to use this feature, we must use the OSGi edition of Restlet since it's the only that has the MANIFEST file of the org.restlet bundle with the activator class specified. Otherwise you don't have to care about the bundle loading order...
Hope it helps you.
Thierry
Unless the Restlet-bundle explicitly imports the packages that contain the extensions (and I doubt it does, and it shouldn't), it wouldn't be able to load them, because bundles have isolated class-spaces.
A possible solution would be to provide the extensions as fragments attached to the Restlet-bundle. Thus, if you make it use the bundle-classloader (the documentation says this can be done by setting the Engines classloader), it would be able to load classes from the fragments.
Indeed it doesn't quite work for OSGi, as it depends on the ability to see the entire class space.
The way to do this in OSGi would be to use the service registry for the extensions, but that only works for OSGi aware libraries.
There is some help on the way: In the recently released OSGi 5 (Service Loader Mediator) there will be support to 'bridge' META-INF/services (I don't know if Restlet uses those, though) onto OSGi services, so 'legacy' libraries should work well within OSGi.
There is an implementation in Apache Aries called Spi-Fly. I looked at it briefly a while back. It might do the trick for you, it might not.

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