5 Replies Latest reply on Mar 20, 2009 11:03 AM by Ales Justin

    How to install a bean without affecting unrelated bean's sta

    jaikiran pai Master

      Consider this case:

      1) You have a MC bean (named Bean1).
      2) Bean1 during its START phase (through the start() operation) wants to "install" another MC bean lets say Bean2 (which is of a completely different "type"). So Bean1 has this piece of code in its start

      public void start()
      {
      // install Bean2
      getKernel().getController().install(bean2.getBeanMetadata(),bean2Instance);
      }

      3) Now the important part - let's consider that the KernelController for this Kernel already has a bunch of contexts which are ready to go to START phase. So let's consider the controller has this bunch of contexts ready to got to START state - {Bean3, Bean4, Bean5}

      From what i see, when Bean1 installs Bean2 through the controller, the controller passes this context *and also the other contexts* through the various states. So during this single install operation on Bean2, the controller actually even starts incrementing the state of other contexts. So Bean3 is now moved to START state (and its start() operation is invoked).

      Questions:

      1) Is this API that is being used in the Bean1.start() the correct way to install a bean? I guess yes, because i could not find any other API which does a similar thing :)
      2) What is the best way to install a bean without affecting the state of other *unrelated beans*. In this example, Bean2 and Bean3 are unrelated, still installing Bean2 is causing a state change in Bean3. How do i avoid this?

        • 1. Re: How to install a bean without affecting unrelated bean's
          Ales Justin Master

           

          "jaikiran" wrote:

          1) Is this API that is being used in the Bean1.start() the correct way to install a bean? I guess yes, because i could not find any other API which does a similar thing :)

          Isn't a single entry the best approach?
          So you know you cannot "screw" it up. ;-)

          "jaikiran" wrote:

          2) What is the best way to install a bean without affecting the state of other *unrelated beans*. In this example, Bean2 and Bean3 are unrelated, still installing Bean2 is causing a state change in Bean3. How do i avoid this?

          If you wanted this, it would mean you would have to express all your
          "unrelated" dependencies, hence making it *related*. :-)

          Why would this bother you?

          If it's really a case when those beans are not allowed to move fwd,
          then it's just a case of missing proper dependencies. ;-)

          • 2. Re: How to install a bean without affecting unrelated bean's
            jaikiran pai Master

             

            "alesj" wrote:

            If you wanted this, it would mean you would have to express all your
            "unrelated" dependencies, hence making it *related*. :-)

            Not sure i understand this - the BMD being installed (Bean2) has all the related dependencies defined within itself. And those dependencies are *not* on Bean3 or any other contexts.

            "alesj" wrote:

            Why would this bother you?

            Okay, so here's the real issue https://jira.jboss.org/jira/browse/EJBTHREE-1724 and here's what's happening (the real scenario which i mocked in my post earlier):

            1) Consider an application having around 300 EJBs
            2) EJBContainer (this is the Bean1 we talked in my first post) corresponding to one of these 300 beans has a start which installs a proxyfactory (bean2 in the earlier post).
            2) The kernel internally has other contexts for remaining 299 beans ready to be pushed to START.
            3) The proxyfactory (bean2) is *not* dependent on any of these 299 beans (kernel contexts Bean3, Bean4, Bean5 that we discussed in my first post) and ideally can be "installed" without having to do anything with the remaining 299 contexts. (This isn't the case currently in MC - read #4 below)
            4) Right now in MC, the proxyfactory install (which was triggered by the EJBContainer (Bean1)) triggers a START of Bean3 which installs proxyfactory2 which then triggers START of someother context (Bean4) and this goes on and on for all those 300 beans and effectively leads to a recursive call on the same instance of AbstractController install method, leading to a StackOverflowError.

            Since proxyfactory and the other contexts are unrelated and independent, i would have expected no state change on other beans when proxyfactory is installed thus avoiding this recursion on the same method.





            • 3. Re: How to install a bean without affecting unrelated bean's
              Ales Justin Master

               

              "jaikiran" wrote:
              "alesj" wrote:

              If you wanted this, it would mean you would have to express all your
              "unrelated" dependencies, hence making it *related*. :-)

              Not sure i understand this - the BMD being installed (Bean2) has all the related dependencies defined within itself. And those dependencies are *not* on Bean3 or any other contexts.

              You don't know if it's really (un)related until you tried it.
              How else would you know that beanX is not related to beanY
              unless you tried to push beanY past some state or by inspecting all dependencies out there.

              "jaikiran" wrote:

              Since proxyfactory and the other contexts are unrelated and independent, i would have expected no state change on other beans when proxyfactory is installed thus avoiding this recursion on the same method.

              This is by design, we try to move anything until something previously still moved.
              The recursion shouldn't be too big, since if bean has no real dependencies,
              it's moved to installed on first attempt, hence not hugely involved anymore in context state changing/checking.
              And 300+ should be the number we can handle ...

              • 4. Re: How to install a bean without affecting unrelated bean's
                jaikiran pai Master

                 

                "alesj" wrote:

                You don't know if it's really (un)related until you tried it.
                How else would you know that beanX is not related to beanY

                Isn't this possible by just checking the dependencies of beanX?

                "alesj" wrote:

                The recursion shouldn't be too big, since if bean has no real dependencies, it's moved to installed on first attempt, hence not hugely involved anymore in context state changing/checking.

                I need to explain this a bit more :) The (MC) bean (=proxyfactory) has no real dependencies. Infact the question is not really about dependencies. Its more of a single install triggering a recursive installation of all other (unrelated) contexts that are available in the controller. The controller recursively installs these based on *states* and not because those are any dependencies of the bean being installed:

                // This one resolves all the contexts by State. So if there are N number of contexts in
                 // the ready to start state, their state will be incremented even if they are not
                 // real dependencies of the original context that was passed for "install"
                protected boolean resolveContexts(ControllerState fromState, ControllerState toState, boolean trace)
                 {
                 boolean resolutions = false;
                 Set<ControllerContext> unresolved = contextsByState.get(fromState);
                 Set<ControllerContext> resolved = resolveContexts(unresolved, toState, trace);
                 if (resolved.isEmpty() == false)
                 {
                 for (ControllerContext context : resolved)
                 {
                 Object name = context.getName();
                 if (fromState.equals(context.getState()) == false)
                 {
                 if (trace)
                 log.trace("Skipping already installed " + name + " for " + toState.getStateString());
                 }
                 else if (installing.add(context) == false)
                 {
                 if (trace)
                 log.trace("Already installing " + name + " for " + toState.getStateString());
                 }
                 else
                 {
                 try
                 {
                 if (trace)
                 log.trace("Dependencies resolved " + name + " for " + toState.getStateString());
                
                 if (incrementState(context, trace))
                



                "alesj" wrote:

                And 300+ should be the number we can handle ...

                Right now not :) The application that i attached is bare minimal in terms of dependencies within the beans.