【问题标题】:Discovering JMX Ephemeral Port Number for Java 9+发现 Java 9+ 的 JMX 临时端口号
【发布时间】:2020-07-10 09:28:18
【问题描述】:

这个问题:When using a JMX server with ephemeral port, how to get the server port number? 表示我们可以使用 sun.management.ConnectorAddressLink 和指定的参数来发现临时 JMX 端口(如果我们以 com.sun.management.jmxremote.port=0 开始我们的进程)。

但是对于 Java 9+,这些类是私有的并且不能再被访问。有什么方法可以通过编程方式找到 JMX 绑定到的端口?

【问题讨论】:

  • 这个问题有一个赏金+宽限期,我在赏金到期之前发布了一个答案。我希望赏金将在提交日期时间获得基础。

标签: java jmx


【解决方案1】:

ConnectorAddressLink 类可以通过 jdk.internal.agent 模块调用。

下面的示例代码展示了我们如何以编程方式在 java 9/11/14 中找到 JMX 临时端口(仅使用 OpenJDK 版本测试)。

Java 9+ 代码:

在下面的代码中,您可以获取 PID 或使用 0 来表示当前 PID,因此提供了一种在两种情况下显示 JMX URL 的方法,它们将是相同的。

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

*模块和 JMX 的 Java 9+ VM 参数

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

编程愉快。

【讨论】:

    猜你喜欢
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    • 2012-05-07
    • 1970-01-01
    • 2015-08-17
    • 2019-04-12
    • 1970-01-01
    相关资源
    最近更新 更多