8 Replies Latest reply on Jun 5, 2007 10:04 AM by manik

    Binding proxy to Cache in AS JNDI

    brian.stansberry

      Just realized that the standard way of providing remote access to the cache by binding a proxy in JMX will no longer work with 2.0.

      The usual JRMPProxyFactory approach works with MBeans, which in 2.0 means the CacheJmxWrapper. So, we can bind a proxy to the CacheJmxWrapper, but people likely want the Cache, not the wrapper.

      Client calling getCache() on the wrapper proxy doesn't work, as it's a remote call that will try to return the server side Cache to the remote client.

        • 1. Re: Binding proxy to Cache in AS JNDI
          manik

          Shouldn't it be up to any wrapper code to handle binding to JNDI (as per the ${SUBJECT} instead? This is what I would have thought.

          • 2. Re: Binding proxy to Cache in AS JNDI
            brian.stansberry

            Here's problem in a little more detail. The following is not really accurate; I'm avoiding some abstractions/indirections in the interest of clarity.

            The binding is done by an external mbean service, JRMPProxyFactory. It creates a proxy that implements the specified interface. Our goal is to expose Cache, so lets say it implements Cache.

            The proxy knows how to communicate with one of the AS' detached invokers (which one is a config detail of the JRMPProxyFactory.) When the client invokes a method, it sends back an Invocation object encapsulating the ObjectName of the service to call on, along with the method name and params.

            The detached invoker receives the Invocation and extracts the ObjectName, method name and args. It then does a call on the MBeanServer to invoke the given method.

            Problem is there is no mbean anywhere that exposes the Cache interface. Hence the detached invoker cannot make a call via the MBeanServer to any of the Cache methods.

            • 3. Re: Binding proxy to Cache in AS JNDI
              brian.stansberry

              The JRMPProxyFactory does have one potentially useful config option.

              If your service (say CacheJmxWrapper) exposes this method in its mbean interface:

              public Object invoke(Invocation mi) throws Exception


              then you can set the "InvokeTargetMethod" attribute on JRMPProxyFactory to 'false'. If configured that way, the detached invoker won't try to invoke the target method (e.g. get(fqn, key)) but rather will invoke the invoke(Invocation mi) method.

              It is then the responsibility of your service to read the target method and args from the Invocation and decide how to deal with them. This is how EJB2 containers work.

              In the CacheJmxWrapper case, its implementation of invoke(Invocation mi) would read the method name/args from the invocation and use reflection to invoke on the wrapped Cache.

              Something like that could certainly be implemented, but not in the JBC code base. JBC does not have visibility to the Invocation class. I would have to implement it in the AS code base.

              Want to find a better solution, as this seems like a general AS 5 problem -- exposing Remoting-capable proxies for POJO services.

              • 4. Re: Binding proxy to Cache in AS JNDI
                brian.stansberry

                See http://www.jboss.com/index.html?module=bb&op=viewtopic&t=109907 for the better solution.

                But, here's a related issue....

                Say we solve the Cache issue and a remote Cache proxy is available. Any API call that requires use of a Node will fail, since the Node won't be a remote object. The only available API will be those methods that don't involve a Node.

                • 5. Re: Binding proxy to Cache in AS JNDI
                  brian.stansberry

                  End of my monologue...

                  Coming off the above referenced forum thread, there's now an AS JIRA for solving the original problem: http://jira.jboss.com/jira/browse/JBAS-4456

                  Doubtful this will be done before JBC 2.0, so for the 2.0 doc section on JNDI binding, I'm just going to make a comment that the old method won't work and include a link to the JIRA issue.

                  • 6. Re: Binding proxy to Cache in AS JNDI
                    manik

                     


                    Say we solve the Cache issue and a remote Cache proxy is available. Any API call that requires use of a Node will fail, since the Node won't be a remote object. The only available API will be those methods that don't involve a Node.


                    Hmm, this may involve exposing and binding each Node, which sucks/bordering on completely ridiculous.

                    How about mandating that if you intend to access the cache via JMX, don't use Node APIs? Yes, this restricts some functionality, but not all, and even then only for people remotely accessing a cache bound in JMX/JNDI.

                    And for local usage, people would either create a cache instance directly, or how about binding the CacheFactory (java:/ namespace) so people can get a hold of the cache?

                    Related topic - should CacheFactory always construct caches? Should it also be able to retrieve already-constructed, named caches?

                    E.g.,

                    Cache c1 = DefaultCacheFactory.createCache("MyCache", "cfg.xml");
                    Cache c2 = DefaultCacheFactory.createCache("MyCache", "cfg.xml");
                    
                    assertSame(c1, c2);
                    




                    • 7. Re: Binding proxy to Cache in AS JNDI
                      brian.stansberry

                       

                      "manik.surtani@jboss.com" wrote:

                      Say we solve the Cache issue and a remote Cache proxy is available. Any API call that requires use of a Node will fail, since the Node won't be a remote object. The only available API will be those methods that don't involve a Node.


                      Hmm, this may involve exposing and binding each Node, which sucks/bordering on completely ridiculous.


                      Oh, I'd say that's way over the ridiculous border. :)

                      How about mandating that if you intend to access the cache via JMX, don't use Node APIs? Yes, this restricts some functionality, but not all, and even then only for people remotely accessing a cache bound in JMX/JNDI.


                      Yes, I think this is more a documentation issue, telling people what won't work.

                      The only thing that I commonly used in 1.4 that can't be done via the Cache API are hasChild(Fqn) and getChildrenNames(Fqn).

                      And for local usage, people would either create a cache instance directly, or how about binding the CacheFactory (java:/ namespace) so people can get a hold of the cache?


                      Ignorant question whose answer I should know. If you bind the Cache itself in the java:/ namespace, does it serialize it or just store a ref to the cache in the JNDI tree? If not, then the user can just bind the cache in java:/ for the local clients.

                      Related topic - should CacheFactory always construct caches? Should it also be able to retrieve already-constructed, named caches?

                      E.g.,

                      Cache c1 = DefaultCacheFactory.createCache("MyCache", "cfg.xml");
                      Cache c2 = DefaultCacheFactory.createCache("MyCache", "cfg.xml");
                      
                      assertSame(c1, c2);
                      




                      Interesting. I think the tricky bit is you have to have a cleanup API to remove the caches (or use WeakReferences).

                      If the client is local and JMX is available, they can just use CacheJmxWrapper and JMX becomes a registry. Or maybe binding the Cache in JNDI in java:/ will work.

                      • 8. Re: Binding proxy to Cache in AS JNDI
                        manik

                         



                        Ignorant question whose answer I should know. If you bind the Cache itself in the java:/ namespace, does it serialize it or just store a ref to the cache in the JNDI tree? If not, then the user can just bind the cache in java:/ for the local clients.


                        Should be a ref - in which case storing a Cache instance would work too.



                        Interesting. I think the tricky bit is you have to have a cleanup API to remove the caches (or use WeakReferences).


                        Or the cleanup could be triggered when a cache.destroy() is called - this could cause it to be "unregistered" with the cache factory.


                        If the client is local and JMX is available, they can just use CacheJmxWrapper and JMX becomes a registry. Or maybe binding the Cache in JNDI in java:/ will work.


                        See, I've always believed that JMX is for management information and management processes. To actually use a service, the service should be in JNDI. Maybe that's just me oversimplifying things.