2016-03-29 3 views
2

У меня есть код, соединяющий JMX и получение mBean по имени. Теперь я пишу тесты с JUnit для этого. Я уже провел некоторые тесты без проверки подлинности, используя что-то вроде этого:Параметры времени выполнения JVM аргументы для JMX

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

Обратите внимание, что имена атрибутов здесь отличаются от имен свойств.

Проконсультируйтесь с ConnectorBootstrap.java из источников JDK, чтобы узнать, как инициализируется по умолчанию JMXConnectorServer.

+0

Большое вам спасибо! Ты сделал мой день! Я пытался использовать те же имена свойств в атрибутах среды. Но теперь все работает так, как ожидалось. –