I have a code to connect to the ActiveMQ Artemis broker via the JMX protocol using some kind of login/password authorization
public static MBeanServerConnection connectBroker(String brokerUrl, String user, String password) {
QueueConnection connection = null;
try {
QueueConnectionFactory cf = new ActiveMQQueueConnectionFactory(brokerUrl);
connection = cf.createQueueConnection();
connection.start();
HashMap env = new HashMap();
String[] creds = {user, password};
env.put(JMXConnector.CREDENTIALS, creds);
JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(BuildGet.JMX_URL),env);
return connector.getMBeanServerConnection();
} catch (JMSException | IOException e) {
throw new RuntimeException(e);
}
}
And this code gives these errors:
Caused by: java.lang.RuntimeException: javax.jms.JMSException: Failed to create session factory
at jmxClientUIPConsole.BuildGet.connectBroker(BuildGet.java:81)
at jmxClientUIPConsole.gui.DConsoleFrameController.connectBroker(DConsoleFrameController.java:41)
... 56 more
Caused by: javax.jms.JMSException: Failed to create session factory
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:867)
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createQueueConnection(ActiveMQConnectionFactory.java:335)
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createQueueConnection(ActiveMQConnectionFactory.java:331)
at jmxClientUIPConsole.BuildGet.connectBroker(BuildGet.java:72)
... 57 more
Caused by: ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ219007: Cannot connect to server(s). Tried with all available servers.]
at org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:701)
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:865)
... 60 more
But if you make a method without authorization then everything works:
public static MBeanServerConnection connectBroker(String brokerUrl) {
QueueConnection connection = null;
try {
QueueConnectionFactory cf = new ActiveMQQueueConnectionFactory(brokerUrl);
connection = cf.createQueueConnection();
connection.start();
JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(BuildGet.JMX_URL));
return connector.getMBeanServerConnection();
} catch (JMSException | IOException e) {
throw new RuntimeException(e);
}
}
Here is my management.xml
:
<management-context xmlns="http://activemq.apache.org/schema">
<connector connector-port="13682" connector-host="192.168.1.135"/>
<authorisation>
<allowlist>
<entry domain="hawtio"/>
</allowlist>
<default-access>
<access method="list*" roles="view,update,amq,guest,test"/>
<access method="get*" roles="view,update,amq,guest,test"/>
<access method="is*" roles="view,update,amq,guest,test"/>
<access method="set*" roles="update,amq,guest,test"/>
<access method="*" roles="amq,guest,test"/>
</default-access>
<role-access>
<match domain="org.apache.activemq.artemis">
<access method="list*" roles="view,update,amq,guest,test"/>
<access method="get*" roles="view,update,amq,guest,test"/>
<access method="is*" roles="view,update,amq,guest,test"/>
<access method="set*" roles="update,amq,guest,test"/>
<access method="*" roles="amq,guest,test"/>
</match>
</role-access>
</authorisation>
</management-context>
I pass the login amq
and password amq
to the method. Maybe I'm passing the wrong login and password? Why can an error occur when connecting to a broker?
Now the method looks like this:
public static MBeanServerConnection connectBroker(String brokerUrl, String user, String password) {
try {
Map<String, String[]> env = new HashMap();
String[] creds = {user, password};
env.put(JMXConnector.CREDENTIALS, creds);
JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + brokerUrl + ":13682/jmxrmi"), env);
return connector.getMBeanServerConnection();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
But if I leave login and password empty, then for some reason it can connect, although I left these authorization fields empty for the test. Why isn't an error thrown when the field data is empty?
The stack-trace indicates that the exception is coming from your invocation of javax.jms.QueueConnectionFactory.createQueueConnection()
so it doesn't appear to have anything to do with your JMX connection. The exception is being thrown before it even gets to JMXConnectorFactory.connect()
.
It's important to note that this connectBroker
method is leaking a JMS connection every time it is invoked (assuming it is successful). This is because you create a JMS connection, but you don't close it or return it from the method. I recommend removing the JMS connection from that method entirely as it servers no real purpose.