10 Replies Latest reply: Nov 16, 2010 2:57 AM by 811624 RSS

    Help creating a queue using JMX

    811624
      Hi!
      I am using OpenMQ and trying to query all queues in a broker.
      First of all, I would like to create a queue, so I can recover it after, after some research I came to this code:

      HashMap environment = new HashMap();
      String[] credentials = new String[] {"user", "pass"};
      JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://IAI82180.tis:8686/jndi/rmi://IAI82180.tis:8686/jmxrmi");
      JMXConnector jmxc = JMXConnectorFactory.connect(url, environment);
      MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
      String brokerNameQuery = "org.apache.openmq:BrokerName=localhost,Type=Broker";
      String addQueueOperationName = "addQueue";
      Object[] params = { "myQueue" };
      String[] sig = { "java.lang.String" };

      ObjectName brokerObjName = new ObjectName(brokerNameQuery);
      mbsc.invoke(brokerObjName, addQueueOperationName, params, sig);

      But I get the error:

      Exception in thread "main" javax.management.InstanceNotFoundException: org.apache.openmq:BrokerName=localhost,Type=Broker

      I also went to the control panel and added a broker manually, but it doesn't solves the problem.

      I imagine the problem is in this string: org.apache.openmq:BrokerName=localhost,Type=Broker , which I adapted from an example I found.

      Could anyone help me, please?

      Thanks,
      Oscar
        • 1. Re: Help creating a queue using JMX
          Nigeldeakin-Oracle
          As you observed, the JMX object name you are using is completely wrong. You are also using the wrong operation name and arguments.

          The best place to start is in the official documentation. This is the Oracle GlassFish Message Queue 4.4.2 Developer's Guide for JMX Clients
          http://docs.sun.com/app/docs/doc/821-1797

          The MBean you need is called the Destination manager configuration MBean.
          Its name is described here:
          http://docs.sun.com/app/docs/doc/821-1797/gcirz?l=en&a=view
          Its operations are listed in this table here:
          http://docs.sun.com/app/docs/doc/821-1797/gcimp?l=en&a=view
          You need to use the "create" operation (rows 2 and 3 in that table), which as the table shows has two alternative forms, depending on whether you need to specify destination attributes or not.

          Nigel
          • 2. Re: Help creating a queue using JMX
            811624
            Hi,
            Thank you!
            That is strange that it is so wrong, because I got from an working example (which used activeMQ, but I thought that it would also work in openMQ since it is using the JMS API).
            I will take a look at the links! Thanks you a lot!
            • 3. Re: Help creating a queue using JMX
              811624
              Hi,
              I am reading the book and the explanation is very clear and there are many examples.
              This is the code I created:


              HashMap environment = new HashMap();
              String[] credentials = new String[] {"superadmin", "superadmin"};
              environment.put (JMXConnector.CREDENTIALS, credentials);
                        
              JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8686/jmxrmi");
                        
              JMXConnector jmxc = JMXConnectorFactory.connect(url, environment);
                   
              // Get MBean server connection
              MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
                        
              String addQueueOperationName = "create";
              Object[] params = { DestinationType.QUEUE,
                                       "MyQueue"};
              String[] sig = { String.class.getName(), String.class.getName() };

              ObjectName destinationObjName = new ObjectName(MQObjectName.DESTINATION_MANAGER_CONFIG_MBEAN_NAME);
              mbsc.invoke(destinationObjName, DestinationOperations.CREATE, params, sig);
              System.out.println("done creating");

              Very similar to the examples (except for the use of JMXservice instead of AdminConnectionFactory.

              But I still get a similar error: Exception in thread "main" javax.management.InstanceNotFoundException: com.sun.messaging.jms.server:type=DestinationManager,subtype=Config in the invoke method-

              If I copy and paste the example, the error is the same

              If I use the AdminConnectionFactory, I get the following error

              Exception in thread "main" java.lang.IllegalAccessError: tried to access method com.sun.messaging.jmq.io.MQAddress.<init>()V from class com.sun.messaging.jmq.management.JMXMQAddress

              I am really in a dead end here, would appreciate any help.

              Thanks,
              Oscar
              • 4. Re: Help creating a queue using JMX
                Nigeldeakin-Oracle
                The JMS specification does not define a management API. The JMX APIs offered by both ActiveMQ and Open Message Queue are nonstandard and different.

                Nigel
                • 5. Re: Help creating a queue using JMX
                  Nigeldeakin-Oracle
                  First of all check your JMX URL. This is logged by the broker at startup. Look for an entry like:

                  [15/Nov/2010:10:47:26 GMT] JMX Connector Server jmxrmi started successfully with url service:jmx:rmi://mycomputer/jndi/rmi://12.345.6.7:1099/12.345.6.7/7676/jmxrmi
                  (assuming you specified the -startRmiRegistry option when you started the broker)

                  I took your example, changed the user/password to admin/admin (which are the defaults), corrected the URL, and it worked just fine for me (it created the queue).

                  There are some tips on working out the correct JMX URL on the Open MQ Wiki
                  http://wikis.sun.com/display/GlassFish/OpenMQJMXQuestions

                  However I would recommend using the AdminConnectionFactory API as it saves you the burden of having to work out the correct JMX URL. Make sure you have imqjmx.jar on your classpath. If you see that exception again, please give the full stack trace.

                  Nigel
                  • 6. Re: Help creating a queue using JMX
                    811624
                    Hi,
                    Thanks a lot for your help!
                    I thought that using JMX I could be able to handle ActiveMQ and OpenMQ transparently.

                    About the JMX URL:
                    I will tell step-by-step what I did.
                    I started the server using the startserver.bat that is found in glassfishv3\glassfish\bin directory
                    It output the line

                    [#|2010-11-15T13:59:58.310+0100|INFO|glassfish3.0.1|javax.enterprise.system.tools.admin.org.glassfish.server|_ThreadID=19;_ThreadName=Thread-18;|JMXStartupService: Started JMXConnector, JMXService URL = service:jmx:rmi://IAI82180.tis:8686/jndi/rmi://IAI82180.tis:8686/jmxrmi|#]

                    I copied and pasted the URL in my code and tried to run it. Got the same error ( Exception in thread "main" javax.management.InstanceNotFoundException: com.sun.messaging.jms.server:type=DestinationManager,subtype=Config ). I tried to change the user and pass to admin/admin and got the same error.


                    Then I tried to use the AdminConnectionFactory, here is my code (I copied from the website you gave me):

                    public static void main(String[] args) throws Exception {
                    testAdminConnectionFactory();
                    }

                    public static void testAdminConnectionFactory()
                         {
                              try
                    { //  Create admin connection factory
                    AdminConnectionFactory acf = new AdminConnectionFactory();

                    // Get JMX connector, supplying user name and password
                    JMXConnector jmxc = acf.createConnection("admin", "admin");

                    // Get MBean server connection
                    MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

                    // Create object name
                    ObjectName destMgrConfigName
                    = new ObjectName(MQObjectName.DESTINATION_MANAGER_CONFIG_MBEAN_NAME);


                    // Create operation's parameter and signature arrays

                    Object opParams[] = { DestinationType.QUEUE,
                    "MyQueue"
                    };

                    String opSig[] = { String.class.getName(),
                    String.class.getName()
                    };

                    // Invoke operation
                    mbsc.invoke(destMgrConfigName, DestinationOperations.CREATE, opParams, opSig);

                    // Close JMX connector
                    jmxc.close();
                    }

                    catch (Exception e)
                    { System.out.println( "Exception occurred: " + e.toString() );
                    e.printStackTrace();
                    }
                         }

                    But I still get the error, even though I have the lib imqjmx.jar added to my project and to my buildpath

                    Exception in thread "main" java.lang.IllegalAccessError: tried to access method com.sun.messaging.jmq.io.MQAddress.<init>()V from class com.sun.messaging.jmq.management.JMXMQAddress
                         at com.sun.messaging.jmq.management.JMXMQAddress.<init>(JMXMQAddress.java:48)
                         at com.sun.messaging.jmq.management.JMXMQAddress.createAddress(JMXMQAddress.java:60)
                         at com.sun.messaging.AdminConnectionFactory.getJMXServiceURL(AdminConnectionFactory.java:257)
                         at com.sun.messaging.AdminConnectionFactory.createConnection(AdminConnectionFactory.java:207)
                         at Test.testAdminConnectionFactory(Test.java:242)
                         at Test.main(Test.java:29)

                    Edited by: 808621 on 15/Nov/2010 5:13
                    • 7. Re: Help creating a queue using JMX
                      Nigeldeakin-Oracle
                      [#|2010-11-15T13:59:58.310+0100|INFO|glassfish3.0.1|javax.enterprise.system.tools.admin.org.glassfish.server|_ThreadID=19;_ThreadName=Thread-18;|JMXStartupService: Started JMXConnector, JMXService URL = service:jmx:rmi://IAI82180.tis:8686/jndi/rmi://IAI82180.tis:8686/jmxrmi|#]
                      Ah, that explians it. This URL is being logged by the GlassFish instance rather than the MQ broker. So you were connecting to the GlassFish MBeanServer, not the broker's which explains why you got "object not found".

                      Look in the MQ broker log. This is something like glassfish/domains/domain1/imq/instances/imqbroker/log/log.txt, and the JMX startup message is of the form

                      [15/Nov/2010:10:47:26 GMT] JMX Connector Server jmxrmi started successfully with url service:jmx:rmi://mycomputer/jndi/rmi://12.345.6.7:1099/12.345.6.7/7676/jmxrmi

                      As for the other error: the class com.sun.messaging.jmq.io.MQAddress is in imq.jar. Is this in the classpath as well? Are you certain that you are using the same version of all jars?

                      Nigel
                      • 8. Re: Help creating a queue using JMX
                        811624
                        Hi,
                        regarding the AdminConnectionFactory, there was a progress. I added the imq.jar lib, it showed some improvement, but there is a small problem: the error I get is

                        Exception occurred: javax.management.JMException: No JMXServiceURL was found for connector jmxrmi.
                        Address used: mq://localhost:7676/jmxrmi
                        javax.management.JMException: No JMXServiceURL was found for connector jmxrmi.
                        Address used: mq://localhost:7676/jmxrmi
                             at com.sun.messaging.AdminConnectionFactory.getJMXServiceURL(AdminConnectionFactory.java:303)
                             at com.sun.messaging.AdminConnectionFactory.createConnection(AdminConnectionFactory.java:207)
                             at Test.testAdminConnectionFactory(Test.java:242)
                             at Test.main(Test.java:29)

                        I need to inform somehoe the JMXServiceURL, which takes me to the first question.

                        I looked at the log, but it is not updated since Nov 12., which is pretty strange. I tried to use the JMX from Nov. 12. but it didn't work out. I am now trying to find out to why it isn't writing on the log.
                        I tried to execute the following commands:
                        asaadmin startdomain in glassfishv3\bin
                        startserv.bat in glassfishv3\glassfish\bin
                        imqbrokerd.exe in Sun\MessageQueue\bin

                        But it is not working. I am doing some research at the moment, just to keep you up to date :)

                        thanks!
                        • 9. Re: Help creating a queue using JMX
                          Nigeldeakin-Oracle
                          If you're using GlassFish (the application server), use "asadmin start-domain" to start the GlassFish instance. The MQ broker will be started lazily when you try to deploy or start an application that uses JMS, or when you try to create a JMS (not JMX) connection to it.
                          • 10. Re: Help creating a queue using JMX
                            811624
                            Hi,
                            Just to get back to you: I am still looking for it. I could start the broker by pinging it in the admin console. Actually, the page that helped me doing that was your blog http://openmessaging.blogspot.com/2009/08/how-to-set-arbitrary-broker-properties.html :D

                            The log I got was: [16/Nov/2010:09:30:58 MEZ] JMX Connector Server jmxrmi started successfully with url service:jmx:rmi://IAI82180/jndi/rmi://IAI82180.tis:8686/IAI82180.tis/7878/jmxrmi

                            I am getting the following exception when I try to use the JMXConnectionFactory

                            Exception in thread "main" java.rmi.UnmarshalException: java.lang.ClassNotFoundException: org.apache.activemq.store.kahadb.data.KahaDestination$DestinationType (no security manager: RMI class loader disabled); nested exception is:
                                 java.lang.ClassNotFoundException: org.apache.activemq.store.kahadb.data.KahaDestination$DestinationType (no security manager: RMI class loader disabled)
                                 at javax.management.remote.rmi.RMIConnectionImpl.unwrap(RMIConnectionImpl.java:1525)
                                 at javax.management.remote.rmi.RMIConnectionImpl.unwrap(RMIConnectionImpl.java:1559)
                                 at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:771)
                                 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:597)
                                 at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
                                 at sun.rmi.transport.Transport$1.run(Transport.java:159)
                                 at java.security.AccessController.doPrivileged(Native Method)
                                 at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
                                 at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
                                 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
                                 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
                                 at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                                 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                                 at java.lang.Thread.run(Thread.java:619)
                            Caused by: java.lang.ClassNotFoundException: org.apache.activemq.store.kahadb.data.KahaDestination$DestinationType (no security manager: RMI class loader disabled)
                                 at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:375)
                                 at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
                                 at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
                                 at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
                                 at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197)
                                 at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1575)
                                 at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
                                 at java.io.ObjectInputStream.readEnum(ObjectInputStream.java:1686)
                                 at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1326)
                                 at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1667)
                                 at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1323)
                                 at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
                                 at java.rmi.MarshalledObject.get(MarshalledObject.java:142)
                                 at javax.management.remote.rmi.RMIConnectionImpl.unwrap(RMIConnectionImpl.java:1523)

                            And this one when trying the AdminConnectionFactory

                            javax.management.JMException: No JMXServiceURL was found for connector jmxrmi.
                            Address used: mq://localhost:7676/jmxrmi
                            Exception occurred: javax.management.JMException: No JMXServiceURL was found for connector jmxrmi.
                            Address used: mq://localhost:7676/jmxrmi
                                 at com.sun.messaging.AdminConnectionFactory.getJMXServiceURL(AdminConnectionFactory.java:303)
                                 at com.sun.messaging.AdminConnectionFactory.createConnection(AdminConnectionFactory.java:207)
                                 at Test.testAdminConnectionFactory(Test.java:242)
                                 at Test.main(Test.java:29)

                            I am looking for the reason for both of them in google :)


                            Edit: I just noticed: activemq class? I have no ideia from where it came from, I am reviewing my libs again :(

                            Edit2: Just managed to connect! :) Now I am trying to add the queue, I am getting this error

                            Exception in thread "main" javax.management.MBeanException: Exception caught while invoking operation create in MBean DestinationManagerConfig
                                 at com.sun.messaging.jmq.jmsserver.management.mbeans.MQMBeanReadOnly.invoke(MQMBeanReadOnly.java:215)
                                 at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836)
                                 at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761)
                                 at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1427)
                                 at javax.management.remote.rmi.RMIConnectionImpl.access$200(RMIConnectionImpl.java:72)
                                 at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1265)
                                 at java.security.AccessController.doPrivileged(Native Method)
                                 at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1367)
                                 at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:788)
                                 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:597)
                                 at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
                                 at sun.rmi.transport.Transport$1.run(Transport.java:159)
                                 at java.security.AccessController.doPrivileged(Native Method)
                                 at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
                                 at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
                                 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
                                 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
                                 at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                                 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                                 at java.lang.Thread.run(Thread.java:619)
                                 at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
                                 at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
                                 at sun.rmi.server.UnicastRef.invoke(Unknown Source)
                                 at com.sun.jmx.remote.internal.PRef.invoke(Unknown Source)
                                 at javax.management.remote.rmi.RMIConnectionImpl_Stub.invoke(Unknown Source)
                                 at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.invoke(Unknown Source)
                                 at Test.createQueue(Test.java:227)
                                 at Test.main(Test.java:30)

                            Edit3: I took a look in the log file and solved it.
                            Thanks a lot for your help, it is running now!

                            Edited by: 808621 on 16/Nov/2010 0:40

                            Edited by: 808621 on 16/Nov/2010 0:49

                            Edited by: 808621 on 16/Nov/2010 0:55

                            Edited by: 808621 on 16/Nov/2010 0:57