1

We share a remote Linux box for developing various Java apps, and we use VisualVM over ssh to profile the apps as described here. Is there any way to enable JMX/profiling on our Java processes without needing to allocate/provision port numbers among our processes/users? It's annoying to have to always make sure you're specifying a (unique) port number just to enable profiling.

To make this all more concrete: hardcoding the port obviously doesn't work and will conflict:

exec java -Dcom.sun.management.jmxremote.port=3000 ...

We can require always specifying a unique port whenever you run a process, but this is tedious---you have to ensure your ports don't conflict with your other processes and also don't conflict with other users:

exec java -Dcom.sun.management.jmxremote.port=$1 ...

Currently we use:

exec java -Dcom.sun.management.jmxremote.port=$(( $RANDOM + 2000 )) ...

But we still occasionally bump into occupied port numbers.

We can continue with fancier scripts (e.g. querying netstat for occupied port numbers and hoping there's no race), but we're wondering whether there's a better way / whether we're Doing It Wrong.

Community
  • 1
  • 1
Yang
  • 16,037
  • 15
  • 100
  • 142

2 Answers2

0

My best guess is that you should figure out if there is a way to start the VM without the -Dcom.sun.management.jmxremote.port=3000 ... but then start your own MBeanServer connectors

http://www.docjar.com/html/api/sun/management/jmxremote/ConnectorBootstrap.java.html

is the place where sun jvm seems to be starting the connectors based on the passed in system properties, I think reading the code there will provide enough info to be able to start your own MBeanServerConnector

http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/remote/JMXConnectorServerFactory.html

the environment variables passed to newJMXConnectorServer seems to be just a MAP if you read the code from the JDK you might be able to discover what to put in the map so that it starts a connector with your own code then that way you can write your own java code to pick available port numbers. I have not tried this approach but it seems promising and I am really want an answer to the question you raised.

JMXConnectorServer connServer = null;
  735           try {
  736               connServer =
  737                       JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
  738               connServer.start();
  739           } catch (IOException e) {
  740               if (connServer == null) {
  741                   throw new AgentConfigurationError(CONNECTOR_SERVER_IO_ERROR,
  742                           e, url.toString());
  743               } else {
  744                   throw new AgentConfigurationError(CONNECTOR_SERVER_IO_ERROR,
  745                           e, connServer.getAddress().toString());
  746               }
  747           }
ams
  • 60,316
  • 68
  • 200
  • 288
  • Doesn't launching the server from within the Java app just push the problem one layer down? It would allow port-finding to be more robust (since I can try more than one port, and there could be no TOCTTOU race), but I'd also like to avoid having to add this into all the projects we're working on. Anyway, I too am hoping there's something that will solve this problem out there. – Yang Feb 17 '12 at 09:46
0

One possible solution is to run VisualVM on remote box and use vnc or remote X session to display VisualVM on your local machine.

Tomas Hurka
  • 6,723
  • 29
  • 38