How to connect to JMX server running inside WSL2
Asked Answered
P

4

6

I'm running my Java application with the following parameters that enable JMX server's remote connections:

-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=9998
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

I can successfully connect to that JMX server via VisualVM by adding a new JMX Connection to address: <HOSTNAME>:9998

But when i run that application inside Windows Subsystem for Linux 2 (WSL2) Visual VM cannot connect to localhost:9998: connection failed

For what I know, every port that the application is listening on in WSL2 is also opened in host machine (Windows itself), and I can check that using Win+R -> cmd -> telnet localhost 9998 (connected successfully). Also, I'm running an nginx instance inside WSL2 that I can connect to by any browser on my host machine (Windows) using localhost.

Percaline answered 16/2, 2021 at 10:33 Comment(0)
P
5

I wasn't able to get Windows jconsole to connect to a JVM running in WSL2 using any of the suggestions above, however it is now possible to run Linux jconsole in WSL2, using Windows 11's Linux GUI support. Works perfectly.

Panathenaea answered 26/7, 2021 at 16:24 Comment(1)
Do you mean this? Run Linux GUI apps on the Windows Subsystem for LinuxValladares
T
3

I had the same problem and finally I found a working set of properties for my WSL2. Additionally I had additional requirement to set it up for docker container running inside WSL2, while JConsole/VisualVM was running on Windows host. I have also a VPN running which probably mess up networking even more.

I found this application https://github.com/cluther/jmx-tester to be useful in debugging the connection.

inside WSL2

java \
-Dcom.sun.management.jmxremote=true \
-Djava.rmi.server.hostname=127.0.0.1 \
-Dcom.sun.management.jmxremote.port=9991 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.registry.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.net.preferIPv4Stack=true \
-jar jmx-tester-1.0.0.jar

Then on Windows host connect JMX to 127.0.0.1:9991

docker container inside WSL2

java \
-Dcom.sun.management.jmxremote=true \
-Djava.rmi.server.hostname=127.0.0.1 \
-Dcom.sun.management.jmxremote.host=0.0.0.0 \
-Dcom.sun.management.jmxremote.port=9991 \
-Dcom.sun.management.jmxremote.rmi.port=9991 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.registry.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.net.preferIPv4Stack=true \
-jar jmx-tester-1.0.0.jar

Then on Windows host connect JMX to 127.0.0.1:9991

Tomlinson answered 15/4, 2022 at 7:57 Comment(2)
+1 for mentioning "java.rmi.server.hostname" (which was what I needed, while the other more recent answers seem to lack) to be able to connect from Windows to WSL2. I wonder if the host, when telling the client which port to use, also sends the IP/hostname to connect to, and without setting that property in my case it was something else than localhost.Canella
OMG this actually worked! Thanks a lot. How the hell did you figure it out??Valladares
C
1

In my case it depends on java.net.preferIPv6Addresses https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/doc-files/net-properties.html

Default value is false

I have server running on WSL2 and client running on Win11:

c:>java -Djava.net.preferIPv6Addresses=system my.My2 http://localhost:8025
http://localhost:8025
{"timestamp":"2022-04-22T10:25:03.819+00:00","status":"404","error":"Not Found","path":"/"}

c:>java -Djava.net.preferIPv6Addresses=true my.My2 http://localhost:8025
http://localhost:8025
{"timestamp":"2022-04-22T10:25:14.544+00:00","status":"404","error":"Not Found","path":"/"}

c:>java -Djava.net.preferIPv6Addresses=false my.My2 http://localhost:8025
http://localhost:8025
Exception in thread "main" java.net.ConnectException
        at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:571)
        at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:123)
        at my.My2.main(My2.java:15)
Caused by: java.net.ConnectException
...

c:>java  my.My2 http://localhost:8025
http://localhost:8025
Exception in thread "main" java.net.ConnectException
        at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:571)
        at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:123)
        at my.My2.main(My2.java:15)
Caused by: java.net.ConnectException
...
Cailly answered 22/4, 2022 at 10:29 Comment(0)
S
0

This seems to be a general issue with Java.

https://github.com/microsoft/WSL/discussions/6253

A workaround that worked for me was listening on '0.0.0.0' instead of '127.0.0.1' in WSL2 with the JMX server.

Steeplechase answered 1/4, 2021 at 14:59 Comment(1)
do you mean using -D=com.sun.management.jmxremote.host=0.0.0.0?Gibrian

© 2022 - 2024 — McMap. All rights reserved.