Search code examples
javajmxc3p0mbeansobjectname

C3P0Registry mbean is not being registered with MBeanServer. Getting InstanceNotFoundException


I am trying to get dbpool details using my function named getdbPoolStatistics() which returns a hashmap of all the metrices that i'm gonna monitor. In getdbPoolStatistics(), i use C3P0Registry.getPooledDataSources() which returns 2 db pools and then access the pools using an iterator i.e. connectionIterator .

To get token , which is further used during ObjectName creation.

ArrayList<String> pooledDataSourcesIdentityTokenList = new ArrayList<String>();    

mbean that gives you monitoring info.

Iterator<PooledDataSource> connectionIterator = C3P0Registry.getPooledDataSources().iterator();     

Get token and add it to ArrayList.

while(connectionIterator.hasNext()) {
      pooledDataSourcesIdentityTokenList.add(connectionIterator.next().getIdentityToken());
}

After this we need to get MBeanServer

MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

While registering mbean, I have used Domain: com.mchange.v2.c3p0, key-value: type=PooledDataSource and identityToken= token that i had added to ArrayList for 2 db pool objects from C3P0Registry.

Now, if i register the ObjectName using mbs.registerMBean()

for (int i = 0; i < pooledDataSourcesIdentityTokenList.size() ; i++) {
     ObjectName objName =  new ObjectName("com.mchange.v2.c3p0:type=PooledDataSource,identityToken="+pooledDataSourcesIdentityTokenList.get(i)+",*");
     mbs.registerMBean(connectionIterator2.next(), objName.getInstance("com.mchange.v2.c3p0","identityToken",pooledDataSourcesIdentityTokenList.get(i)));
}

i get

:error: unreported exception InstanceAlreadyExistsException; must be caught or declared to be thrown

Now if i use the complete objects instead of iterating over it.

  for (int i = 0; i < pooledDataSourcesIdentityTokenList.size() ; i++) {
      ObjectName objName =  new ObjectName("com.mchange.v2.c3p0:type=PooledDataSource,identityToken="+pooledDataSourcesIdentityTokenList.get(i)+",*");
      mbs.registerMBean(C3P0Registry.getPooledDataSources() , objName);
      startTimeMillisArray[i] = (String)(mbs.getAttribute(objName, "startTimeMillisDefaultUser"));
}

I get :

error:  unreported exception InstanceAlreadyExistsException; must be caught or declared to be thrown mbs.registerMBean(C3P0Registry.getPooledDataSources() , objName);

As InstanceAlreadyExistsException, i thought of not registering MBean Also I found that registerMBean(), was not used in many examples so i removed that line of code and tried.

If i only keep make the ObjectName and then try to getAttribute and put it in startTimeMillisArray

 for (int i = 0; (i < pooledDataSourcesIdentityTokenList.size() ; i++) {
     ObjectName objName =  new ObjectName("com.mchange.v2.c3p0:type=PooledDataSource,identityToken="+pooledDataSourcesIdentityTokenList.get(i)+",*");
     //No registering mbean here.
     startTimeMillisArray[i] = (String)(mbs.getAttribute(objName, "startTimeMillisDefaultUser"));
 }   

then I get the error:

javax.management.InstanceNotFoundException: com.mchange.v2.c3p0:type=PooledDataSource,identityToken=2ufaha9lm5mbruczledo|86ffe7,*
javax.management.InstanceNotFoundException: com.mchange.v2.c3p0:type=PooledDataSource,identityToken=2ufaha9lm5mbruczledo|c7dca5,*

This is creating a lot of confusion whether to use registerMBean() or not and also if I am using it the right way? Please help.


Solution

  • I think you may be doing a lot more work than you need to.

    c3p0 registers its MBeans by default. If you don't want them registered, you have to work at that. If you are having trouble monitoring c3p0 pools and its registry, you may need to debug general JMX stuff. Do you see other MBeans on the same JVM? If not, you may need to set some System properties. See here for some tips.

    You only have to do anything special if you want to turn JMX registration OFF in c3p0, that is, if you want to disable JMX MBean registration.

    You can also give your c3p0 MBeans customized and/or stable names.

    But you should never have to get into low-level JMX APIs, like defining your own ObjectName objects. c3p0 takes care of that for you.

    Please see the JMX section of c3p0's docs, here.

    p.s. c3p0 includes no getdbPoolStatistics() method, that may be part of your own libraries.