Category Archives: jmx
JMX Monitoring Support For Local Process On Windows
If you are monitoring a local jvm process using jconsole or jvisualvm and aren’t able to view the Threads tab on jvisualvm or connect to jconsole, this post should provide some troubleshooting information.
Any application that is started on the Java SE 6 platform will support the Attach API, and so will automatically be made available for local monitoring and management when needed. This out of box jmx support doesn’t work on Windows though. On Windows platforms, for security reasons, local monitoring and management is only supported if your default temporary directory is on a file system that allows the setting of permissions on files and directories (for example, on a New Technology File System (NTFS) file system). It is not supported on a File Allocation Table (FAT) file system, which provides insufficient access controls.
Enabling Logback JMX MBean In Glassfish
Logback support for JMX can be enabled by just adding a <jmxconfigurator/> tag in the configuration file but this is not how a web application should register the logback MBean if you web application is deployed in a glassfish application server. If you do it you would get the below error message on accessing the logback MBean through JConsole –
“Problem invoking getLoggerLevel : java.lang.IllegalStateException: WEB9031: WebappClassLoader unable to load resource[java.lang.Object], because it has not been started or was always stopped”
The root cause is an integration issue between logback and glassfish. On startup glassfish instantiates two classloaders for each of the deployed web application. The first one is a temporary one which is later destroyed.
When your web-application classes get loaded with this temporary classloader, logback initialization gets triggered (if the Logger instances are declared as static instances in your application classes which is mostly the case) like I explain in my older post. During this initialization process logback creates a JMX MBean instance (JMXConfigurator.class) and registers it with the MBean server. At certain point glassfish destroys the temporary classloader and nullifies all the static or final fields from the loaded classes. At a later step a new classloader is instantiated which would be the actual classloader for the web application. This classloader starts & loads the web context and the deployment continues.
The above mentioned error is displayed because while nullifying the classes during the destroy step of the temporary classloader, the registered MBean is not unregistered and logback does not re-register the MBean during the logback initialization step (which is triggered after the actual class loader is instantiated) since a MBean with that name was already registered. Here is short snippet of code from the JMXConfiguratorAction class which does the MBean registration.
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); if(!MBeanUtil.isRegistered(mbs, objectName)) { // register only of the named JMXConfigurator has not been previously // registered. Unregistering an MBean within invocation of itself // caused jconsole to throw an NPE. (This occurs when the reload* method // unregisters the JMXConfigurator jmxConfigurator = new JMXConfigurator((LoggerContext) context, mbs, objectName); try { mbs.registerMBean(jmxConfigurator, objectName); } catch (Exception e) { addError("Failed to create mbean", e); } }
A mystery would be to understand the reason behind glassfish creating a temporary classloader(It is hard to figure it out exactly from the source code 🙂 ).
One simple workaround that can be implemented to resolve this issue is not add the <jmxConfigurator/> tag in the logback configuration file and to manually register the logback jmx mbean in a servlet context listener. Have a look at JMXConfiguratorAction.class for more details on how to register the logback MBean.
This note could be a good addition to the well documented Logback manual :).