nolexa nolexa - 1 month ago 7
Java Question

How do I attach VisualVM to a simple Java process running in a Docker container

Actually I wanted a solution working for JEE containers, specifically for Glassfish, but after I tried many combinations of settings and did not succeed, I reduced the setup to the simplest possible case.

Here is my Hello World daemon started in a Docker container. I want to attach

jconsole
or
VisulaVM
to it. Everything is on the same machine.

public class Main {
public static void main(String[] args) {
while (true) {
try {
Thread.sleep(3000);
System.out.println("Hello, World");
} catch (InterruptedException e) {
break;
}
}
}
}


Dockerfile

FROM java:8
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac Main.java
CMD ["java", "Main"]


Building:
docker build -t hello-world-daemon .


Running:
docker run -it --rm --name hwd hello-world-daemon


Questions:


  • what JVM parameters should be added to
    CMD
    command line?

  • what ports should be exposed and published?

  • what network mode should Docker container be using?



I do not show my failed attempts here so that correct answers will not be biased. This should be a pretty common problem, yet I could not find a working solution.

Update. Worked solution

This Dockerfile works

FROM java:8
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac Main.java
CMD ["java", \
"-Dcom.sun.management.jmxremote", \
"-Dcom.sun.management.jmxremote.port=9010", \
"-Dcom.sun.management.jmxremote.local.only=false", \
"-Dcom.sun.management.jmxremote.authenticate=false", \
"-Dcom.sun.management.jmxremote.ssl=false", "Main"]
EXPOSE 9010


in combination with the docker run command

docker run -it --rm --name hwd -p 9010:9010 hello-world-daemon


VisualVM
connects via right click Local->Add JMX Connection, and then entering
localhost:9010
, or through adding a remote host.

JConsole
connects via selecting a Remote process with
localhost:9010
.

When defining the connection as remote, any interface listed by
ifconfig
can be used. For instance,
docker0
interface with address
172.17.0.1
works. The container's address
172.17.0.2
works too.

Answer

At first you should run you application with these JVM params:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

Then you should expose port for docker:

EXPOSE 9010

Also specify port binding with docker run command:

docker run -p 9010:9010 -it --rm --name hwd hello-world-daemon

After that you can connect with Jconsole to local 9010 port and manage application run in Docker.

Comments