DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • How Spring and Hibernate Simplify Web and Database Management
  • Enhanced Query Caching Mechanism in Hibernate 6.3.0
  • Choosing the Right Caching Strategy
  • Implement Hibernate Second-Level Cache With NCache

Trending

  • Data Lake vs. Warehouse vs. Lakehouse vs. Mart: Choosing the Right Architecture for Your Business
  • Intro to RAG: Foundations of Retrieval Augmented Generation, Part 1
  • Operational Principles, Architecture, Benefits, and Limitations of Artificial Intelligence Large Language Models
  • Endpoint Security Controls: Designing a Secure Endpoint Architecture, Part 2
  1. DZone
  2. Data Engineering
  3. Data
  4. Enabling JMX in Hibernate, Ehcache, Quartz, DBPC and Spring

Enabling JMX in Hibernate, Ehcache, Quartz, DBPC and Spring

By 
Tomasz Nurkiewicz user avatar
Tomasz Nurkiewicz
DZone Core CORE ·
Dec. 22, 11 · Interview
Likes (0)
Comment
Save
Tweet
Share
12.2K Views

Join the DZone community and get the full member experience.

Join For Free

A collection of short how-to's for enabling JMX in several popular Java technologies.

Continuing our journey with JMX (see: ...JMX for human beings) we will learn how to enable JMX support (typically statistics and monitoring capabilities) in some popular frameworks. Most of this information can be found on project's home pages, but I decided to collect it with few the addition of some useful tips.



Hibernate (with Spring support)

Exposing Hibernate statistics with JMX is pretty simple, however some nasty workarounds are requires when JPA API is used to obtain underlying SessionFactory



class JmxLocalContainerEntityManagerFactoryBean() extends LocalContainerEntityManagerFactoryBean {
 override def createNativeEntityManagerFactory() = {
  val managerFactory = super.createNativeEntityManagerFactory()
  registerStatisticsMBean(managerFactory)
  managerFactory
 }
 
