I am going to leave apart basic JMX concepts and concentrate on interesting use cases:
- exposing log4j over JMX (which allows to change LOG LEVEL at runtime)
- exposing Hibernate statistics over JMX
In order to simplify a bit all routines with exposing managed beans I will use Spring Framework which has awesome JMX support driven by annotations. Let's have our first Spring context snippet: exposing log4j over JMX.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <!--xml version="1.0" encoding="UTF-8"?--> < beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:context = "http://www.springframework.org/schema/context" xsi:schemalocation="http://www.springframework.org/schema/beans <!-- Some beans here --> <!-- JMX related bean definitions --> < bean id = "exporter" class = "org.springframework.jmx.export.MBeanExporter" > < property name = "assembler" ref = "assembler" > < property name = "namingStrategy" ref = "namingStrategy" > < property name = "autodetect" value = "true" > </ property ></ property ></ property ></ bean > < bean id = "assembler" class = "org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler" > < property name = "attributeSource" ref = "jmxAttributeSource" > </ property ></ bean > < bean id = "namingStrategy" class = "org.springframework.jmx.export.naming.MetadataNamingStrategy" > < property name = "attributeSource" ref = "jmxAttributeSource" > </ property ></ bean > < bean id = "jmxAttributeSource" class = "org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" > </ bean > <!-- Exposing Log4j over JMX --> < bean name = "jmxLog4j" class = "org.apache.log4j.jmx.HierarchyDynamicMBean" > </ bean > </ beans > |
That's how it look like inside JVisualVM with VisualVM-MBeans plugin installed (please notice that root's logger LOG LEVEL (priority) could be changed from WARN to any, let say, DEBUG, at runtime and have effect immediately):
Let's add Hibernate to JMX view! In order to do that I will create very simple Hibernate configuration using Spring context XML file (I will repeat configuration for JMX-related beans but it's exactly the same as in previous example):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <!--xml version="1.0" encoding="UTF-8"?--> < beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:context = "http://www.springframework.org/schema/context" xmlns:jdbc = "http://www.springframework.org/schema/jdbc" xsi:schemalocation="http://www.springframework.org/schema/beans <!-- Some beans here --> <!-- JMX related bean definitions --> < bean id = "exporter" class = "org.springframework.jmx.export.MBeanExporter" > < property name = "assembler" ref = "assembler" > < property name = "namingStrategy" ref = "namingStrategy" > < property name = "autodetect" value = "true" > </ property ></ property ></ property ></ bean > < bean id = "assembler" class = "org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler" > < property name = "attributeSource" ref = "jmxAttributeSource" > </ property ></ bean > < bean id = "namingStrategy" class = "org.springframework.jmx.export.naming.MetadataNamingStrategy" > < property name = "attributeSource" ref = "jmxAttributeSource" > </ property ></ bean > < bean id = "jmxAttributeSource" class = "org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" > </ bean > <!-- Basic Hibernate configuration --> < bean id = "sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" > < property name = "configurationClass" value = "org.hibernate.cfg.AnnotationConfiguration" > < property name = "dataSource" > < ref bean = "dataSource" > </ ref ></ property > < property name = "hibernateProperties" > < props > < prop key = "hibernate.dialect" >org.hibernate.dialect.HSQLDialect</ prop > < prop key = "hibernate.generate_statistics" >true</ prop > </ props > </ property > </ property ></ bean > < jdbc:embedded-database id = "dataSource" type = "HSQL" ></ jdbc:embedded-database > < bean id = "transactionManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager" > < property name = "sessionFactory" ref = "sessionFactory" > </ property ></ bean > <!-- Exposing Hibernate Statistics over JMX --> < bean name = "hibernateStatistics" class = "org.hibernate.jmx.StatisticsService" > < property name = "sessionFactory" ref = "sessionFactory" > </ property ></ bean > </ beans > |
And now we see this picture (please notice very important Hibernate property in order to see some real data here hibernate.generate_statistics = true):
Cool, simple and very useful, isn't it? :)