2013-03-22 32 views
2

我正在尝试启用我的核心Java应用程序以通过JMX实现远程访问。然而,两个限制使它比应该更难。以编程方式启用远程jmx监控

a)我不能随意更改启动Linux机器上应用程序的脚本。因此,我无法将任何“jmxremote”参数传递给jvm。

b)我指定的远程端口(com.sun.management.jmxremote.port = xxxx)很可能未打开,我无法修改脚本以尝试另一个打开的端口。我必须自动执行。

我试图通过编写一个类来设置所有必需的jmxremote参数以及找到一个“空闲”端口来解决这些限制。

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; 
    } 

} 

如下图所示,我通过弹簧初始化它。

<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> 

为了测试,我在我的Windows机器上启动应用程序。它启动正确。但是,当我在相同方框上尝试通过“远程进程”(ip:port)调用JConsole时,我得到一个“连接被拒绝”消息在底部。

我怀疑JMX代理没有看到我设置的任何远程系统属性。任何想法,提示等将不胜感激。

我正在使用JDK 1.6

回答

3

既然你已经在使用Spring,我想你应该看看如果使用ConnectorServerFactoryBean可以做你正在做的事情。我从来不需要启动远程JMX服务器,但看起来这就是那个对象可以为你做的事情。

+0

谢谢,ConnectorServerFactoryBean的确是我所需要的。 – CaptainHastings 2013-03-22 15:28:51