Remote management using Java Management Extensions (JMX) is possible in executables built with GraalVM Native Image. This demo shows how to build, run, and interact with such a native executable using JMX. It also shows you how to register a custom managed bean (MBean) with the JMX server and the additional steps required for it to work with Native Image.
Note: This demo works with GraalVM for JDK 17 and later.
-
Download and install the latest GraalVM JDK using SDKMAN!.
sdk install java 21.0.1-graal
-
Download the demos repository or clone it as follows:
git clone https://github.com/graalvm/graalvm-demos
cd graalvm-demos/native-image-jmx-demo
Compile the SimpleJmx.java using the GraalVM JDK:
$JAVA_HOME/bin/javac SimpleJmx.java
This creates SimpleJmx.class
, SimpleJmx$Simple.class
, and SimpleJmx$SimpleMBean.class
files.
The main()
method in SimpleJmx.java registers a custom MBean, then loop endlessly, so you have time to inspect the process using VisualVM.
JMX uses dynamic proxies to access MBeans. To be able to interact with the custom SimpleMBean
at run time, you need to provide Native Image with additional dynamic proxy configuration for the MBean interface. For this, you can see a JSON file in a working directory named proxy-config.json with the following contents:
[
{ "interfaces": [ "SimpleJmx$SimpleMBean"] }
]
In the next step, you will pass this JSON file to the native-image
builder.
Build a native executable with VM monitoring enabled:
$JAVA_HOME/bin/native-image --enable-monitoring=jmxserver,jmxclient,jvmstat -H:DynamicProxyConfigurationFiles=proxy-config.json SimpleJmx
The --enable-monitoring=jmxserver
option enables the JMX Server feature which allows accepting incoming connections.
The --enable-monitoring=jmxclient
option enables the JMX Client feature which allows making outgoing connections.
Both features can be used together, comma-separated, for example, --enable-monitoring=jmxserver,jmxclient
.
The jvmstat
option should also be included if you want to enable discovery by VisualVM and other JVMs: --enable-monitoring=jmxserver,jmxclient,jvmstat
.
Now run your native executable with JMX properties:
./simplejmx -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=9996 -Dcom.sun.management.jmxremote.ssl=false
This starts the application as a simple JMX server, without password authentication or SSL using port 9996
.
You can configure JMX to apply all the usual properties as shown in this guide, but this example uses a basic configuration for simplicity.
-
Install and open VisualVM to view the managed beans in a user-friendly way.
-
Make sure you have the VisualVM-MBeans plugin installed (go to Tools, then Plugins, under Available Plugins, select "VisualVM-MBeans", and click Install).
-
Go to the Applications tab and select the SimpleJmx process. From there you can select the MBeans tab.
-
In the MBeans tab, you can inspect the custom MBean you created earlier and perform operations on it.
To conclude, Native Image now provides support for remote management using JMX. Users can enable the JMX agent in a native executable to monitor a client application running on a remote system.