2016-03-29 42 views
2

我有一些代码连接到JMX并获取mBean的名称。现在我正在用JUnit编写测试。我已经做了一些测试,没有认证使用这样的事情:运行时设置JMX的JVM参数

private static void startJmxServer() throws Exception { 
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 

    LocateRegistry.createRegistry(PORT); 

    JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + HOST + ':' + PORT + "/jmxrmi"); 
    JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); 

    Example exampleMBean = new Example(); 
    ObjectName exampleName = new ObjectName(MBEAN_NAME); 

    mbs.registerMBean(exampleMBean, exampleName); 

    connectorServer.start(); 
} 

现在我想做一些测试与身份验证。所以,我需要指定下一个JVM性的判定:

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=1234 
-Dcom.sun.management.jmxremote.authenticate=true 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.access.file=/somepath/jmxremote.access 
-Dcom.sun.management.jmxremote.password.file=/somepath/jmxremote.password 

我已经尝试过在JMXConnectorServer环境变量通过这个特性。我也试过System.setProperty。但是失败了,因为连接没有任何凭据。 的唯一途径,这使得它的工作是:

private static void startJmxServer() throws Exception { 
    String name = ManagementFactory.getRuntimeMXBean().getName(); 
    VirtualMachine vm = VirtualMachine.attach(name.substring(0, name.indexOf('@'))); 

    String lca = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress"); 

    if (lca == null) { 
     Path p = Paths.get(System.getProperty("java.home")).normalize(); 

     if (!"jre".equals(p.getName(p.getNameCount() - 1).toString() 
      .toLowerCase())) { 
      p = p.resolve("jre"); 
     } 

     File f = p.resolve("lib").resolve("management-agent.jar").toFile(); 

     if (!f.exists()) { 
      throw new IOException("Management agent not found"); 
     } 

     String options = String.format("com.sun.management.jmxremote.port=%d, " + 
      "com.sun.management.jmxremote.authenticate=true, " + 
      "com.sun.management.jmxremote.ssl=false, " + 
      "com.sun.management.jmxremote.access.file=/somepath/jmxremote.access, " + 
      "com.sun.management.jmxremote.password.file=/somepath/jmxremote.password", PORT); 
     vm.loadAgent(f.getCanonicalPath(), options); 
    } 

    vm.detach(); 

    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 

    Example exampleMBean = new Example(); 

    ObjectName exampleName = new ObjectName(MBEAN_NAME); 
    mbs.registerMBean(exampleMBean, exampleName); 
} 

但作为代理加载我不能改变虚拟机性能不authentication.Also运行测试,我想避免这种类的事情,因为需要在手动定义tools.jar并希望使用常见的JMX工具。任何想法如何管理?

回答

2

认证配置在environment中传递 - 第二个参数为JMXConnectorServerFactory.newJMXConnectorServer

HashMap<String, Object> env = new HashMap<>(); 
    env.put("jmx.remote.x.password.file", "/somepath/jmxremote.password"); 
    env.put("jmx.remote.x.access.file", "/somepath/jmxremote.access"); 

    JMXConnectorServer connectorServer = 
     JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); 

请注意,此处的属性名称与属性名称不同。

从JDK源查看ConnectorBootstrap.java以查看默认JMXConnectorServer是如何初始化的。

+0

非常感谢!你让我很快乐!我试图在Environment属性中使用相同的属性名称。但现在一切正常,如预期一样。 –