I have two different JNDI datasources in my Grails 3 app. The app starts and runs correctly when not using JNDI (either dev or prod). But when building and running a war in Tomcat with JNDI datasources I get the exception shown below. It seems to originate as a conflict with jmx, but I have tried disabling jmx wherever I see it, in application.yml and in the datasources themselves. Still, the problem persists. Grails 3.2.13, Tomcat 9.
NOTE: Using an Oracle db as the primary database eliminates the problem. It seems to me that the error with Postgres is caused by the default datasource factory in use. That said, I don't know how to correct it; I thought disabling jmx would do it.
application.groovy:
production:
dataSource:
jmxEnabled: false
dbCreate: none
jndiName: java:comp/env/jdbc/jpmt-prod-db
dataSources:
jddt4:
jmxEnabled: false
dbCreate: none
jndiName: java:comp/env/jdbc/jddt4-prod-db
Tomcat xml config:
<Resource
name="jdbc/jpmt-prod-db"
auth="Container"
type="javax.sql.DataSource"
url="jdbc:postgresql://<pg_host>:5432/<db>?currentSchema=sch"
driverClassName="org.postgresql.Driver"
dialect="org.hibernate.dialect.PostgreSQLDialect"
username="<user>"
password="<pswd>"
testOnBorrow="true"
removeAbandonedOnBorrow="true"
removeAbandonedTimeout="30"
logAbandoned="true"
maxActive="20"
maxIdle="10"
minIdle="5"
minEvictableIdleTimeMillis="1800000"
timeBetweenEvictionRunsMillis="1800000"
numTestsPerEvictionRun="3"
validationQuery="select 1"
jmxEnabled="false"
/>
<Resource
name="jdbc/jddt4-prod-db"
url="jdbc:oracle:thin:@<host>:<sid>"
type="oracle.jdbc.pool.OracleDataSource"
factory="oracle.jdbc.pool.OracleDataSourceFactory"
driverClassName="oracle.jdbc.OracleDriver"
dialect="org.hibernate.dialect.Oracle10gDialect"
user="<user>"
password="<pswd>"
logSql="false"
removeAbandoned="true"
removeAbandonedTimeout="30"
logAbandoned="true"
maxActive="20"
maxIdle="10"
maxwait="-1"
minEvictableIdleTimeMillis="1800000"
timeBetweenEvictionRunsMillis="1800000"
numTestsPerEvictionRun="3"
validationQuery="select 1 from dual"
jmxEnabled="false"
/>
The exception at Grails startup:
2019-02-20 18:24:32,588 ERROR org.springframework.boot.SpringApplication - Application startup failed
org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.apache.tomcat.dbcp.dbcp2.BasicDataSource@1485a2ce] with key 'dataSourceUnproxied'; nested exception is javax.management.InstanceAlreadyExistsException: Catalina:type=DataSource,host=localhost,context=/,class=javax.sql.DataSource,name="jdbc/jpmt-prod-db"
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:628)
at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:550)
at org.springframework.jmx.export.MBeanExporter.afterSingletonsInstantiated(MBeanExporter.java:432)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:781)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:372)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at grails.boot.GrailsApp.run(GrailsApp.groovy:83)
at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:151)
at org.grails.boot.context.web.GrailsAppServletInitializer.createRootApplicationContext(GrailsAppServletInitializer.groovy:57)
at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:86)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5098)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:703)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:630)
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1840)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:525)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:424)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1585)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:308)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:424)
at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:367)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:969)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:839)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1429)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:944)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:261)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:770)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Catalina.start(Catalina.java:682)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:350)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
Caused by: javax.management.InstanceAlreadyExistsException: Catalina:type=DataSource,host=localhost,context=/,class=javax.sql.DataSource,name="jdbc/jpmt-prod-db" at com.sun.jmx.mbeanserver.Repository.addMBean(Repository.java:437) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerWithRepository(DefaultMBeanServerInterceptor.java:1898) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:966) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:900) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:324) at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:522) at org.springframework.jmx.support.MBeanRegistrationSupport.doRegister(MBeanRegistrationSupport.java:195) at org.springframework.jmx.export.MBeanExporter.registerBeanInstance(MBeanExporter.java:675) at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:618) ... 54 common frames omitted