Bug 53416 - Two datasources with the same name in different web applications results in javax.management.InstanceAlreadyExistsException
Two datasources with the same name in different web applications results in j...
Status: RESOLVED FIXED
Product: Tomcat Modules
Classification: Unclassified
Component: jdbc-pool
unspecified
PC Windows Vista
: P2 normal (vote)
: ---
Assigned To: Tomcat Developers Mailing List
:
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2012-06-14 13:37 UTC by Anthony Gerrard
Modified: 2012-06-27 17:38 UTC (History)
0 users



Attachments
JMX Registration of two pools (30.17 KB, image/jpeg)
2012-06-26 20:32 UTC, Filip Hanik
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Anthony Gerrard 2012-06-14 13:37:06 UTC
Deploy two different web applications onto Tomcat.

Each web application has a resource that:

* uses the Use Tomcat JDBC Connection Pool
* has an identical name to the other one

<Resource name="jdbc/collision" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" ... />

When starting the server you get a non fatal error in the logs InstanceAlreadyExistsException.  Both applications appear to still work OK

ERROR org.apache.tomcat.jdbc.pool.DataSource - Unable to register JDBC pool with JMX
javax.management.InstanceAlreadyExistsException: tomcat.jdbc:name="jdbc/soscvuk",context=/,type=ConnectionPool,host=localhost,class=org.apache.tomcat.jdbc.pool.
DataSource
	at com.sun.jmx.mbeanserver.Repository.addMBean(Repository.java:453) ~[na:1.6.0_32]
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.internal_addObject(DefaultMBeanServerInterceptor.java:1484) [na:1.6.0_32]
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:963) [na:1.6.0_32]
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:917) [na:1.6.0_32]
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:312) [na:1.6.0_32]
	at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:482) [na:1.6.0_32]
	at org.apache.tomcat.jdbc.pool.DataSource.registerJmx(DataSource.java:135) [tomcat-jdbc.jar:na]
	at org.apache.tomcat.jdbc.pool.DataSource.preRegister(DataSource.java:102) [tomcat-jdbc.jar:na]
	at org.apache.tomcat.util.modeler.BaseModelMBean.preRegister(BaseModelMBean.java:1132) [tomcat-coyote.jar:7.0.27]
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.preRegisterInvoke(DefaultMBeanServerInterceptor.java:1010) [na:1.6.0_32]
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:938) [na:1.6.0_32]
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:917) [na:1.6.0_32]
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:312) [na:1.6.0_32]
	at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:482) [na:1.6.0_32]
	at org.apache.tomcat.util.modeler.Registry.registerComponent(Registry.java:742) [tomcat-coyote.jar:7.0.27]
	at org.apache.catalina.core.NamingContextListener.addResource(NamingContextListener.java:1062) [catalina.jar:7.0.27]
	at org.apache.catalina.core.NamingContextListener.createNamingContext(NamingContextListener.java:671) [catalina.jar:7.0.27]
	at org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:270) [catalina.jar:7.0.27]
	at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119) [catalina.jar:7.0.27]
	at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90) [catalina.jar:7.0.27]
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5161) [catalina.jar:7.0.27]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.27]
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:895) [catalina.jar:7.0.27]
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:871) [catalina.jar:7.0.27]
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615) [catalina.jar:7.0.27]
	at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:649) [catalina.jar:7.0.27]
	at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1585) [catalina.jar:7.0.27]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) [na:1.6.0_32]
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) [na:1.6.0_32]
	at java.util.concurrent.FutureTask.run(FutureTask.java:138) [na:1.6.0_32]
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_32]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_32]
	at java.lang.Thread.run(Thread.java:662) [na:1.6.0_32]
Comment 1 Filip Hanik 2012-06-26 20:32:59 UTC
Created attachment 29000 [details]
JMX Registration of two pools

The name of the JMX bean that gets registered is unique to the web application, so your example must have something else wrong

I've attached an image of what JMX registration looks like when two web applications define an identical data source

If we examine your object name:

tomcat.jdbc:name="jdbc/soscvuk",context=/,type=ConnectionPool,host=localhost,class=org.apache.tomcat.jdbc.pool

you can see that it contains the 'context' and the 'host' as part of the name. Two web applications can not have the same context.

There must be something misconfigured in your application.
Comment 2 Filip Hanik 2012-06-26 20:33:44 UTC
Tested, unable to reproduce.
Please reopen with enough information to reproduce the issue, and I will take another look at it.
Comment 3 Anthony Gerrard 2012-06-26 21:05:11 UTC
We have two services with one web application in each.  One is for our secure site and one for our non secure.  We use Apache as the ssl endpoint and reverse proxy using ajp connectors.  Both web applications have the root context in their service.  This configuration works and we had no problems with the default connection pooling.  I got the error when switching to the tomcat connection pool.

Our server.xml looks something like

<Server>
  <Service name="Catalina">
    <Engine name="Catalina" defaultHost="${host.mainsite.name}">
      <Host name="${host.mainsite.name}" 
            appBase="webapps/${host.mainsite.name}" unpackWARs="true" 
            autoDeploy="false">
      </Host>
    </Engine>
  </Service>

  <Service name="Catalina-Secure">
    <Engine name="Catalina-Secure" defaultHost="${host.mainsite.name}">
      <Host name="${host.mainsite.name}" 
          appBase="webapps/${host.mainsite.name}-ssl" unpackWARs="true" 
          autoDeploy="false">
      </Host>
    </Engine>
  </Service>
</Server>

I've subsequently worked around this using <ResourceLink /> which I think is more appropriate for our set-up anyway.  However I still think this is a bug.
Comment 4 Mark Thomas 2012-06-26 21:12:29 UTC
Use of multiple versions of a web application may also trigger the issue (I haven't tested it).
Comment 5 Filip Hanik 2012-06-27 17:20:56 UTC
Roger, I will fix this.
Comment 6 Filip Hanik 2012-06-27 17:32:59 UTC
(In reply to comment #4)
> Use of multiple versions of a web application may also trigger the issue (I
> haven't tested it).

That wont be issue, as the ObjectName will have something like context=/test##001 instead of context=/test

the problem we encountered here is that the JNDI names in tomcat 6 would have path=/test whereas 7 has context=/test
Comment 7 Filip Hanik 2012-06-27 17:38:30 UTC
Fixed in r1354641 (trunk)
Fixed in r1354642 (7.0.x)