 def registerStatisticsMBean(managerFactory: EntityManagerFactory) {
  managerFactory match {
   case impl: EntityManagerFactoryImpl =>
    val mBean = new StatisticsService();
    mBean.setStatisticsEnabled(true)
    mBean.setSessionFactory(impl.getSessionFactory);
    val name = new ObjectName("org.hibernate:type=Statistics,application=spring-pitfalls")
    ManagementFactory.getPlatformMBeanServer.registerMBean(mBean, name);
   case _ =>
  }
 }
 
}
Note that I have created a subclass of Springs built-in LocalContainerEntityManagerFactoryBean. By overriding createNativeEntityManagerFactory() method I can access EntityManagerFactory and by trying to downcast it to org.hibernate.ejb.EntityManagerFactoryImpl we were able to register Hibernate Mbean.
One more thing has left. Obviously we have to use our custom subclass instead of org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean. Also, in order to collect the actual statistics instead of just seeing zeroes all the way down we must set the hibernate.generate_statistics flag.
@Bean
def entityManagerFactoryBean() = {
 val entityManagerFactoryBean = new JmxLocalContainerEntityManagerFactoryBean()
 entityManagerFactoryBean.setDataSource(dataSource())
 entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter())
 entityManagerFactoryBean.setPackagesToScan("com.blogspot.nurkiewicz")
 entityManagerFactoryBean.setJpaPropertyMap(
  Map(
   "hibernate.hbm2ddl.auto" -> "create",
   "hibernate.format_sql" -> "true",
   "hibernate.ejb.naming_strategy" -> classOf[ImprovedNamingStrategy].getName,
   "hibernate.generate_statistics" -> true.toString
  ).asJava
 )
 entityManagerFactoryBean
}
Here is a sample of what can we expect to see in JvisualVM (don't forget to install all plugins!):




In addition we get a nice Hibernate logging:
HQL: select generatedAlias0 from Book as generatedAlias0, time: 10ms, rows: 20

EhCache

Monitoring caches is very important, especially in application where you expect values to generally be present there. I tend to query the database as often as needed to avoid unnecessary method arguments or local caching. Everything to make code as simple as possible. However this approach only works when caching on the database layer works correctly. Similar to Hibernate, enabling JMX monitoring in EhCache is a two-step process. First you need to expose provided MBean in MBeanServer:
@Bean(initMethod = "init", destroyMethod = "dispose")
def managementService = new ManagementService(ehCacheManager(), platformMBeanServer(), true, true, true, true, true)
 
@Bean def platformMBeanServer() = ManagementFactory.getPlatformMBeanServer
 
def ehCacheManager() = ehCacheManagerFactoryBean.getObject
 
@Bean def ehCacheManagerFactoryBean = {
 val ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean
 ehCacheManagerFactoryBean.setShared(true)
 ehCacheManagerFactoryBean.setCacheManagerName("spring-pitfalls")
 ehCacheManagerFactoryBean
}
Note that I explicitly set CacheManager name. This is not required but this name is used as part of the Mbean name and a default one contains hashCode value, which is not very pleasant. The final touch is to enable statistics on a cache basis:
	<cache name="org.hibernate.cache.StandardQueryCache"
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="3600"
    timeToLiveSeconds="600"
    overflowToDisk="false"
    memoryStoreEvictionPolicy="LRU"
    statistics="true"
/>
Now we can happily monitor various caching characteristics of every cache separately:



As we can see the percentage of cache misses increases. Never a good thing. If we don't enable cache statistics, enabling JMX is still a good idea since we get a lot of management operations for free, including flushing and clearing caches (useful during debugging and testing).

Quartz scheduler

In my humble opinion Quartz scheduler is very underestimated library, but I will write an article about it on its own. This time we will only learn how to monitor it via JMX. Fortunately it's as simple as adding:
org.quartz.scheduler.jmx.export=true
To quartz.properties file. The JMX support in Quartz could have been slightly broader, but still one can query e.g. which jobs are currently running. By the way the new major version of Quartz (2.x) brings very nice DSL-like support for scheduling:
	
val job = newJob(classOf[MyJob])
val trigger = newTrigger().
  withSchedule(
   repeatSecondlyForever()
  ).
  startAt(
   futureDate(30, SECOND)
  )
scheduler.scheduleJob(job.build(), trigger.build())

Apache Commons DBCP

Apache Commons DBCP is the most reasonable JDBC pooling library I came across. There is also c3p0, but it doesn't seem like it's actively developed any more. Tomcat JDBC Connection Pool looked promising, but since it's bundled in Tomcat, your JDBC drivers can no longer be packaged in WAR.
The only problem with DBCP is that it does not support JMX. At all (see this two and a half year old issue). Fortunately this can be easily worked around. Besides we will learn how to use Spring built-in JMX support.
Looks like the standard BasicDataSource has all what we need, all we have to do is to expose existing metrics via JMX. With Spring it is dead-simple – just subclass BasicDataSource and add @ManagedAttribute annotation over desired attributes:
@ManagedResource
class ManagedBasicDataSource extends BasicDataSource {
 
    @ManagedAttribute override def getNumActive = super.getNumActive
    @ManagedAttribute override def getNumIdle = super.getNumIdle
    @ManagedAttribute def getNumOpen = getNumActive + getNumIdle
    @ManagedAttribute override def getMaxActive: Int= super.getMaxActive
    @ManagedAttribute override def setMaxActive(maxActive: Int) {
        super.setMaxActive(maxActive)
    }
 
    @ManagedAttribute override def getMaxIdle = super.getMaxIdle
    @ManagedAttribute override def setMaxIdle(maxIdle: Int) {
        super.setMaxIdle(maxIdle)
    }
 
    @ManagedAttribute override def getMinIdle = super.getMinIdle
    @ManagedAttribute override def setMinIdle(minIdle: Int) {
        super.setMinIdle(minIdle)
    }
 
    @ManagedAttribute override def getMaxWait = super.getMaxWait
    @ManagedAttribute override def setMaxWait(maxWait: Long) {
        super.setMaxWait(maxWait)
    }
 
    @ManagedAttribute override def getUrl = super.getUrl
    @ManagedAttribute override def getUsername = super.getUsername
}
Here are few data source metrics going crazy during load-test:



JMX support in the Spring framework itself is pretty simple. As you have seen above exposing arbitrary attribute or operation is just a matter of adding an annotation. You only have to remember about enabling JMX support using either XML or Java (also see: SPR-8943 : Annotation equivalent to <context:mbean-export/> with @Configuration):
<context:mbean-export/>
or:
@Bean def annotationMBeanExporter() = new AnnotationMBeanExporter()
This article wasn't particularly exciting. However, the knowledge of JMX metrics will enable us to write simple yet fancy dashboards in no time. Stay tuned!

 

From http://nurkiewicz.blogspot.com/2011/12/enabling-jmx-in-hibernate-ehcache-qurtz.html

Spring Framework Hibernate Quartz (scheduler) Ehcache Cache (computing)

Opinions expressed by DZone contributors are their own.

Related

  • How Spring and Hibernate Simplify Web and Database Management
  • Enhanced Query Caching Mechanism in Hibernate 6.3.0
  • Choosing the Right Caching Strategy
  • Implement Hibernate Second-Level Cache With NCache

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!