3 Replies Latest reply on Sep 26, 2005 9:04 AM by justinwalsh

    Stopping MBean throws exceptions

      Hi,

      I am writing an MBean to programmatically destroy an existing connection pool and create a new one. As a part of this, I've implemented the below class and deployed it on the JBoss AS 3.2.5.

      import java.sql.Connection;
      import java.sql.Statement;
      
      import javax.management.*;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.sql.DataSource;
      
      public class DSCreator implements DSCreatorMBean
      {
       private MBeanServer myServer = null;
      
       public void createMBean()
       {
       try
       {
       MBeanServer server = getServer();
      
       ObjectName cmName = new ObjectName("jboss.jca:service=NoTxCM,name=MyDS");
       ObjectName mcfName = new ObjectName("jboss.jca:service=ManagedConnectionFactory,name=MyDS");
       ObjectName mcpName = new ObjectName("jboss.jca:service=ManagedConnectionPool,name=MyDS");
      
       stopDestroyAndRemoveMBean(cmName);
       stopDestroyAndRemoveMBean(mcfName);
       stopDestroyAndRemoveMBean(mcpName);
      
       server.createMBean("org.jboss.resource.connectionmanager.NoTxConnectionManager",cmName);
       server.createMBean("org.jboss.resource.connectionmanager.RARDeployment",mcfName);
       server.createMBean("org.jboss.resource.connectionmanager.JBossManagedConnectionPool",mcpName);
      
       setCMAttributeList(cmName,mcpName);
       setMCFAttributeList(mcfName);
       setMCPAttributeList(mcfName,mcpName);
      
       ObjectName serviceControllerName = new ObjectName("jboss.system:service=ServiceController");
       startManagedConnectionFactory(serviceControllerName,mcfName);
       startManagedConnectionPool(serviceControllerName,mcpName);
       startConnectionManager(serviceControllerName,cmName);
       }
       catch(Exception e)
       {
       e.printStackTrace();
       }
       }
      
       private void stopDestroyAndRemoveMBean(ObjectName name) throws Exception
       {
       ObjectName serviceControllerName = new ObjectName("jboss.system:service=ServiceController");
      
       if(getServer().isRegistered(name))
       {
       invoke(serviceControllerName,
       "stop",
       new Object[] {name},
       new String[] {"javax.management.ObjectName"});
       invoke(serviceControllerName,
       "destroy",
       new Object[] {name},
       new String[] {"javax.management.ObjectName"});
       invoke(serviceControllerName,
       "remove",
       new Object[] {name},
       new String[] {"javax.management.ObjectName"});
       }
       }
      
       private void startManagedConnectionFactory(ObjectName serviceControllerName, ObjectName mcfName) throws Exception
       {
       // create and configure the ManagedConnectionFactory
       invoke(serviceControllerName,
       "create",
       new Object[] {mcfName},
       new String[] {"javax.management.ObjectName"});
       invoke(serviceControllerName,
       "start",
       new Object[] {mcfName},
       new String[] {"javax.management.ObjectName"});
      
       //Now set the important attributes:
       invoke(mcfName, "setManagedConnectionFactoryAttribute",
       new Object[] {"ConnectionURL", java.lang.String.class, "jdbc:sybase:Tds:host:port/db"},
       new String[] {"java.lang.String", "java.lang.Class", "java.lang.Object"});
       invoke(mcfName, "setManagedConnectionFactoryAttribute",
       new Object[] {"DriverClass", java.lang.String.class, "com.sybase.jdbc2.jdbc.SybDriver"},
       new String[] {"java.lang.String", "java.lang.Class", "java.lang.Object"});
       invoke(mcfName, "setManagedConnectionFactoryAttribute",
       new Object[] {"UserName", java.lang.String.class, "user"},
       new String[] {"java.lang.String", "java.lang.Class", "java.lang.Object"});
       invoke(mcfName, "setManagedConnectionFactoryAttribute",
       new Object[] {"Password", java.lang.String.class, "pwd"},
       new String[] {"java.lang.String", "java.lang.Class", "java.lang.Object"});
       }
      
       private void startManagedConnectionPool(ObjectName serviceControllerName, ObjectName mcpName) throws Exception
       {
       //start the pool
       invoke(serviceControllerName,
       "create",
       new Object[] {mcpName},
       new String[] {"javax.management.ObjectName"});
       invoke(serviceControllerName,
       "start",
       new Object[] {mcpName},
       new String[] {"javax.management.ObjectName"});
       }
      
       private void startConnectionManager(ObjectName serviceControllerName, ObjectName cmName) throws Exception
       {
       // start the ConnectionManager
       invoke(serviceControllerName,
       "create",
       new Object[] {cmName},
       new String[] {"javax.management.ObjectName"});
       invoke(serviceControllerName,
       "start",
       new Object[] {cmName},
       new String[] {"javax.management.ObjectName"});
       }
      
       private Object invoke(ObjectName name, String method, Object[] args, String[] sig) throws Exception
       {
       return getServer().invoke(name, method, args, sig);
       }
      
       private void setCMAttributeList(ObjectName cmName, ObjectName mcpName) throws Exception
       {
       AttributeList al = new AttributeList();
       al.add(new Attribute("JndiName", "MyDS"));
       al.add(new Attribute("ManagedConnectionPool", mcpName));
       al.add(new Attribute("CachedConnectionManager", new ObjectName("jboss.jca:service=CachedConnectionManager")));
       al.add(new Attribute("OldRarDeployment ", new ObjectName("jboss.jca:service=RARDeployment,name=JBoss LocalTransaction JDBC Wrapper")));
       //try to set the attributes on the bean
       getServer().setAttributes(cmName, al);
       }
      
       private void setMCFAttributeList(ObjectName mcfName) throws Exception
       {
       AttributeList al = new AttributeList();
       al.add(new Attribute("ManagedConnectionFactoryClass", "org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory"));
       //try to set the attributes on the bean
       getServer().setAttributes(mcfName, al);
      
       }
      
       private void setMCPAttributeList(ObjectName mcfName,ObjectName mcpName) throws Exception
       {
       AttributeList al = new AttributeList();
       al.add(new Attribute("ManagedConnectionFactoryName", mcfName));
       al.add(new Attribute("MinSize", new Integer(0)));
       al.add(new Attribute("MaxSize", new Integer(50)));
       al.add(new Attribute("BlockingTimeoutMillis", new Long(5000)));
       al.add(new Attribute("IdleTimeoutMinutes", new Integer(15)));
       al.add(new Attribute("Criteria", "ByNothing"));
       //try to set the attributes on the bean
       getServer().setAttributes(mcpName, al);
      
       }
      
       private MBeanServer getServer()
       {
       if(myServer == null)
       {
       myServer = (MBeanServer)MBeanServerFactory.findMBeanServer(null).get(0);
       }
      
       return myServer;
       }
      
       public void start()
       {
       }
      
       public void stop()
       {
       }
      }


      All the public methods mentioned above are present in the interface.

      I already have the DataSource "java:/MyDS" created via the sybase-ds.xml, during the server startup. Now, when I invoke the createMBean method for the first time, it destroys the datasource and creates a new one without any problem. I was also able to test to see if the connection pool is working. Now, when I invoke the createMBean again, I get the below exception:

      15:16:38,130 ERROR [JBossManagedConnectionPool] Stopping failed jboss.jca:service=ManagedConnectionPool,name=MyDS
      javax.management.InstanceNotFoundException: jboss.jca:service=ManagedConnectionFactory,name=MyDS is not registered.
       at org.jboss.mx.server.registry.BasicMBeanRegistry.get(BasicMBeanRegistry.java:462)
       at org.jboss.mx.server.MBeanServerImpl.removeNotificationListener(MBeanServerImpl.java:544)
       at org.jboss.resource.connectionmanager.JBossManagedConnectionPool.stopService(JBossManagedConnectionPool.java:408)
       at org.jboss.system.ServiceMBeanSupport.jbossInternalStop(ServiceMBeanSupport.java:319)
       at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:223)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:324)
       at org.jboss.mx.server.ReflectedDispatcher.dispatch(ReflectedDispatcher.java:60)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:61)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:53)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
       at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:185)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:473)
       at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:837)
       at $Proxy65.stop(Unknown Source)
       at org.jboss.system.ServiceController.stop(ServiceController.java:449)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:324)
       at org.jboss.mx.server.ReflectedDispatcher.dispatch(ReflectedDispatcher.java:60)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:61)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:53)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
       at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:185)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:473)
       at test.jboss.jca.DSCreator.invoke(DSCreator.java:196)
       at test.jboss.jca.DSCreator.stopDestroyAndRemoveMBean(DSCreator.java:123)
       at test.jboss.jca.DSCreator.createMBean(DSCreator.java:95)


      The last line in the above exception is line 95 of this code(the above code is edited, so it doesn't exactly correspond what's below), which is:
      stopDestroyAndRemoveMBean(mcpName);


      I'm not sure why it throws this exception only when I do it the second time. I'd like to understand the dependencies between the NoTXCM and ManagedConnectionFactory and the ManagedConnectionPool. I suppose ManagedConnectionFactory is depending upon ManagedConnectionPool and hence it's stopping that MBean even before it stops the MCF and that's causing this exception. Could someone confirm this?

      Can someone let me know what could be causing this exception?

      Thanks,
      Kalyan.

        • 1. Re: Stopping MBean throws exceptions

          Though I get the exception the newly created connection pool works. Moreover, the stopDestroyAndRemoveMBean method first checks if the mbean is already registered with the MBeanServer or not and only if it is registered, it will try to stop, destroy and remove the mbean. It's strange that the getServer().isRegistered(name) is returning true, but the exception that's throws says that 'name' is not registered.

          Any help would be appreciated. I atleast wanted to hide this exception from the log and I don't seem to have a handle to how's it's getting printed. I tried to consume this exception in my code, but the exception doesn't seem to get propagated to my code, but it's getting printed somewhere in the middle, between my code and BasicMBeanRegistry.get method.

          Thanks,
          Kalyan.

          • 2. Re: Stopping MBean throws exceptions

            You need to unregister the MBean using

            getServer().unregisterMBean(name);
            

            Just destroying the bean will not suffice.

            • 3. Re: Stopping MBean throws exceptions

              Aaah - I see that you are calling "remove" on the bean (which translates to a unregister eventually)

              So - Ignore my previous post.

              The beans that you are creating have the following dependencies in the direction of the arrow
              NoTxCM --> ManagedConnectionPool --> ManagedConnectionFactory

              i.e. The NoTxCM depends on the ManagedConnectionPool .... etc

              You therefore need to stop/destroy the beans and remove them so that the dependencies are not broken:

               ObjectName mcFactoryName = new ObjectName("jboss.jca:service=ManagedConnectionFactory,name=MyDS");
               ObjectName mcPoolName = new ObjectName("jboss.jca:service=ManagedConnectionPool,name=MyDS");
               ObjectName txConManagerName = new ObjectName("jboss.jca:service=NoTxCM,name=MyDS");
              
               // stop and destroy in the order of dependencies
               stopAndDestroyMBean(mcFactoryName);
               stopAndDestroyMBean(mcPoolName);
               stopAndDestroyMBean(txConManagerName);
              
               // remove in the reverse order of dependencies
               removeMBean(txConManagerName);
               removeMBean(mcPoolName);
               removeMBean(mcFactoryName);
              
               // create in the reverse order of dependencies
               createManagedConnectionFactory(mcFactoryName);
               createManagedConnectionPool(mcPoolName, mcFactoryName);
               createTxConManager(txConManagerName, mcPoolName);
              


               private void stopAndDestroyMBean(ObjectName name) throws Exception {
               ObjectName serviceControllerName = new ObjectName(
               "jboss.system:service=ServiceController");
              
               if (getServer().isRegistered(name)) {
               getServer().invoke(serviceControllerName, "stop",
               new Object[] { name },
               new String[] { "javax.management.ObjectName" });
               getServer().invoke(serviceControllerName, "destroy",
               new Object[] { name },
               new String[] { "javax.management.ObjectName" });
               }
               }
              

               private void removeMBean(ObjectName name) throws Exception {
              
               ObjectName serviceControllerName = new ObjectName(
               "jboss.system:service=ServiceController");
              
               if (getServer().isRegistered(name)) {
               getServer().invoke(serviceControllerName, "remove",
               new Object[] { name },
               new String[] { "javax.management.ObjectName" });
               }
               }