Thanks for the review comments. I've taken a different approach now and the problem seems more generic. Here's the core issue:
RawStore is kept as a threadlocal variable. A RawStore object has a reference to the JDOPersistanceManager object which JDOPersistanceManagerFactory caches. To remove the JDOPersistanceManager from the cache, an explicit JDOPersistanceManager#close call is required.
The issue is, that in HiveServer2, we keep 2 threadpools (handler - binary mode/http mode & async) managed by an ExecutorService. Based on the config, the threadpools keep a certain number of threads live and kill excess threads after a configurable keepAliveTime expires. However, ExecutorService does not provide a hook to plug in custom cleanup code when a thread is killed - ideally this is where we'd plug in code to close the JDOPersistanceManager stored in the threadlocal RawStore.
The current approach I've taken provides a custom ThreadFactory while creating the threadpool, which has a finalize method that does the cleanup. The ThreadFactory also maintains a map of RawStore object per Thread and in the finalize method of each thread, retrieves the RawStore object from the map, and performs the shutdown.
On another note, remote metastore also uses ExecutorService for maintaining its ThreadPool. I haven't tested there, but similar problem should exist in that case.