OSGi : Are bundles/jars cached? - osgi

I was always wondering: When I install a jar in OSGi, for example with "install file:///xyz" or with "install http://xyz.org/my.jar" - does OSGi only store a reference? Or does it copy the file to some sort of local repository?
I am especially interested what happens for remote resources (like "install http://...").
cheers,
T.

Yes, they are cached. From http://felix.apache.org/site/apache-felix-framework-bundle-cache.html:
The OSGi specification states that the framework must cache bundles
and their run-time state, but it does not explicitly define how this
should be done. As a result, each OSGi framework implementation is
likely to cache bundles differently.

Related

Runtime flexibility of OSGi

To get started with OSGi, thought of asking this since this become unclear to me.
If you have runtime code change as a requirement, OSGi is probably the only possible way to achieve this using Java.
from https://mondula.com/2016/01/11/osgi-benefits-and-drawbacks/
How the runtime flexibility is maintained in OSGi technically?
This is a large question that would be impractical to fully answer here. The following is a simplified overview.
OSGi allocates a Java ClassLoader for each resolved bundle. When a bundle is updated, OSGi first sends a stop signal to the bundle, allowing it to release resources and prepare to be garbage collected.
The new bundle is then re-resolved against its requirements, which may have changed compared to the previous version. Assuming the new version still resolves (i.e. its requirements are still satisfied) then OSGi allocates a new ClassLoader, uses that to load the classes in the bundle, and if the bundle has an activator and was in ACTIVE state before the update, sends a start signal to the newly loaded activator.

In the OSGi eco-system landscape is there any mean to automatically upgrade the OSGi Container himself?

Maybe this question seems odd ?
I am working on OSGi-fication of our software based on Agents collecting some informations on servers.
Concerning Bundles update, it's natively supported by OSGi frameworks (OBR, Apache ACE, ...)
But, concerning the OSGI Container itself (Felix, Karaf, ...), is there a mechanism or a framework/tool having capacity to upgrade the container "automatically"?
Any idea? Any feedback?
Not in the OSGi specification. It assumes the framework is available on the classpath and can be launched. Any ability to update the framework implementation would be specific to a framework implementation as a value add.

OSGI bundles and multiple jvms

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://....

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.

What is the natural start order for package-dependent OSGI bundles (under Karaf)?

I have a problem on 2.2.8 version of Karaf (and most probably on the earlier versions too).
I'm going to use Karaf to host the system with dynamically deployed bundles. Bundles are deployed by users and i cannot know beforehand which are they.
I expect order of the BundleActivator.start() to exactly correspond to package dependencies between bundles (dependencies of import/export packages) and planning to expect that it will be safe to assume that bundle0 will be completely initialized before bundle1 is going to be started. But it is not so - it seems that BundleActivator.start() is invoked in a "random" order and disregards package dependencies between bundles.
Sample use-case, I have 3 libs
test-lib0 - defines testlib0.ITestRoot, exports testlib0 package
test-lib1 - defines testlib1.TestRoot implements ITestRoot, exports testlib1 package
test-lib2 - uses both libs, ITestRoot and TestRoot
When Karaf is started, i see following sample output in console
karaf#root> TestLib1Activator.start()
TestLib2Activator.start()
ITestRoot: interface com.testorg.testlib0.ITestRoot - 16634462
TestRoot: class com.testorg.testlib1.TestRoot - 21576551
TestLib0Activator.start()
but i expect it should be always in this order
TestLib0Activator.start()
TestLib1Activator.start()
TestLib2Activator.start()
ITestRoot: interface com.testorg.testlib0.ITestRoot - 16634462
TestRoot: class com.testorg.testlib1.TestRoot - 21576551
I'm attaching sample project for tests. Test case: after "mvn install" just move jars from ./deploy folder to the same folder of Karaf, trace messages should appear in console.
(Note: it may work correctly from the first attempt, try one more time then :))
Sample test project
http://karaf.922171.n3.nabble.com/file/n4025256/KarafTest.zip
Note: this is cross-post from http://karaf.922171.n3.nabble.com/What-is-the-natural-start-order-for-dependent-bundle-td4025256.html
In OSGi the bundle lifecycle is installed → resolved → starting → started.
Import-Package and Export-Package only influence when the bundle goes from installed to resolved. So the framework makes sure all bundles you import packages from are resolved before your bundle but then your bundle only goes to the resolved state. Then in a second step the activators are called. So you can not assume the activators are called in the same order. If you need some initializations before your testlib2 can work then you should use OSGi services.
So If I understood your case correctly then you testlib0 defines an interface, testlib1 implements it and testlib2 wants to use the implementation. So the best way to achieve this is to publish the impl as an OSGi service in testlib1 and reference this service in testlib3. You can then use the service with a ServiceTracker or with e.g. blueprint. I have a small example that shows this: http://www.liquid-reality.de/x/DIBZ . So if you do your case like in my example blueprint makes sure that the context of testlib2 only gets started when the service is there. It will even stop testlib2 when the service goes away.

Resources