12 Replies Latest reply on Apr 19, 2004 10:11 PM by ben.wang

    Using TreeCacheAop inside Jboss via MBean

    peterox

      As the title suggests, I have been trying to access a TreeCacheAop inside of a session EJB with absolutely no luck.

      Please help!!!

      First some background.
      JBoss version 4.0.0DR3
      JDK 1.4.2_04


      I have successfully created a TreeCacheMBean, via the MBeanServerFactory.

      public class TesterBean
       implements SessionBean {
       SessionContext sessionContext;
       protected TreeCacheMBean cache=null;
       protected MBeanServer server=null;
       static final String cache_service="jboss.cache:service=TreeCacheAop";
       protected ObjectName cacheService = null;
      
       public void setSessionContext(SessionContext sessionContext) {
       this.sessionContext = sessionContext;
       List servers=MBeanServerFactory.findMBeanServer(null);
       if(servers == null || servers.size() == 0)
       {
       //throw new Exception("TreeCacheView.init(): no MBeanServers found");
       }
       else
       {
       server=(MBeanServer)servers.get(0);
       try {
       cacheService = new ObjectName(cache_service);
       cache = (TreeCacheMBean) MBeanProxyExt.create
       (TreeCacheMBean.class,
       cache_service, server);
       }
       catch (MalformedObjectNameException ex) {
       System.out.println(ex.getMessage());
       }
       }
       }


      And I did add a node via the put methods.

      ....
      cache.put("/aNode", "test", "foo");

      ....

      All well and good. After that I tried to add an AOP object and found that there is no putObject method in TreeCacheMBean. So I tried the following:

      public void addSoemthing(int ID, String name) {
      
       try {
      
       Fqn fqn = new Fqn(new Integer(sportID));
       Sport newSport = new Sport(sportID, name);
       Object[] args = {fqn, newSport};
       String[] sig = {String.class.getName(), Object.class.getName()};
       server.invoke(cacheService, "putObject", args, sig);
       }
       catch (ReflectionException ex) {
       System.out.println(ex);
       }
       catch (MBeanException ex) {
       System.out.println(ex);
       }
       catch (InstanceNotFoundException ex) {
       System.out.println(ex);
       }
       }


      And I get the reflection exception:
      Cause: java.lang.IllegalArgumentException: Unable to find operation putObject(java.lang.String,java.lang.Object)

      I have just downloaded the JBoss source code and I can't even find the code for TreeCacheMBean???

      What am I missing???

      Thanks in advance.


        • 1. Re: Using TreeCacheAop inside Jboss via MBean
          belaban

          Okay, our bad !

          TreeCacheAop was not an MBean. I have just added the xdoclet tags to make it into one, and checked my code into the CVS (jboss-head).

          We do *not* write the TreeCacheMBean or TreeCacheAopMBeans, but let xdoclet do it. Once you have run the build, you will see both classes under output/gen-src.

          Regards,
          Bela

          • 2. Re: Using TreeCacheAop inside Jboss via MBean
            starksm64

            TreeCacheAop was a TreeCacheMBean by virtue of the fact that it extended TreeCache or else he would not have been able to create it through the MBeanServer. However, this does not expose the putObject operation.

            You can expose any object as an mbean using the xmbean deployment mechanism without having to introduce management interfaces. Create an xmbean descriptor for the TreeCacheAop class following the docs/dtds/jboss_xmbean_1_1.dtd and create a org.jboss.mx.modelmbean.XMBean doing something like this:

             public static ObjectName createServletMBean(MBeanServer server)
             throws Exception
             {
             ObjectName oname = new ObjectName(...);
             ClassLoader loader = Thread.currentThread().getContextClassLoader();
             URL servletInfoURL = loader.getResource("META-INF/servletinfo-xmbean.xml");
             XMBean xmbean = new XMBean(info, servletInfoURL);
             ServletInfo info = new ServletInfo();
             server.registerMBean(xmbean, oname);
             return oname;
             }
            
            


            • 3. Re: Using TreeCacheAop inside Jboss via MBean
              peterox

              Firstly in reply to bela:

              I have just completed compiling JBoss for the first time. No worries.
              BUT, there is no TreeViewAopMBean class. I looked into the xdoclet tag you mentioned and found that TreeCache has a @jmx.mbean and many @jmx.managed-operation tags, but TreeCachAop does not. Is this just an oversight or and I missing a piece of the puzzle??

              Secondly in reply to Scott:

              I am just new to JBoss and therefore I am not familiar with what exactly an MBean is?? Can you suggest any doco that would enlighten me??

              I'll give your suggestion a go, but let me just check I'm getting what your saying??

              I create this xml file and then simply use the same invoke method on the created server that I had previously?

              I found the "xmbeancache-service.xml" file under ache/etc, can I use this as a starting point?

              • 4. Re: Using TreeCacheAop inside Jboss via MBean
                starksm64

                xmbeancache-service.xml is a service descriptor with an embedded xmbean.
                You could deploy the TreeCacheAop service in a similar manner.

                Else, look at the xmbean descriptors in the server/default/conf/xmdesc directory, for example JNDIView-xmbean.xml

                • 5. Re: Using TreeCacheAop inside Jboss via MBean
                  peterox

                  In your example you pass an 'info' object to the constructor of the XMBean object. What is this meant to be?

                  • 6. Re: Using TreeCacheAop inside Jboss via MBean
                    belaban

                    TreeCacheAop is an MBean now, meaning it exposes its and its superclass' attrs/ops. This is in jboss-head, checked in yesterday.

                    Bela

                    • 7. Re: Using TreeCacheAop inside Jboss via MBean
                      starksm64

                      The info object is the pojo resource the XMBean is exposing a management interface for. In your case it would be the TreeCacheAop instance.

                      • 8. Re: Using TreeCacheAop inside Jboss via MBean
                        peterox

                        bela,

                        Thanks for that, but I am still having troubles. Everything compiles but when putObject is called the following is output.

                        java.lang.IllegalArgumentException: Unable to find operation putObject(org.jboss.cache.Fqn,java.lang.Object)


                        Any ideas??

                        • 9. Re: Using TreeCacheAop inside Jboss via MBean
                          belaban

                          You're not using the right jboss-cache.jar. Check out the generated TreeCacheAopMBean, and then do a jar tvf jboss-cache.jar |grep TreeCacheAopMBean.

                          You can also check like this:
                          javap -classpath jboss-cache.jar org.jgroups.cache.aop.TreeCacheAopMBean |grep putObject

                          to see if the method is found.
                          Bela

                          • 10. Re: Using TreeCacheAop inside Jboss via MBean
                            peterox

                            Scott,

                            I am also having no luck with your method. Here are the details.

                            Any ideas??


                             public static ObjectName createServletMBean(MBeanServer server)
                             throws Exception {
                             Object info = null;
                             ObjectName oname = new ObjectName(cache_service);
                             ClassLoader loader = Thread.currentThread().getContextClassLoader();
                             URL servletInfoURL = loader.getResource("META-INF/treecache-xmbean.xml");
                             System.out.println(servletInfoURL.toString());
                             server = MBeanServerFactory.createMBeanServer();
                            
                             // I tried both of the below methods, with same results
                             Descriptor d = new DescriptorSupport();
                             d.setField(XMBeanConstants.RESOURCE_REFERENCE, new TreeCacheAop());
                             d.setField(XMBeanConstants.RESOURCE_TYPE, servletInfoURL.toString());
                            
                             XMBean xmbean = new XMBean(d, XMBeanConstants.DESCRIPTOR);
                            
                             XMBean xmbean = new XMBean(new TreeCacheAop(), servletInfoURL);
                            
                             server.registerMBean(xmbean, oname);
                             return oname;
                             }
                            
                            


                            Here is the xml file

                            <?xml version="1.0" encoding="UTF-8"?>
                            <!DOCTYPE mbean PUBLIC "-//JBoss//DTD JBOSS XMBEAN 1.1//EN" "http://www.jboss.org/j2ee/dtd/jboss_xmbean_1_1.dtd">
                            <mbean>
                             <description>This is an XMBean that proxies to the TreeCacheAop</description>
                             <class>org.jboss.cache.aop.TreeCacheAop</class>
                             <operation>
                             <description>Put an element (key/value) in the hashmap of a given node</description>
                             <name>putObject</name>
                             <parameter>
                             <name>fqn</name>
                             <type>java.lang.String</type>
                             <description>The FQN of the node</description>
                             </parameter>
                             <parameter>
                             <name>obj</name>
                             <type>java.lang.Object</type>
                             <description>The object</description>
                             </parameter>
                             <return-type>java.lang.Object</return-type>
                             </operation>
                             <operation>
                             <description>Put an element (key/value) in the hashmap of a given node</description>
                             <name>putObject</name>
                             <parameter>
                             <name>fqn</name>
                             <type>org.jboss.cache.Fqn</type>
                             <description>The FQN of the node</description>
                             </parameter>
                             <parameter>
                             <name>obj</name>
                             <type>java.lang.Object</type>
                             <description>The object</description>
                             </parameter>
                             <return-type>java.lang.Object</return-type>
                             </operation>
                            </mbean>


                            Here is the exception

                            Error parsing the XML file, from XMLMetaData:
                            09:27:24,853 INFO [STDOUT] org.jboss.mx.util.JBossNotCompliantMBeanException: Error parsing the XML file, from XMLMetaData:
                            09:27:24,853 INFO [STDOUT] at org.jboss.mx.metadata.XMLMetaData.build(XMLMetaData.java:290)
                            09:27:24,853 INFO [STDOUT] at org.jboss.mx.modelmbean.XMBean.(XMBean.java:219)
                            09:27:24,853 INFO [STDOUT] at cachetest.TesterBean.createServletMBean(TesterBean.java:112)
                            09:27:24,853 INFO [STDOUT] at cachetest.TesterBean.setSessionContext(TesterBean.java:42)
                            09:27:24,869 INFO [STDOUT] at org.jboss.ejb.StatelessSessionEnterpriseContext.(StatelessSessionEnterpriseContext.java:47)
                            09:27:24,869 INFO [STDOUT] at org.jboss.ejb.plugins.StatelessSessionInstancePool.create(StatelessSessionInstancePool.java:35)
                            09:27:24,869 INFO [STDOUT] at org.jboss.ejb.plugins.AbstractInstancePool.get(AbstractInstancePool.java:146)
                            09:27:24,869 INFO [STDOUT] at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:58)
                            09:27:24,869 INFO [STDOUT] at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84)
                            09:27:24,869 INFO [STDOUT] at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:314)
                            09:27:24,884 INFO [STDOUT] at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:148)
                            09:27:24,884 INFO [STDOUT] at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:118)
                            09:27:24,884 INFO [STDOUT] at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
                            09:27:24,884 INFO [STDOUT] at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
                            09:27:24,900 INFO [STDOUT] at org.jboss.ejb.SessionContainer.internalInvoke(SessionContainer.java:572)
                            09:27:24,900 INFO [STDOUT] at org.jboss.ejb.Container.invoke(Container.java:889)
                            09:27:24,900 INFO [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                            09:27:24,900 INFO [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                            09:27:24,900 INFO [STDOUT] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                            09:27:24,900 INFO [STDOUT] at java.lang.reflect.Method.invoke(Method.java:324)
                            09:27:24,915 INFO [STDOUT] at org.jboss.mx.server.ReflectedDispatcher.dispatch(ReflectedDispatcher.java:74)
                            09:27:24,994 INFO [STDOUT] at org.jboss.mx.server.Invocation.dispatch(Invocation.java:45)
                            09:27:24,994 INFO [STDOUT] at org.jboss.mx.server.Invocation.invoke(Invocation.java:70)
                            09:27:24,994 INFO [STDOUT] at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:168)
                            09:27:24,994 INFO [STDOUT] at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:469)
                            09:27:24,994 INFO [STDOUT] at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:362)
                            09:27:25,103 INFO [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                            09:27:25,103 INFO [STDOUT] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                            09:27:25,103 INFO [STDOUT] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                            09:27:25,103 INFO [STDOUT] at java.lang.reflect.Method.invoke(Method.java:324)
                            09:27:25,103 INFO [STDOUT] at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
                            09:27:25,103 INFO [STDOUT] at sun.rmi.transport.Transport$1.run(Transport.java:148)
                            09:27:25,103 INFO [STDOUT] at java.security.AccessController.doPrivileged(Native Method)
                            09:27:25,103 INFO [STDOUT] at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
                            09:27:25,103 INFO [STDOUT] at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
                            09:27:25,103 INFO [STDOUT] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
                            09:27:25,353 INFO [STDOUT] at java.lang.Thread.run(Thread.java:534)
                            09:27:25,353 INFO [STDOUT] Caused by: org.dom4j.DocumentException: Error on line 12 of document jar:file:/E:/jboss-head/build/output/jboss-4.0.0DR3/server/all/tmp/deploy/tmp15810CacheTest.jar!/META-INF/treecache-xmbean.xml : Element "parameter" allows no further input; "description" is not allowed. Nested exception: Element "parameter" allows no further input; "description" is not allowed.
                            09:27:25,353 INFO [STDOUT] at org.dom4j.io.SAXReader.read(SAXReader.java:339)
                            09:27:25,384 INFO [STDOUT] at org.dom4j.io.SAXReader.read(SAXReader.java:218)
                            09:27:25,384 INFO [STDOUT] at org.jboss.mx.metadata.XMLMetaData.build(XMLMetaData.java:245)
                            09:27:25,400 INFO [STDOUT] ... 36 more


                            • 11. Re: Using TreeCacheAop inside Jboss via MBean
                              peterox

                              bela,

                              I did copy the newly created jboss-cache.jar to the server/default/lib directory. The output of the jar and javap calls are below:

                              934 Thu Mar 25 08:24:42 GMT+10:00 2004 org/jboss/cache/aop/TreeCacheAopMBean.class

                              Compiled from "TreeCacheAopMBean.java"
                              interface org.jboss.cache.aop.TreeCacheAopMBean extends org.jboss.cache.TreeCacheMBean{
                               public abstract void setEvictionPolicyClass(java.lang.String);
                               public abstract java.lang.Object putObject(java.lang.String,java.lang.Object);
                               throws java/lang/Exception
                               public abstract java.lang.Object putObject(org.jboss.cache.Fqn,java.lang.Object);
                               throws java/lang/Exception
                               public abstract java.lang.Object _putObject(org.jboss.cache.Fqn,java.lang.Object);
                               throws java/lang/Exception
                               public abstract java.lang.Object getObject(java.lang.String);
                               throws java/lang/Exception
                               public abstract java.lang.Object getObject(org.jboss.cache.Fqn);
                               throws java/lang/Exception
                               public abstract java.lang.Object removeObject(java.lang.String);
                               throws java/lang/Exception
                               public abstract java.lang.Object removeObject(org.jboss.cache.Fqn);
                               throws java/lang/Exception
                               public abstract java.lang.Object _put(org.jboss.cache.GlobalTransaction,org.jboss.cache.Fqn,java.lang.Object,java.lang.Object,
                              boolean);
                               throws org/jboss/cache/lock/LockingException, org/jboss/cache/lock/TimeoutException
                               public abstract void evict(org.jboss.cache.Fqn);
                               throws java/lang/Exception
                              }


                              So that seems to be fine.

                              • 12. Re: Using TreeCacheAop inside Jboss via MBean

                                Hi,

                                I have finally got around to fix this bug. I have also created a unit test case under test/cache/test/aop/MBeanUnitTestCase to test cache aop running as a MBean service.

                                We will plan to deliver a patch release soon.

                                -Ben