5 Replies Latest reply on Dec 15, 2009 3:29 PM by thomas.diesler

    No explicit control over bundle.start()

    thomas.diesler

      https://jira.jboss.org/jira/browse/JBOSGI-204

      The MC Framework incorrectly uninstalls the bundle if there is a failure in bundle.start()

      The controller context reached its required stage DESCRIBED after bundle install. A subsequent call to bundle.start() is supposed to transition to stages CLASSLOADER and then INSTALLED, which corresponds to the Bundle states RESOLVED and ACTIVE respectively.

      If the transition to INSTALLED fails, the controller context gets undeployed, which causes the bundle to transition to UNINSTALLED.

      The desired behaviour is:

      * on fail to resolve: remain in state INSTALLED
      * on fail to start: remain in state RESOLVED

      Adrian, this seems to be a fundamental problem for which neither Ales nor I could come up with a solution. Could you perhaps have a look at this issue.

      It is also related to PROPERTY_AUTO_START and the DeployerWrapper

        • 1. Re: No explicit control over bundle.start()
          alesj

           

          "thomas.diesler@jboss.com" wrote:

          The MC Framework incorrectly uninstalls the bundle if there is a failure in bundle.start()

          No, that is / should be the right behavior, as you don't wanna have broken service stuck in some middle state.

          The is a notion of ErrorHandler in Controller, which might be useful,
          if we decide to go down this path.

          Imho, the real problem is how we handle this Bundle::start.

          "thomas.diesler@jboss.com" wrote:

          The controller context reached its required stage DESCRIBED after bundle install. A subsequent call to bundle.start() is supposed to transition to stages CLASSLOADER and then INSTALLED, which corresponds to the Bundle states RESOLVED and ACTIVE respectively.

          Bundle::start should only be called after we're past CLASSLOADER stage.
          At least in automated mode. If the user wants to do this before, it's his choice and potential fault.

          "thomas.diesler@jboss.com" wrote:

          Adrian, this seems to be a fundamental problem for which neither Ales nor I could come up with a solution. Could you perhaps have a look at this issue.

          Actually I solved it in some hackish way.
          Afair, my problem was that I didn't know how to resolve cyclic bundles,
          but that's actually Controller's resolve problem as it doesn't know how to resolve cyclic dependencies in the same state.

          But yeah, I'm all for it that Adrian gets a stab at this problem. :-)
          * Bundle:start issue
          * cyclic bundle dependencies
          * resolve algorithm performance issue (EmanuelM has a good example of this)


          • 2. Re: No explicit control over bundle.start()
            thomas.diesler

             


            No, that is / should be the right behavior, as you don't wanna have broken service stuck in some middle state.


            It is legal to have a temporary error in the BundleActivator, for example because of an invalid service lookup. The same call might succeed at some later time.


            Bundle::start should only be called after we're past CLASSLOADER stage.
            At least in automated mode. If the user wants to do this before, it's his choice and potential fault.


            There is explicit control over the transition from INSTALLED to RESOLVED via PackageAdmin. Also, a bundle that provides an export package transitions to RESOLVED when the importing bundle gets started.


            • 3. Re: No explicit control over bundle.start()

               

              "alesj" wrote:
              "thomas.diesler@jboss.com" wrote:

              The MC Framework incorrectly uninstalls the bundle if there is a failure in bundle.start()

              No, that is / should be the right behavior, as you don't wanna have broken service stuck in some middle state.

              The is a notion of ErrorHandler in Controller, which might be useful,
              if we decide to go down this path.


              That is the correct way to handle it. As we discussed when designing the
              ErrorHandler, the default behaviour is to assume an error during the lifecycle
              is fatal. We don't know whether the object that threw the exception
              is still in a consistent state, so we throw it away.

              This rule comes from the EJB spec and it is a very safe assumption.

              The OSGi spec takes a different (and probably incorrect :-) view.


              Imho, the real problem is how we handle this Bundle::start.

              "thomas.diesler@jboss.com" wrote:

              The controller context reached its required stage DESCRIBED after bundle install. A subsequent call to bundle.start() is supposed to transition to stages CLASSLOADER and then INSTALLED, which corresponds to the Bundle states RESOLVED and ACTIVE respectively.

              Bundle::start should only be called after we're past CLASSLOADER stage.
              At least in automated mode. If the user wants to do this before, it's his choice and potential fault.


              No bundle.start() is no different to

              change(deploymentContext, ControllerState.INSTALLED);

              If the deployment was only in the DESCRIBE state, it should transistion through
              all the intermediate states.
              Of course, it might not be able to do it if there are missing classloading dependencies
              meaning the bundle cannot be resolved.

              So the solution is to add an ErrorHandler to the DeploymentControllerContext
              if it is an OSGi deployment, although I'd prefer it if this was an api on the
              DeploymentUnit using DeploymentStages rather than working against the
              implementation details.

              • 4. Re: No explicit control over bundle.start()
                thomas.diesler

                 


                The OSGi spec takes a different (and probably incorrect :-) view.


                I disagree. A bundle that is INSTALLED has no classloader nor bundle context associated with it. You can use PackageAdmin for an attempt to resolve that bundle. If that fails, the bundle is still INSTALLED. If that succeeds the bundle is RESOLVED, you can then use bundle.start() to start the bundle (i.e. call BundleActivator). If that fails the bundle is still RESOLVED. In no case does the bundle get uninstalled if a transition to the RESOLVED or ACTIVE state fails.


                So the solution is to add an ErrorHandler to the DeploymentControllerContext if it is an OSGi deployment,


                Ok, here is the issue

                https://jira.jboss.org/jira/browse/JBDEPLOY-225

                • 5. Re: No explicit control over bundle.start()
                  thomas.diesler

                  This can be handled in the OSGi layer like this

                   

                  public class OSGiBundleActivatorDeployer extends AbstractSimpleRealDeployer<OSGiBundleState>
                  {
                     @Override
                     public void deploy(DeploymentUnit unit, OSGiBundleState bundleState) throws DeploymentException
                     {
                        try
                        {
                           bundleState.startInternal();
                        }
                        catch (BundleException ex)
                        {
                           // We do not rethrow this exception to the deployer framework.
                           // An exception during Bundle.start() is regarded as a normal deployemtn condition and handeled internally by the OSGi layer.
                           // The OSGiBundleManager picks up this BundleException and rethrows it if available.
                           unit.addAttachment(BundleException.class, ex);
                        }
                     }
                  }