Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

org.apache.tomcat.jdbc.pool.DataSource register with jmx #1590

Closed
ralscha opened this issue Sep 20, 2014 · 8 comments
Closed

org.apache.tomcat.jdbc.pool.DataSource register with jmx #1590

ralscha opened this issue Sep 20, 2014 · 8 comments
Assignees
Labels
type: enhancement A general enhancement
Milestone

Comments

@ralscha
Copy link
Contributor

ralscha commented Sep 20, 2014

1.2.0.BUILD-SNAPSHOT

Would be nice if the DataSource object registers itself with jmx (if jmx is enabled)
I tried to enable it with spring.datasource.jmxEnabled=true
But it looks like this property does nothing.

I can use the following code to register the DataSource in my application

@Autowired
public Startup(DataSource dataSource, MBeanServer server) throws MalformedObjectNameException, Exception {
  if (dataSource instanceof org.apache.tomcat.jdbc.pool.DataSource) {
    org.apache.tomcat.jdbc.pool.DataSource tomcatDS =(org.apache.tomcat.jdbc.pool.DataSource)dataSource;
    tomcatDS.preRegister(server, new ObjectName(ConnectionPool.POOL_JMX_TYPE_PREFIX+tomcatDS.getClass().getName()+",name=mypool"));
        }
    }
@dsyer
Copy link
Member

dsyer commented Sep 22, 2014

This would work too:

    @Bean
    public ConnectionPool getJmxPool(DataSource dataSource) throws SQLException {
        return dataSource.createPool().getJmxPool();
    }

@dsyer dsyer added the type: enhancement A general enhancement label Sep 22, 2014
@ralscha
Copy link
Contributor Author

ralscha commented Sep 22, 2014

This does work. But it has one problem when jmxEnabled is set to false: spring.datasource.jmxEnabled=false

The application throws this error, because getJmxPool() returns null

org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [jdbcPool] with key 'jdbcPool'; nested exception is java.lang.IllegalArgumentException: Candidate object must not be null
    at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:613)
    at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:538)
    at org.springframework.jmx.export.MBeanExporter.afterSingletonsInstantiated(MBeanExporter.java:420)

@dsyer
Copy link
Member

dsyer commented Sep 22, 2014

That looks like a completely unrelated problem (the pool properties are not initialized until the pool is used).

@dsyer
Copy link
Member

dsyer commented Sep 22, 2014

Or maybe not. Maybe you just need to put a check in there so you don't create the @Bean if the property is false, e.g. @ConditionalOnExpression("${spring.datasource.jmxEnabled:true}").

@dsyer
Copy link
Member

dsyer commented Sep 22, 2014

You could put that in the TomcatDataSourceConfiguration BTW (fill in the contributor's agreement if you haven't already and send a pull request).

@philwebb philwebb added this to the 1.2.0.M2 milestone Sep 22, 2014
@ralscha
Copy link
Contributor Author

ralscha commented Sep 23, 2014

The @ConditionalOnExpression solution works great.

@Bean
@ConditionalOnExpression("${spring.datasource.jmxEnabled:true}")
public ConnectionPool jdbcPool(DataSource dataSource) throws SQLException {
  return dataSource.createPool().getJmxPool();
}

I was looking for the TomcatDataSourceConfiguration class but there is only one such class and it's located in a test class (TomcatDataSourceConfigurationTests).

@dsyer
Copy link
Member

dsyer commented Sep 24, 2014

Sorry, that was me remembering Spring Boot 1.0.x. The only way to do it generically and safely now might be to add a @Configuration that is @ConditionalOnBean and @ConditionalOnClass referring to the Tomcat DataSource.

@philwebb philwebb modified the milestones: 1.2.0.RC1, 1.2.0.M2 Oct 10, 2014
@dsyer dsyer self-assigned this Nov 3, 2014
@dsyer dsyer closed this as completed in f304d46 Nov 3, 2014
@dsyer dsyer removed the in progress label Nov 3, 2014
philwebb added a commit that referenced this issue Nov 4, 2014
@philwebb philwebb reopened this Nov 7, 2014
@philwebb
Copy link
Member

philwebb commented Nov 7, 2014

It turns out registering the JMX information by default can cause some issues if you use Spring's Test Context Framework. I've hit this trying to upgrade Sagan. By default, tests with @ContextConfiguration keep contexts open, so a second test case causes the following:

Caused by: javax.management.InstanceAlreadyExistsException: org.apache.tomcat.jdbc.pool.jmx:name=dataSourceMBean,type=ConnectionPool
    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:658)
    at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:603)
    ... 57 more

I can't find an easy way to fix this so I think we need to change spring.datasource.jmx-enabled to default to false and make this one opt-in.

@philwebb philwebb assigned philwebb and unassigned dsyer Nov 7, 2014
mocleiri pushed a commit to mocleiri/spring-boot that referenced this issue Apr 20, 2015
If the DataSource is a Tomcat one we force it to register an MBean
if spring.jmx.enabled=true

Fixes spring-projectsgh-1590
mocleiri pushed a commit to mocleiri/spring-boot that referenced this issue Apr 20, 2015
Change the default value of spring.datasource.jmx-enabled to false
to prevent InstanceAlreadyExistsException problems when using the
Spring Test Framework.

Fixes spring-projectsgh-1590
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants