3

I am trying to monitor all Java processes running on a server via jstatd. I've got it set up enough that I can connect with VisualVM and see all running processes. Most displays work fine, however certain things (especially CPU usage and MBeans) do not display. Instead, it says:

MBeans Browser

Data not available because JMX connection to the JMX agent could not be established.

I assumed that the problem was that the application must "announce" through the jstatd RMI registry rather than a local one, so I tried out the following (per these suggestions) but it still won't display. The code I tried is as follows:

public class JmxRmiConnectorTest {
    public static void main(String[] args) throws Exception {
        Registry rmiRegistry = LocateRegistry.createRegistry(9994);
        String svc =
            "service:jmx:rmi://localhost:9994/jndi/rmi://localhost:1099/connector";

        MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();

        JMXServiceURL url = new JMXServiceURL(svc);
        RMIConnectorServer rmiServer = new RMIConnectorServer(url, null, mbeanServer);
        rmiServer.start();

        Thread.sleep(100000);

        rmiServer.stop();
    }
}

How can I get my MBeans and CPU usage to show up in VisualVM when seen through jstatd?

Steven Schlansker
  • 37,580
  • 14
  • 81
  • 100

3 Answers3

9

jstatd has nothing to do with JMX. Jstatd is a proxy for Jvmstat. To get MBeans and CPU usage you need to also enable JMX. See JMX Remote Monitoring and Management for more details. Once you have JMX enabled, VisualVM will automatically detect (via jvmstat) that it can also use JMX and it will display data from both jvmstat and JMX in one place.

Tomas Hurka
  • 6,723
  • 29
  • 38
  • See the code I posted, I am exporting JMX via a RMIConnectorServer above. So I think that part is covered. But VisualVM doesn't pick up the connection automagically as you describe, and I am trying to figure out exactly where that has gone wrong. Thanks. – Steven Schlansker Feb 20 '12 at 21:42
  • 1
    I don't think this will work. VisualVM can detect JMX connection via jvmstat because it has access (via jvmstat) to commandline arguments of monitored process. Please, use the process I outlined above. It is much easier to set several commandline arguments than adding special code to your application. – Tomas Hurka Feb 21 '12 at 11:54
  • Thanks, that's the key -- that VisualVM figures out how to connect via parsing the command line parameters. That's pretty stupid. We have a custom exporter because we want to bind to a specific network interface (a 10.x network rather than the public IP) to reduce our attack vector. Is there any way at all to get it to work with a custom exporter? – Steven Schlansker Feb 22 '12 at 23:14
  • 1
    This is not stupid. There is simply no other way to find out about JMX connection and its configuration (except of the brute-force port scan). – Tomas Hurka Feb 23 '12 at 11:32
  • 1
    Seems that they could rendezvous with the RMI registry, or even export that information directly via jvmstat. I'm pretty convinced that they way it's written as-is is not really a good way of doing it, even if for no other reason that you can then never use any sort of custom exporter. – Steven Schlansker Feb 23 '12 at 18:38
  • I am really confused by your response. Who is 'they'? External JMX connection is not exported via jvmstat. Note that JMX specification does not provide any way of discovery of JXM connection. JMX is designed so that you connect to it directly with URL. Merging jvmstat and JMX data in VisualVM is something you have got as bonus. I don't understand why do you need custom exporter. You asked how to monitor application via jvmstat - for that you don't need anything special, just start your application with JMX enabled like it is described in JDK guide mentioned above. Nothing else is needed. – Tomas Hurka Feb 23 '12 at 18:56
  • My point is: There is a broker configured and running (in jstatd) where various information is already kept. But instead of keeping JMX connection information there where it could be maintained programmatically, they (writers of VisualVM et al) chose to parse command line arguments. And as I said before, the reason I want a custom exporter is to bind to a specific network interface, which the stock exporter *does not support* – Steven Schlansker Feb 23 '12 at 23:26
  • I'll give you the bounty for the pointer on the command line arguments unless someone comes up with a better solution in a day or two. Thanks! – Steven Schlansker Feb 24 '12 at 22:56
0

In remote, launch java like this to enabl jmxremote.

java -Dcom.sun.management.jmxremote \
     -Dcom.sun.management.jmxremote.port=9191 \
     -Dcom.sun.management.jmxremote.authenticate=false \
     -Dcom.sun.management.jmxremote.ssl=false \
     -Djava.rmi.server.hostname=`hostname` \
     -jar app.jar

In locale,use jps like thisjps YOUHOSTNAME:9191.

wener
  • 7,191
  • 6
  • 54
  • 78
0

Just for those who need a quick working method. JMX can be start/stop dynamically, that's without restart of JVM. In my case, after start jmx dynamically and restart jvisualvm, JMX and cpu usage works fine.

jcmd PID ManagementAgent.start jmxremote.port=9999 jmxremote.ssl=false jmxremote.authenticate=false

or

jcmd PID ManagementAgent.stop
user2204107
  • 111
  • 1
  • 4