[JBoss OSGi Development] - Re: Autostart bundles when deployed in JBossAS
by thomas.diesler@jboss.com
There is an approach from Ales, which introduces a new state 'Reset' and resets the context to Described when it cannot get resolved.
http://anonsvn.jboss.org/repos/jbossas/projects/demos/microcontainer/trun...
This approach fails however for bundles with self dependencies.
I also have made an attempt which involves a LifecycleCallbackItem and uses the PackageAdmin in a seperate Thread to resolve and progress bundles
http://anonsvn.jboss.org/repos/jbossas/projects/jboss-osgi/projects/runti...
| public void deploy(DeploymentUnit unit, OSGiBundleState bundleState) throws DeploymentException
| {
| bundleState.getBundleManager();
|
| ControllerContext context = unit.getAttachment(ControllerContext.class);
| DependencyInfo di = context.getDependencyInfo();
|
| LifecycleCallbackItem lifecycleCallbackItem = new LifecycleCallback(unit);
| di.addLifecycleCallback(lifecycleCallbackItem);
| }
|
| private class LifecycleCallback implements LifecycleCallbackItem
| {
| private DeploymentUnit unit;
| private PackageAdmin packageAdmin;
| private DeployerClient deployerClient;
|
| public LifecycleCallback(DeploymentUnit unit)
| {
| this.unit = unit;
|
| OSGiBundleState bundleState = unit.getAttachment(OSGiBundleState.class);
| BundleContext sysContext = bundleState.getBundleManager().getSystemContext();
| ServiceReference sref = sysContext.getServiceReference(PackageAdmin.class.getName());
| packageAdmin = (PackageAdmin)sysContext.getService(sref);
|
| deployerClient = unit.getAttachment(MainDeployer.class);
| }
|
| public void uninstall(ControllerContext ctx)
| {
| OSGiBundleState bundleState = unit.getAttachment(OSGiBundleState.class);
| unresolvedBundles.remove(bundleState);
| }
|
| public void install(ControllerContext ctx) throws Exception
| {
| Runnable runnable = new Runnable()
| {
| public void run()
| {
| try
| {
| // [TODO] remove this hack and find a way to trigger
| // PackageAdmin after the context has been deployed
| Thread.sleep(100);
| }
| catch (InterruptedException e)
| {
| // ignore
| }
|
| OSGiBundleState bundleState = unit.getAttachment(OSGiBundleState.class);
|
| // Add the new bundle to the list of unresolved
| unresolvedBundles.add(0, bundleState);
| OSGiBundleState[] unresolved = new OSGiBundleState[unresolvedBundles.size()];
| unresolvedBundles.toArray(unresolved);
|
| // Try to resolve all unresolved bundles
| packageAdmin.resolveBundles(unresolved);
| if (bundleState.getState() != Bundle.RESOLVED)
| log.info("Unresolved: " + bundleState);
|
| for (OSGiBundleState aux : unresolved)
| {
| if (aux.getState() == Bundle.RESOLVED)
| {
| unresolvedBundles.remove(aux);
|
| try
| {
| // When resolved progress to INSTALLED
| String name = aux.getDeploymentUnit().getName();
| deployerClient.change(name, DeploymentStages.INSTALLED);
| }
| catch (DeploymentException ex)
| {
| log.error(ex);
| }
| }
| }
| }
| };
| new Thread(runnable).start();
| }
|
| public ControllerState getWhenRequired()
| {
| return new ControllerState(getStage().getName());
| }
|
| public ControllerState getDependentState()
| {
| return null;
| }
|
| public Object getBean()
| {
| return null;
| }
| }
|
The separate Thread was necessary because the context is still installing when the PackageAdmin tries to progress to stage CLASSLOADER.
Conceptually, there are two passes needed for bundle deployment.
Phase #1: Install bundles (reqstage == DESCRIBE )
Phase #2: Resolve & Start bundles (reqstage == INSTALLED)
Perhaps a callback for when the Phase #1 is needed or is there any other way to get rid of that Thread that starts Phase #2?
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4253529#4253529
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4253529
15 years, 3 months