Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

docker

jmx

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.

like image 933
nolexa Avatar asked Jan 31 '16 00:01

nolexa


People also ask

How does remote process connect to VisualVM?

Connecting to a Remote Host To add a remote host, right-click the Remote node in the Applications window, choose Add Remote Host and type the host name or IP address in the Add Remote Host dialog box. (You can also specify a display name that will be used to refer to the host when listed under the Remote node.)

How do I connect to docker process?

To connect to a container using plain docker commands, you can use docker exec and docker attach . docker exec is a lot more popular because you can run a new command that allows you to spawn a new shell. You can check processes, files and operate like in your local environment.


1 Answers

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.

like image 166
eg04lt3r Avatar answered Sep 25 '22 05:09

eg04lt3r