[jboss-dev-forums] [JBoss OSGi Development] - Re: Autostart bundles when deployed in JBossAS

thomas.diesler@jboss.com do-not-reply at jboss.com
Fri Sep 4 06:03:10 EDT 2009


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/trunk/igloo/src/main/java/org/jboss/demos/bootstrap/igloo/deployers/

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/runtime/microcontainer/trunk/src/main/java/org/jboss/osgi/plugins/deployers/bundle/OSGiBundleResolverDeployer.java


  |    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



More information about the jboss-dev-forums mailing list