When is an OSGi fragment attached to host?
Asked Answered
P

2

14

I have an OSGi bundle with persistence service (using hibernate) and a fragment, which contains configuration (xml file). In bundle's activator, I'm loading the configuration using:

@Override
public void start(BundleContext ctx) {
   URL url = ctx.getBundle().getResource("hibernate.cfg.xml");
   SessionFactory sessionFactory = new AnnotationConfiguration().configure(url).buildSessionFactory();
}

but sometimes, the URL is null. When I've tried to list all available URLs (using findEntries method), it appeared that the bundle's own ones are available always, but the fragment ones only sometimes. I'm using Felix 4.0.2, the bundle and the fragment is started at the same Felix. auto.start level.

Pozzuoli answered 14/6, 2012 at 8:55 Comment(0)
D
23

Fragments attach to the host at the time that the host is resolved. Normally the fragment will be attached so long as it is installed before the host resolves.

However there is always the possibility for the host to resolve without the fragment, because hosts do not depend on their fragments. Therefore ordinarily you should write your host so that it can cope with the fragment not being present -- i.e. it should not throw NPEs etc.

Since OSGi R4.3 you can introduce a dependency from the host onto its fragment using the Require-Capability and Provide-Capability headers. By inventing your own namespace for the dependency you can make your fragment provide it with Provide-Capability. Then your host can require it with Require-Capability.... now the OSGi framework will ensure that the fragment must be available before it resolves the host.

Dinghy answered 14/6, 2012 at 12:47 Comment(2)
That's handy. I have never actually seen that usecase fail (we use Equinox), but I didn't realize it could fail to resolve the fragment 'in time'. Good to know.Terchie
I wish StackOverflow let me subscribe to users just so I could read everything Neil posts. :-) I learn something new almost every time he answers!Mchenry
S
0

The fragment is attached to the host during the resolving process of the fragment bundle. The host is resolved and can start successfully even if the fragment is not there; but the fragment is dependent on the host - it can be resolved and afterwards started only after it is attached to the host.

By having both bundles with the same start level, it seems that you have created race conditions for these two bundles. The framework starts resolving and starting both bundles at the same time. Sometimes it manages to start the host bundle before the resolving process of the fragment has been finished -> then the start method of the host bundle behaves as if no fragment is available.

What you can do is e.g. to give the fragment an earlier start level than that of the host bundle. The fragment should resolve and start successfully even if the host bundle is not started yet. It only needs the host bundle to be resolved.

You can also test this behavior on other OSGi frameworks - e.g. on ProSyst's mBedded Server (mBS) - I know that it is fully compliant with OSGI spec 4.2 where the above fragment resolving is specified.

Shorn answered 14/6, 2012 at 9:40 Comment(2)
Thank you for clarification! Unfortunately, it's not working. I've set the felix.auto.start level for fragment to be lower than for the bundle itself. I've double checked this in gogo console - the bundle has higher level than the fragment. I feel like the start level doesn't guarantee that the bundle/fragment with lower level will finish its resolution before going to higher start level.Pozzuoli
This is incorrect. First, the fragment attaches at the time that the host is resolved. Second, the framework does not resolve and start at the same time. In fact, starting has no impact whatsoever on the resolution, and fragments cannot be started anyway.Dinghy

© 2022 - 2024 — McMap. All rights reserved.