0
votes

I have an embedded Jetty app running locally and have jconsole connected to it. When I subscribe to notifications from java.lang.Memory, I don't see any notifications coming through - even when I trigger a garbage collection manually. I'm new to JMX, but my understanding is that platform mbeans like GarbageCollectorMXBean and MemoryMXBean should be available by default and shouldn't need configuring. Is that correct?

I'm configuring JMX as follows, where server is the jetty server:

private void configureJmx(CommandLine cmd) {
    String jmxRmiHost = cmd.getOptionValue("jmxRmiHost");
    String jmxRmiPortString = cmd.getOptionValue("jmxRmiPort");
    String jmxPasswordFile = cmd.getOptionValue("jmxPasswordFile");
    String jmxAccessFile = cmd.getOptionValue("jmxAccessFile");
    if (jmxRmiHost != null || jmxRmiPortString != null || jmxPasswordFile != null || jmxAccessFile != null) {
        if (jmxRmiHost == null || jmxRmiPortString == null || jmxPasswordFile == null || jmxAccessFile == null) {
            throw new IllegalStateException("If any of -jmxRmiHost, -jmxRmiPort, -jmxPasswordFile or -jmxAccessFile "
                    + "are set, then all of them must be");
        } else {
            int jmxRmiPort = Integer.valueOf(jmxRmiPortString);
            MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
            server.addEventListener(mbContainer);
            server.addBean(mbContainer);
            server.addBean(Log.getLog());
            String rmiUrl = "/jndi/rmi://" + jmxRmiHost + ":" + jmxRmiPort + "/jmxrmi";
            try {
                JMXServiceURL jmxServiceUrl = new JMXServiceURL("rmi", jmxRmiHost, jmxRmiPort, rmiUrl);
                Map<String, String> jmxEnvironment = new HashMap<String, String>(2);
                jmxEnvironment.put("jmx.remote.x.password.file", jmxPasswordFile);
                jmxEnvironment.put("jmx.remote.x.access.file", jmxAccessFile);
                String name = "org.eclipse.jetty.jmx:name=rmiconnectorserver";
                ConnectorServer connectorServer = new ConnectorServer(jmxServiceUrl, jmxEnvironment, name);
                connectorServer.start();
            } catch (Exception e) {
                throw new RuntimeException("Unable to configure JMX: " + e);
            }
        }
    }
}

Presumably, in jconsole I should be able to just select the mbean in the MBeans tab and click 'subscribe' to see its notifications?

Thanks for your help.

EDIT: Just tried add the following args when invoking java. Still no luck.

  -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 \
1

1 Answers

1
votes

It turns out I was receiving JMX notifications, but the MBeans I was expecting weren't present. It was because when we changed from standalone to embedded Jetty, we forgot to invoke java with the same arguments. I examined Jetty's config files and found it was using the following command-line args.

-XX:+UseConcMarkSweepGC
-XX:ParallelCMSThreads=2
-XX:+CMSClassUnloadingEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:CMSInitiatingOccupancyFraction=80
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-XX:+PrintTenuringDistribution
-XX:+PrintCommandLineFlags
-XX:+DisableExplicitGC

Running the app with the above solved the problem.