The way it works is that BundleInstallProcessor installs the Bundle
through the BundleManager
serviceName = bundleManager.installBundle(deployment, null);
This actually installs the HostBundleInstalledService and returns its
service name. The actual Bundle install happens in the service async.
Then we create a dependency on that service to the next phase
phaseContext.addDeploymentDependency(serviceName,
OSGiConstants.INSTALLED_BUNDLE_KEY);
So it is guaranteed that the HostBundleInstalledService has done its
work (i.e. install the bundle into the framework) when the next
deployment phase is executed. So any DUP after the REGISTER phase can
pick up the bundle from the DU under that attachment key. The bundle
service names for RESOLVED & ACTIVE can be derived from the INSTALLED
service name. I agree there is currently no obvious/good API to work
with Bundle services (I'll fix that). You would do it like this
XBundle bundle =
depUnit.getAttachment(OSGiConstants.INSTALLED_BUNDLE_KEY);
ServiceName installedName = bundle.adapt(ServiceName.class);
ServiceName resolvedName = installedName.getParent().append("RESOLVED")
The BundleResolveProcessor should create a similar dependency to the
next phase for the RESOLVED service (I made a note of that). We
currently do this
resolver.resolveAndApply(context);
depUnit.putAttachment(Attachments.BUNDLE_STATE_KEY,
BundleState.RESOLVED);
ModuleIdentifier identifier = brev.getModuleIdentifier();
ServiceName moduleService =
ServiceModuleLoader.moduleServiceName(identifier);
phaseContext.addDeploymentDependency(moduleService,
Attachments.MODULE);
It'd be wrong to assume that the ClassLoader is available after
resolveAndApply returns. The RESOLVE service has a dependency on the
MODULE service. As you can see, this will only be available in the next
phase.
The INSTALL deployment phase (terrible confusion between DU phases,
Bundle states and Bundle services) contains the BundleActivateProcessor,
which does this
bundle.start(options);
depUnit.putAttachment(Attachments.BUNDLE_STATE_KEY, BundleState.ACTIVE);
When you create a dependency on the bundle ACTIVE service you have a
guarantee that the BundleContext is available. You cannot assume that
this will happen during DU processing. There are several ways to disable
DU bundle resolution/activation. The only guarantee that you have on the
BundleContext being available is via the bundle ACTIVE service or if you
register a LifecycleInterceptor with the framework, which we have
actually done in jboss-as-osgi-web.
I'd say your friend is the WebContextLifecycleInterceptor. You can pass
stuff from a DUP to that LifecycleInterceptor and you have the
BundleContext when it gets invoked for the state change to ACTIVE.
Not sure if this applies here, but generally your code must work for
XBundle instances that are directly registered with the XEnvironment.
These are plain modules adapted to bundles. Currently, their start/stop
operations do nothing and they have no state changes managed by the
framework. So you should be safe - LifecycleInterceptors don't see them.
cheers
-thomas
On 07/18/2012 05:47 PM, David Bosschaert wrote:
If I understand it correctly, the HostBundleActiveService contains
the
bundle ID as the service name, like this:
jbosgi.bundle.3."osgi.enterprise"."4.2.0.201003190513".ACTIVE
I can get the symbolic name and version from the BundleInfo
attachment, but the bundle ID is not yet available as the bundle
doesn't exist yet. So I guess I can't simply use MSC dependencies to
depend on this service?
Should I create an MSC service listener and match the name instead?
Cheers,
David
On 18/07/2012 13:26, Thomas Diesler wrote:
> Your WebContextFactory would become a service that your DUP installs.
>
> On 07/18/2012 02:24 PM, Thomas Diesler wrote:
>> Yes, this could work. However it's probably better to use a
>> dependency on the HostBundleActiveService.
>> Generally, services that have a dependency on a particular bundle
>> state should do this via ordinary service dependencies rather via
>> async listeners on bundle events. So you would have a
>> BundleContextInjection service with an injected bundle dependency on
>> the HostBundleActiveService.
>>
>> cheers
>> -thomas
>>
>>
>> On 07/18/2012 01:56 PM, David Bosschaert wrote:
>>> Hi all,
>>>
>>> I began completing the OSGi WAB support that Thomas started some time
>>> ago. The first piece I looked at is AS7-5203 which gives Servlets
>>> access
>>> to the OSGi BundleContext via the ServletContext.
>>>
>>> Before filing a pull I'm looking for some feedback on how I
>>> implemented
>>> this. Maybe people have thoughts re how it can be improved or
>>> simplified. It currently works like this:
>>> * I added a DeploymentUnitProcessor in the REGISTER phase that adds a
>>> WebContextFactory.ATTACHMENT to the deployment unit.
>>> * This attachment is picked up by JBoss Web (it already provided
>>> this hook).
>>> * When the Bundle representing the WAB is started it calls back into
>>> the
>>> WebContextFactory to set the BundleContext in the ServletContext. It
>>> does this via a MSC Service that in turn uses an OSGi BundleListener.
>>>
>>> The changes are here:
>>>
https://github.com/bosschaert/jboss-as/commit/9ab72ce08a3357a3e6fdb1a68c2...
>>>
>>>
>>>
>>> Thanks,
>>>
>>> David
>>>
>>> _______________________________________________
>>> jboss-osgi-dev mailing list
>>> jboss-osgi-dev(a)lists.jboss.org
>>>
https://lists.jboss.org/mailman/listinfo/jboss-osgi-dev
>>
>
--
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Thomas Diesler
JBoss OSGi Lead
JBoss, a division of Red Hat
xxxxxxxxxxxxxxxxxxxxxxxxxxxx