4 Replies Latest reply on May 24, 2008 3:04 PM by Andrew Rubinger

    Obtain Kernel from unspecified Context

    Andrew Rubinger Master

      I believe this has now graduated to a Developer's issue:

      http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4151409

      Ideally POJOs should not depend on the MC API, and could have everything injected from any IoC Container.

      However, this introduces a precondition that all POJOs with dependencies on MC Beans are installed into the MC itself. In many cases, this is not possible.

      Additionally, there are cases in which a POJO cannot have the Kernel available to it - ie. any instance that's not created by the application developer.

      What are the fundamental arguments against the following construct:

      KernelRegistry registry = KernelRegistry.getRegistry(); // Singleton
      
      /*
       * The Registry maintains a Map of all Kernels created under a key
       * of some KernelContext
       */
      
      // Properties from somewhere, possibly jboss-mc.properties
      KernelContext context = new KernelContext();
      // KernelContext context = new KernelContext(Properties); // Valid as well
      
      Kernel kernel = registry.getKernel(context);


      ?

      S,
      ALR

        • 1. Re: Obtain Kernel from unspecified Context
          Adrian Brock Master

           

          "ALRubinger" wrote:

          What are the fundamental arguments against the following construct:


          * Security - if you have two kernels in the same JVM with an api
          to get access to both, how do you stop one user playing with the other user's kernel?

          * API - why is name appropriate?
          e.g. for scoped kernels we use a scope key since the kernels are not independent
          and have a structure

          * An invalid assumption in your argument

          However, this introduces a precondition that all POJOs with dependencies on MC Beans are installed into the MC itself. In many cases, this is not possible.


          There are at least four ways to inject objects that are not managed by the MC.
          1) Using a factory (the factory knows how to get a reference to the object
          and it is then registered in the MC)
          2) Using a value-factory (a more general approach where the object
          is not registered in the MC - e.g. this can be used to inject things like system properties
          or get information from an ldap server, etc.
          3) Inject a locator - this is like (2) but less declartive. You inject an object
          that can be used to locate the relevant object in some arbitrary way
          4) Using a KernelRegistryPlugin - maps some other "namespace"s into the
          MC injection namespace

          * Philosophy
          This isn't pure IOC. You now depend upon the API and not just that, you have
          to agree a name which probably isn't going to work in some arbitrary environment.
          e.g. look at the horrible hack where we locate the MBeanServer by seeing
          which has a default domain of "jboss" - which isn't even necessarily unique

          The kernel is only really required for specialised cases where
          some component wants to manage the state of another component.
          e.g. the service controller managing jmx lifecycle or the deployers
          managing the deployment lifecycle
          Other uses are generally hacks because you haven't thought out how to
          do IOC properly.

          * Summary

          In general the building of such a registry is something a user can do according
          their usecase. e.g. in the appserver the singleton kernel can be located using
          ServiceController.getKernel(). But there's nothing to stop a web-app
          creating its own kernel for its own internal use.
          The retrieval/availablity of the relevant kernel(s) is best left whoever created it,
          since only they know how it should be used. But this is really for "super users",
          most users should use plain IOC.


          • 2. Re: Obtain Kernel from unspecified Context
            Andrew Rubinger Master

             

            "adrian@jboss.org" wrote:
            * An invalid assumption in your argument

            However, this introduces a precondition that all POJOs with dependencies on MC Beans are installed into the MC itself. In many cases, this is not possible.


            There are at least four ways to inject objects that are not managed by the MC.


            No, I need to inject *into* a bean not managed by MC.

            I'll proceed for now by letting the Host environment maintain a reference to the Kernel, as you'd suggested.

            My stance is that it's not always possible to do pure IoC. Seems like you object to my use of MC as an Object Store.

            * JNDI ObjectFactory.getObjectInstance() < Creates new instance of the Object Factory on every lookup
            * Struts Action Handler
            * Servlet
            * Anything else not instantiated by the developer

            S,
            ALR

            • 3. Re: Obtain Kernel from unspecified Context
              Adrian Brock Master

               

              "ALRubinger" wrote:

              My stance is that it's not always possible to do pure IoC. Seems like you object to my use of MC as an Object Store.


              Not all. I showed two different ways to do just that in the original MC examples. :-)

              It's called the locator pattern, but how you serialize a locator which is itself non-serializable
              because contains references to non-serializable objects is obviously a different issue.

              • 4. Re: Obtain Kernel from unspecified Context
                Andrew Rubinger Master

                For follow-up, my solution for EJB3 will be the following:

                * Introduce an Ejb3Registry SPI to informally mirror operation naming conventions set forth by JNDI (lookup, bind, rebind, unbind)
                * Implement an MC Plugin that conforms to the SPI
                * AS Deployers will be responsible for populating the Ejb3Registry with the MC Implementation (ie. put in a reference to the Kernel)
                * Unit Tests, Embedded, other runtimes become responsible for providing their own implementations or populating with MC Implementation

                This way, EJB3 may become agnostic to the Object Store and hence becomes decoupled from MC, further ensuring that only the appropriate Kernel is in scope (as many may be available within the JVM).

                S,
                ALR