1 2 Previous Next 15 Replies Latest reply on Dec 5, 2005 1:41 PM by adrian.brock

    JNDI Dependencies

    bill.burke

      Recently, I've been working on EJB3's to get them to publish their dependencies to the kernel (jb4, or mc5). One problem I've run into is that it is sometimes impossible to determine all the dependencies of an EJB3 as all the bindings are done through JNDI. Specifically EJB refs are tradionatlly wired through JNDI. Same with resource refs and such. Unfortunately, it is usually impossible to extract a kernel name from a jndi name to generate a dependency.

      JNDI has no notification service (or does it?). We could write one, but this would not be usable on older versions of JBoss. My idea is to create a JNDI watch service that polls for jndi dependencies. So the algorithm would look like this:

      1. EJB Deployer find JNDI dependency, create dependency on "jndi.depends:name=/foo/bar"
      2. EJB Deployer register JNDI watch with JNDI Watch Service.
      3. JNDI Watch service does continuous JNDI lookups. When JNDI name is available, register a simple MBEAN to satisfy #1 above. (This happens in background every 1 sec

      I don't know, maybe this is a bad idea altogether and the user should just have to create depends tags.

        • 1. Re: JNDI Dependencies
          starksm64

          There is an javax.naming.event api that we don't currently implement.

          So you are talking about runtime lookups of ejbs being implicit dependencies?

          • 2. Re: JNDI Dependencies
            bill.burke

            I don't think the javax.naming.event api will cut it. From what I can discern from the JavaDocs, you have to have an existing context to watch before you can register to listen to an event.


            So you are talking about runtime lookups of ejbs being implicit dependencies?


            I want to generate dependencies at deployment for ENC resources or injected resources. These include EJB refs and resource refs like queues/topics. I get a few dependency ordering questions on the EJB3 list.

            Bill

            • 3. Re: JNDI Dependencies
              bill.burke

              Actually, I'm not sure this service could work as there's no nice way to clean up these registered JNDI Dependency objects from the kernel unless I had a "garbage collector" for them. It wouldn't work very well (if at all) for redeployments.

              No, what you would have to do is intercept bind/unbind/rebind and register/unregister these JNDI dependency objects.

              • 4. Re: JNDI Dependencies
                bill.burke

                I guess the best thing to do is modify org.jnp.NamingService to accept injection of a JndiNotification interface for bind, unbind, rebind. Then this interface can do anything we want and we can later build the javax.naming.event stuff on top of it as well as a jndi dependency service.

                • 5. Re: JNDI Dependencies
                  starksm64

                   

                  "bill.burke@jboss.com" wrote:

                  I want to generate dependencies at deployment for ENC resources or injected resources. These include EJB refs and resource refs like queues/topics. I get a few dependency ordering questions on the EJB3 list.

                  Ok, but centering on jndi to manage this seems like the wrong thing to do though. Its seems that an extension to the existing depends notion in the deployment layer is needed to simply add a notion of a service being a supplier/consumer of non-jmx elements that can be used instead of an mbean level dependency.

                  Alternatively, you have depends using the jndi-names and there is an alias registry that maps between the jndi binding name and its supplier service object name.

                  • 6. Re: JNDI Dependencies

                     

                    "bill.burke@jboss.com" wrote:

                    No, what you would have to do is intercept bind/unbind/rebind and register/unregister these JNDI dependency objects.


                    ...


                    I guess the best thing to do is modify org.jnp.NamingService


                    No. Who says we are using org.jnp.NamingService for JNDI?

                    The correct solution is to use "Decorators" for jndi binding
                    rather than letting services manage it themselves.
                    Then we can add whatever behaviour we like regardless of JNDI implemenation

                    Pseudo code:

                    public Object invoke(Invocation invocation) throws Throwable
                    {
                     if (method == setKernelControllerContext)
                     {
                     KernelControllerContext ctx = getKernelControllerContext(invocation);
                     String jndiName = getJNDIFromMetaData(ctx);
                     JNDIBinding binding = new JNDIBinding(jndiName)
                     ctx.addSupplies(binding);
                     invocation.addInstanceMetaData(binding);
                     }
                     if (method == start)
                     {
                     String jndiName = invocation.getInstanceMetaData(JNDIBinding.class).getJNDIName();
                     jndiBindingPolicy.bind(jndiName);
                     }
                     if (method == stop)
                     {
                     String jndiName = invocation.getInstanceMetaData(JNDIBinding.class).getJNDIName();
                     jndiBindingPolicy.unbind(jndiName);
                     }
                    }
                    


                    <bean name="Blah">
                     <annotation name="JNDIName">whatver</annotation> <!-- Triggers Decorator -->
                    </bean>
                    or
                    @JNDIName("whatever")
                    public class MyBean
                    {
                    }
                    


                    • 7. Re: JNDI Dependencies

                       

                      "scott.stark@jboss.org" wrote:
                      "bill.burke@jboss.com" wrote:

                      I want to generate dependencies at deployment for ENC resources or injected resources. These include EJB refs and resource refs like queues/topics. I get a few dependency ordering questions on the EJB3 list.

                      Ok, but centering on jndi to manage this seems like the wrong thing to do though.


                      Correct. Dependency management belongs in the dependency controller.


                      Its seems that an extension to the existing depends notion in the deployment layer is needed to simply add a notion of a service being a supplier/consumer of non-jmx elements that can be used instead of an mbean level dependency.

                      Alternatively, you have depends using the jndi-names and there is an alias registry that maps between the jndi binding name and its supplier service object name.


                      I call this demands/supplies. I haven't done the "write your own dependency" abstraction
                      yet which will make this "redundant".

                      • 8. Re: JNDI Dependencies

                         

                        "adrian@jboss.org" wrote:

                        Pseudo code:


                        I suppose an explanation wouldn't go a miss as well :-)

                        The decorator intercepts the MC context construction
                        to add an extra dependency
                        addSupplies(binding)
                        

                        and remember the resolved instance level jndi name (either from annotations or the BeanMetaData overrides).

                        The instance level metadata is then used to do the binding
                        using whatever is configured as the jndiBindingPolicy.

                        NOTE: This decorator is a singleton implemented as a cross cutting
                        concern on the @JNDIName annotation.

                        You could also in principle add additional features like changing the binding
                        policy on an instance:

                        @JNDIName(name="whatever" bindingPolicy="SomethingOtherBeanInTheMC")
                        public class MyBean
                        {
                        }
                        


                        • 9. Re: JNDI Dependencies
                          bill.burke

                          Well, I wanted something that could work in older versions of JBoss 4.x with minimal modifications and patching. Neither JBoss 4.x or even CVS Head supports the notion of demands/supplies as nothing in head is using the MC to boot. Your solutions above requires the patching of each and every service/resource that publishes to JNDI. JNP is quite easy to patch for older versions of JBoss 4, all the other sevices, not. Maybe this is something I should just not do for JBoss 4.x.

                          My idea was to patch JNP to just spit out notifications of bind/unbind events. An implementation of javax.naming.event could be built on top of this as well as the JNDI dependency service I talked about. above. So, JNP wouldn't be responsible for managing this stuff, just for notificiation of bind/unbind events.

                          I have recently written a small kernel abstraction to find how dependencies are registered for(demands) and how services are installed/uninstalled for both JBoss4 and MC. I'll post a wiki/blog/forum post about it when I finish. I've almost entirely abstracted the EJBContainer so it doesn't know if it is booted by the MC outside of JBoss (or JBoss 5) or within a JMX kernel.

                          I'll try out the demands/supplies stuff with JNDI dependencies in the MC version of this.

                          • 10. Re: JNDI Dependencies

                            "Maybe this is something I should just not do for JBoss 4.x."

                            In JBoss4, not only might not the jndi name be bound, the class might not
                            even be deployed, yet... :-)
                            There are a number of other issues/limitations with the lifecycle handling for cross
                            deployment dependencies.
                            Were you there a year ago when I did "JBoss4 MicroKernel - a critique"?
                            Or were you there but playing poker on your laptop :-)

                            • 11. Re: JNDI Dependencies

                               

                              "adrian@jboss.org" wrote:

                              There are a number of other issues/limitations with the lifecycle handling for cross
                              deployment dependencies.

                              That are not create/start/stop/destroy


                              • 12. Re: JNDI Dependencies

                                 

                                "bill.burke@jboss.com" wrote:
                                Your solutions above requires the patching of each and every service/resource that publishes to JNDI. JNP is quite easy to patch for older versions of JBoss 4, all the other sevices.


                                But this needs fixing in general.
                                * Who says we are using JNP?
                                * What if the context is read-only using the public jndi api?
                                * This code is repeated everywhere and I have to fix a number of issues with
                                it being wrong, not doing error handling correctly, etc.


                                My idea was to patch JNP to just spit out notifications of bind/unbind events. An implementation of javax.naming.event could be built on top of this as well as the JNDI dependency service I talked about. above. So, JNP wouldn't be responsible for managing this stuff, just for notificiation of bind/unbind events.


                                That is a workaround to the problem, not a long term solution ;-)
                                What else needs doing on these bind events? Who else supplies them?
                                This pattern is repeated for other services besides JNDI.

                                i.e. cross-cutting concern ;-)

                                • 13. Re: JNDI Dependencies
                                  bill.burke

                                   

                                  "adrian@jboss.org" wrote:
                                  "Maybe this is something I should just not do for JBoss 4.x."

                                  In JBoss4, not only might not the jndi name be bound, the class might not
                                  even be deployed, yet... :-)


                                  I don't think so...

                                  1. EJB 1 has @EJB ref bound to a specific JNDI name we'll say "foo".
                                  2. EJB 1 Deployer creates a dependency in kernel for an MBean "jndi.depends:name=foo"
                                  3. Foo gets deployed. EJB 2 Container binds "foo" into JNDI.
                                  4. JNDI bind() is intercepted and sends notification that a binding of "foo" is happening.
                                  5. A JNDI Watch service receives the notification and creates an MBean "jndi.depends:name=foo" and tells the service controller to create/start it
                                  6. EJB 1 Container's dependency is resolved.

                                  shutdown:
                                  7. EJB2 unbinds "foo". JNP intercepts this and sends "unbind" notification
                                  8. JNDI Watch service receives notification and stops/destroys/removes "jdni.depends:name=foo".

                                  Conceptually this is the same as your demands/supplies as the kernel is still managing dependencies. But the JNDI Watch service is handling the "aliasing" by creating an MBean that is the alias.

                                  If you have the VERY RARE (only in fantasy land) case where a resource lives in non-JNP JNDI then the user just has to create the JNDI DEPENDENCY MBean themselves.


                                  There are a number of other issues/limitations with the lifecycle handling for cross
                                  deployment dependencies.


                                  u do what you can and what u have time for. With completeness you will never finish and deliver a product.


                                  Were you there a year ago when I did "JBoss4 MicroKernel - a critique"?
                                  Or were you there but playing poker on your laptop :-)


                                  Or maybe I just couldn't interpret your mumbling/accent as usual. No, I think it really was that I was playing poker at TSS Las Vegas.



                                  • 14. Re: JNDI Dependencies
                                    starksm64

                                    I still don't see why jndi is the focus here. The closest analog to the jboss5 kernel depenency controller is the service controller, and it makes more sense to expose this "jndi" info as a demands/supplies notion based on a name (jndi is one example) that is mapped to the existing dependency mechanism based on the service that supplies the demanded resources. This could probably be added to the DeploymentInfo context rather easily.

                                    That ejb-local-refs even have a jndi binding is a implementation detail that need not exist. Has that changed in ejb3 with @EJB annotations?

                                    1 2 Previous Next