How to connect to JMX server running inside WSL2 - java

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.

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

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.

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
...

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.

Related

Unable to remote connect VisualVM to CentOS

I am new to VisualVM and trying to monitor some application which is deployed on Tomcat 9 CentOS server. I have installed VisualVM on my Windows laptop and trying to remote connect to the JVM on the CentOS server, but nothing is displayed (message on VisualVM: Not supported for this JVM).
Please find below Java version installed on CentOS server:
[root#localhost bin]# java -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
Based on the online resource I saw, I need to enable JMX on Tomcat, so I have added the following properties in my setenv.sh (in tomcat/bin folder) file:
export CATALINA_OPTS="\
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=8999 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false"
I have downloaded the latest VisualVM and created a remote host via File->Add Remote Host. Then Add JMX Connection info as follows:
connection:dymmyip:8999
username :user
Password :dummyPassword
uncheck :do not require ssl
When I try to connect, the following screen is displayed:
Can anyone tell me please what I am missing here?
You can add the missing =true in your setenv.sh
export CATALINA_OPTS="\
-Dcom.sun.management.jmxremote=true \
-Dcom.sun.management.jmxremote.port=8999 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.local.only=false"
You have to chmod you setenv.sh too:
$ cd <your-tomcat-dir>/bin
$ chmod a+x setenv.sh
Be sure it is not a firewall issue. Test the connection with telnet dummyip 8999
Be sure using the same JVM on both VisualVM and Tomcat. (Be careful with architecture too: 32 or 64bits)
You can get the last release of VisualVM here.
To install it:
$ [ -f "/usr/bin/visualvm" ] && sudo mv /usr/bin/visualvm{,.old}
$ wget https://github.com/oracle/visualvm/releases/download/2.1.4/visualvm_214.zip
$ unzip visualvm_214.zip
$ sudo mv visualvm_214 /opt/
$ sudo ln -s /opt/visualvm_214/bin/visualvm /usr/bin/
$ visualvm --jdkhome /usr/lib/jvm/java-17-openjdk-amd64
Use the path you want in --jdkhome.

How to access JMX interface in docker container on VM from outside?

I am trying to remotely monitor a JVM running in docker. The configuration looks like this:
machine: runs a JVM (in my case, Hello-World springboot app) in docker on an ubuntu machine (VM);
the IP of this machine is 10.10.1.29;
docker container has IP 172.28.0.3;
and to connect to VM by ssh I putted my creds
I have DockerFile of myApp
// some docker commands
EXPOSE 9010
CMD ["java", \
"-Dcom.sun.management.jmxremote", \
"-Dcom.sun.management.jmxremote.authenticate=false", \
"-Dcom.sun.management.jmxremote.ssl=false", \
"-Dcom.sun.management.jmxremote.port=9010", \
"-Dcom.sun.management.jmxremote.rmi.port=9010", \
"-Djava.rmi.server.hostname=10.10.1.29", \
"-jar /app/myApp-1.0.0.jar"]
the container starts and everything is super by docker-compose
config docker-compose.yaml:
// some yaml config
ports:
- "9010:9010" # JMX
I am running jconsole locally and tried to run this
service:jmx:rmi:///jndi/rmi://10.10.1.29:9010/jmxrmi
but connection failed
I tried different options but unfortunately unsuccessfully
Does anyone have a solution to this? Maybe the configuration is incorrect?
You will have to look into several issues here:
run the JVM with JMX enabled. Be aware of the port that is opened to access these values
run the docker container such that the port to the outside of the container
as the container is running inside some OS ensure there is no firewall preventing access to this port from outside the OS
as the OS is running inside a VM ensure that VM is fowarding traffic to the correct port
from outside the VM access the correct interface/port. If this access is from outside the host OS, ensure the host OS does not implement a firewall and forwards the traffic correctly
Failure on any of these points will simply not give you access.

JMX and Debugging on Tomcat inside Docker

I am trying to setup IntelliJ to connect to a Tomcat instance running in a Docker container. I would like to be able to use remote debugging and also deploy remotely using JMX.
I can enable remote debugging using the environment variables
JPDA_ADDRESS=8000
JPDA_TRANSPORT=dt_socket
and by starting Tomcat with catalina.sh jpda run, so remote debugging works without a problem.
I can also do this alternatively with
CATALINA_OPTS='-agentlib:jdwp=transport=dt_socket,address=8000,suspend=n,server=y'
and then I don't need to use catalina.sh jpda run
No matter what I do, I cannot get JMX to work. I verified that I have catalina-jmx-remote.jar in /usr/local/tomcat/lib`.
I have tried setting CATALINA_OPTS and JAVA_OPTS to
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=1099
-Dcom.sun.management.jmxremote.rmi.port=1099
-Djava.rmi.server.hostname=192.168.99.100
-Dcom.sun.management.jmxremote.ssl=false
I have verified that 192.168.99.100 is the IP of my docker machine. I have tried connecting to JMX with VisualJM and IntelliJ, it does not work. I have verified that the port 1099 is open and available from the host.
Tomcat is receiving the JMX args
20-Apr-2016 23:50:14.019 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.rmi.port=1099 -Djava.rmi.server.hostname=192.168.99.100 -Dcom.sun.management.jmxremote.ssl=false
Why can't I get JMX to work? There is no information available in any logs and this will not work no matter what I try.
Edit: lsof -i :1099 shows nothing running on that port
I am running on Mac OS X. It is a docker-machine but I believe docker uses virualbox on mac because it can't run containers natively.
I have mapped the port. docker ps shows 0.0.0.0:1099->1099/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8080->8080/tcp. Ports 8080 and 8000 work so 1099 should be mapped correctly too.
I was able to connect when I used 0.0.0.0 for jmxremote.host and server.hostname
HOST=0.0.0.0
java -Xmn100M -XX:+PrintGCDetails -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -Xmx384M $JAVA_OPTS\
-Dcom.sun.management.config.file=/opt/app/management.properties \
-Djava.util.logging.config.file=/opt/app/logging.properties \
-Dcom.sun.management.jmxremote.port=$JMX_PORT \
-Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT \
-Dcom.sun.management.jmxremote.host=$HOST \
-Djava.rmi.server.hostname=$HOST \
-jar /opt/app/app.jar

How to attach JConsole to a remote JVM? [duplicate]

This question already has answers here:
Has anyone ever got a remote JMX JConsole to work?
(20 answers)
Closed 7 years ago.
I have a Java 8 application running on a remote Linux server and need to attach a JConsole to it for debugging purposes.
From my local machine I set up a tunnel to the remote machine:
ssh -fN -L 9999:localhost:9999 myuser#1.11.11.111
On the remote machine I run the application with the following system properties:
java -Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.local.only=false \
-cp foo.jar:config com.foo.bar.Main config/blah.properties
but when I start the JConsole I get Secure connection failed.
If I click on "Insecure connection" I get
How can I get around this?
I managed to make it working adding an extra system property for the RMI port:
java \
-Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.rmi.port=9999 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.local.only=false \
-cp foo.jar:config com.foo.bar.Main config/blah.properties

Cannot connect to JMX/RMI server with VisualVM for no apparent reason

I have my OSGi application launching with the following command in my remote machine:
java -Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=8080 \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-jar bin/felix.jar
And in my local machine I have VisualVM from which I try to connect to the remote JVM instance:
What am I missing?
Thanks!
The comment from #Klara saved my day !!
fixed my connection to the jstad
jstatd -J-Djava.security.policy=all.policy -J-Djava.rmi.server.hostname=hostname-goes-here &

Categories

Resources