Programmatically enabling remote jmx monitoring
java, jmx, spring-jmx
Solution
Since you are already using Spring I think you should see if using a `ConnectorServerFactoryBean` can do what you are looking to do. I've never had to start a remote JMX server but it looks like that's what that object can do for you.
Problem
I am attempting to enable my core java application for remote accessibility via JMX. However, two restrictions are making it harder than it should be. a) I am not at the liberty to change the script which starts the app on the linux box. Therefore, I cannot pass any of the "jmxremote" parameters to the jvm. b) It is very possible that the remote port ( `com.sun.management.jmxremote.port = xxxx` ) I specify is not open and I cannot modify the script to try another open port. I must do it automatically. I tried to get around these restrictions by writing a class with would set all the required jmxremote params as well as find a "free" port. ``` public class JmxRemoteConnectionHelper{ @Override public void init( ) throws Exception{ InetAddress address = InetAddress.getLocalHost(); String ipAddress = address.getHostAddress(); String hostname = address.getHostName(); String port = String.valueOf( getFreePort( ) ); System.setProperty("java.rmi.server.hostname", ipAddress ); System.setProperty("com.sun.management.jmxremote", "true" ); System.setProperty("com.sun.management.jmxremote.authenticate", "false" ); System.setProperty("com.sun.management.jmxremote.ssl", "false" ); System.setProperty("com.sun.management.jmxremote.port", port ); } private final int getFreePort( ){ **//seedPort is passed in the constructor** int freePort = seedPort; ServerSocket sSocket = null; for( int i=ZERO; i<PORT_SCAN_COUNTER; i++ ){ try{ freePort = freePort + i; sSocket = new ServerSocket( freePort ); //FOUND a free port. break; }catch( Exception e ){ //Log }finally{ if( sSocket != null ){ try{ sSocket.close(); sSocket = null; }catch(Exception e ){ //Log } } } } return freePort; } } ``` As shown below, I, then initialize it via spring. ``` <bean id="JmxRemoteConnection" class="JmxRemoteConnectionHelper" init-method="init" /> <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean" depends-on="JmxRemoteConnection" /> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false" > <property name="assembler" ref="assembler"/> <property name="namingStrategy" ref="namingStrategy"/> <property name="autodetect" value="true"/> <property name="server" ref="mbeanServer"/> </bean> <bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/> <bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler"> <property name="attributeSource" ref="jmxAttributeSource"/> </bean> <bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy" lazy-init="true"> <property name="attributeSource" ref="jmxAttributeSource"/> </bean> ``` To test, I start the app on my windows machine. It starts up correctly. However, when I bring up JConsole on the same box and try to connect via "remote process" (ip:port), I get a "connection refused" message at the bottom. My suspicion is that the JMX agent is not seeing any of the remote system properties that I am setting. I am using JDK 1.6.