I'm developing collection of monitoring script and templates for zabbix. It's called ZTC and all script are on python.
Now I want to add support for some java monitoring. I've not found the way to do it from CPython - only from java or jython. Since all project is on python, I've decided to write a simple script on jython, which would be called from my cpython classes.
Here is how my code looks like:
#!/usr/bin/env jython
#Java Dependencies
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.lang.management.ManagementFactory;
#Python Dependencies
import sys, cmd, socket
def usage():
print """Usage:
jmxclient.py -h
jmxclient.py <connect_url> <jmx_attribute_path> <jmx_property>"""
class JMXClient:
remote = None
def connect(self, connect_url):
if self.remote:
return True
#Establish Connection to JMX Server
url = javax.management.remote.JMXServiceURL(connect_url);
connector = javax.management.remote.JMXConnectorFactory.connect(url);
self.remote = connector.getMBeanServerConnection();
def getAttribute(self, mbean_path, attribute):
"""Query the mbean server for a specific attribute and return the
result"""
obn = javax.management.ObjectName(mbean_path);
result = self.remote.getAttribute(obn, attribute);
return result
if len(sys.argv) <= 1:
usage()
sys.exit(2)
if sys.argv[1] in ('-h', '--help'):
usage()
sys.exit(2)
if len(sys.argv) <> 4:
usage()
sys.exit(2)
(connect_url, mbean_path, attribute) = sys.argv[1:]
j = JMXClient()
j.connect(connect_url)
print j.getAttribute(mbean_path, attribute)
Ok, now I'm trying to get some attribute from terracotta server. It uses jmxmp with url service:jmx:jmxmp://0.0.0.0:9520.
So, I'm running my script as follows:
$ ./jmxclient.py service:jmx:jmxmp://localhost:9520 java.lang.ClassLoading LoadedClassCount
Traceback (innermost last):
File "./jmxclient.py", line 87, in ?
File "./jmxclient.py", line 61, in connect
at javax.management.remote.JMXConnectorFactory.newJMXConnector(JMXConnectorFactory.java:327)
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:247)
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:207)
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)
java.net.MalformedURLException: java.net.MalformedURLException: Unsupported protocol: jmxmp
(line numbers not relevant due to some stripped comments)
How do I add support of this jmxmp protocol?
I've found that it seems it might be enabled by jmxremote_optional.jar. How do I add this jar to my jython (pref. not system-wide)?
UPDATE:
As suggested, I've added jmxremote_optional.jar and jmxremote.jar from jmxremote-1_0_1-ri-bin-b58.zip
reference implementation: jython -Djava.endorsed.dirs=. -Dpython.path=.../jmxremote_optional.jar:.../jmxremote.jar:.../jmissl.jar jmxclient.py service:jmx:jmxmp://localhost:9520 java.lang.ClassLoading LoadedClassCount
, but still getting the same error. I'm sure that jmxremote_optional.jar is in classpath, and code seems to be very similar to reference examples.
After reading api docs, I've tried following changes:
url = javax.management.remote.JMXServiceURL('jmxmp', 'localhost', 9520);
connector = javax.management.remote.jmxmp.JMXMPConnector(url)
connector.connect()
self.remote = connector.getMBeanServerConnection();
which leads me to another exception:
Traceback (innermost last):
File "../src/jmxclient.py", line 87, in ?
File "../src/jmxclient.py", line 61, in connect
at com.sun.jmx.remote.opt.security.AdminClient.connectionOpen(AdminClient.java:209)
at com.sun.jmx.remote.generic.ClientSynchroMessageConnectionImpl.connect(ClientSynchroMessageConnectionImpl.java:72)
at javax.management.remote.generic.GenericConnector.connect(GenericConnector.java:177)
at javax.management.remote.jmxmp.JMXMPConnector.connect(JMXMPConnector.java:119)
at javax.management.remote.generic.GenericConnector.connect(GenericConnector.java:124)
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)
java.io.IOException: java.io.IOException: javax.management.remote.message.HandshakeBeginMessage
Jython version is 2.2 and I don't like to use later version, because this scripts is mostly being used on RHEL5 boxes, and they only have jython 2.2.1.
PS: marking question as answered, because I've decided to give up and use jmxterm or similar tool, which all seems to work with jmxmp by just adding -Djava.endosed.dirs=/path/to/dir_with_jmxremote_optional/. But I'd still like to see jython solution.