After migrating from Java 8 to Java 11, our internal code that allowed jmx / jconsole no longer worked. Following the Java 11 guidelines using the standard config / password files, I got things working, however, I do not want to allow local access.
More specifically, I want to force authentication.
Here is the code that worked fine with Java 8. It does not fail with Java 11, but jconsole cannot connect.
InetAddress bindIpAddress = InetAddress.getByName(hostname);
String jmxUrl = JmxUtils.createJmxServerUrl(bindIpAddress, port);
System.setProperty("java.rmi.server.randomIDs", "true");
System.setProperty("java.rmi.server.hostname", bindIpAddress.getHostAddress());
logger.info("Starting JMX connectorServer.");
try {
final SSLContext sslContext = initializeSslContext();
final HashMap<String, Object> env = new HashMap<>();
final RMIServerSocketFactory serverSocketFactory = new GridServerSocketFactory();
registry = LocateRegistry.createRegistry(port, null, serverSocketFactory);
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, new SslRMIServerSocketFactory(sslContext, null, null, false));
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, new SslRMIClientSocketFactory());
env.put("jmx.remote.authenticator", JmxUtils.createUserAuthenticator(user, password));
connectorServer = new RMIConnectorServer(
new JMXServiceURL(jmxUrl),
env,
ManagementFactory.getPlatformMBeanServer());
connectorServer.start();
running = true;
}
catch (IOException|GeneralSecurityException e) {
logger.error("Exception starting JMX connectorServer", e);
}
To get it to work, I just added this to where we start the JVM, with a different port than the code above uses:
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=25943
-Dcom.sun.management.jmxremote.local.only=false
That allows me to connect (though lacking the internal SSL config we had before) either locally without any authentication, or remotely with authentication.
I have not been able to find a way to disable local access, and local access gives full privileges to jconsole. If I could disable local access, allowing only remote access, that would be help immensely....but how? It is easily configurable for local-only, but I sure can't find anything documented for remote-only.
OR maybe better, is there something I need to add to the original code (that worked with Java 8) to get that to work with Java 11? This would be more ideal.
UPDATE (2023-08-08): The Java-11 JDK doesn't include a jconsole.jar, which is why I went down this path and ran into the above "local access" issues with jconsole.exe. I just discovered, however, that if I simply use the jconsole.jar that's in the Java-8 jdk, everything works fine under Java-11 with our original code. Zero changes. I think that is the route I'm going to take, but, does anyone know why jconsole.jar stopped being included in the JDK in 11, when it was present in 8? (FWIW, we're using Azul.)