Обнаружение номера эфемерного порта JMX для Java 9+ - PullRequest
7 голосов
/ 10 июля 2020

Этот вопрос: При использовании JMX-сервера с эфемерным портом, как получить номер порта сервера? указывает, что мы можем использовать sun.management.ConnectorAddressLink с указанными параметрами для обнаружения эфемерного порта JMX (если мы начните наш процесс с com.sun.management.jmxremote.port=0).

Однако для Java 9+ эти классы были сделаны частными и больше не доступны. Есть ли способ найти программно, к какому порту привязан JMX?

1 Ответ

1 голос
/ 20 июля 2020

Класс ConnectorAddressLink можно вызвать через модуль jdk.internal.agent.

Ниже приведен пример кода, показывающий, как мы можем программно найти эфемерный порт JMX в java 11.09.14 (протестировано только с версиями OpenJDK) .

Java 9+ Код:

В приведенном ниже коде вы можете получить PID или использовать 0 для обозначения текущего PID, тем самым обеспечивая способ показать URL-адрес JMX в обоих сценариях ios, и они будут идентичны.

public class JMXEphemeralPortTest_JAVA9Plus {

  public static void main(String[] args) throws IOException {
    String jmxURL = "NO JMX URL";
    String jmxURL2 = "NO JMX URL";
    if (isJava9Plus(System.getProperties())) {
      long pid = ProcessHandle.current().pid();
      jmxURL = "From Java 9 Plus:-->" + importRemoteFrom_Java9Plus(Math.toIntExact(pid));
      jmxURL2 = "From Java 9 Plus:-->" + importRemoteFrom_Java9Plus(0);
    }
    System.out.println(jmxURL);
    System.out.println(jmxURL2);
  }
  private static boolean isJava9Plus(Properties properties) {
    double javaVersion = Double.parseDouble(properties.getProperty("java.specification.version"));
    System.out.println("Java Version:"+javaVersion);
    return javaVersion >= 1.9;
  }
  private static String importRemoteFrom_Java9Plus(int pid) {
    try {
      final Class<?> clazz = Class.forName("jdk.internal.agent.ConnectorAddressLink");
      final Method method = clazz.getMethod("importRemoteFrom", int.class);
      final Object instance = clazz.getDeclaredConstructor().newInstance();
      Map<String, String> map = (Map<String, String>) method.invoke(instance, pid);
      return map.get("sun.management.JMXConnectorServer.0.remoteAddress");
    } catch (Exception e) {
      throw new IllegalStateException("Could not load needed java 9+ class", e);
    }
  }
}

*Java 9+ Аргументы ВМ для модуля и JMX :

--add-modules jdk.management,jdk.management.agent
--add-exports=jdk.management.agent/jdk.internal.agent=ALL-UNNAMED
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=0
-Dcom.sun.management.jmxremote.local.only=false

Java 9+ Результат:

Java Версия: 14.0 От Java 9 Plus: -> сервис: jmx: rmi: /// jndi / rmi: // XXXX: 50678 / jmxrmi От Java 9 Plus: -> service: jmx: rmi: /// jndi / rmi: // XXXX: 50678 / jmxrmi

Java Версия: 9.0 От Java 9 Plus: -> service: jmx: rmi: /// jndi / rmi: // XXXX: 60342 / jmxrmi От Java 9 Plus: -> service: jmx: rmi: /// jndi / rmi: // XXXX: 60342 / jmxrmi

Удачного программирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...