Uploaded image for project: 'JBoss Web Server'
  1. JBoss Web Server
  2. JWS-970

JMX MBean "tomcat.jdbc" is not registered when type="javax.sql.XADataSource" is specfied to datasource resource

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Critical Critical
    • JWS 5.0_RHEL ER2
    • JWS 3.1.0 SP2 GA
    • tomcat
    • None
    • Hide

      1. Install and configure postgresql
      2. Drop the following Resource into your conf/server.xml's GlobalNamingResources block:

        <Resource name="jdbc/TestDB" type="javax.sql.XADataSource"
                  factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
                  auth="Container" 
                  username="postgres"
                  password="postgres"
                  maxActive="100"
                  minIdle="10"
                  jmxEnabled="true"
                  driverClassName="org.postgresql.Driver"
                  url="jdbc:postgresql://localhost:5432/test" />
      

      3. Start tomcat and verify that there are no errors (verify that it can find the Driver, etc)
      4. Check for existence of DataSource MBean. Open JConsole, attach to process, click MBeans tab, then click tomcat.jdbc -> ConnectionPool -> "jdbc/TestDB" to view the MBean.

      You can use the JMXProxyServlet in step four above, but I don't have time to find the syntax for you.

      Show
      1. Install and configure postgresql 2. Drop the following Resource into your conf/server.xml's GlobalNamingResources block: <Resource name="jdbc/TestDB" type="javax.sql.XADataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" auth="Container" username="postgres" password="postgres" maxActive="100" minIdle="10" jmxEnabled="true" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/test" /> 3. Start tomcat and verify that there are no errors (verify that it can find the Driver, etc) 4. Check for existence of DataSource MBean. Open JConsole, attach to process, click MBeans tab, then click tomcat.jdbc -> ConnectionPool -> "jdbc/TestDB" to view the MBean. You can use the JMXProxyServlet in step four above, but I don't have time to find the syntax for you.

      JMX MBean "tomcat.jdbc" is not registered when type="javax.sql.XADataSource" is specfied to datasource resource. Same issue happens on both Tomcat 7 and 8.

      <Context>
      
        ...(snip)...
        <!-- MBean is registered correctly with type="javax.sql.DataSource" -->
        <!-- <Resource name="jdbc/TestDB" type="javax.sql.DataSource" -->
        <!-- But MBean is NOT registered with type="javax.sql.XADataSource" -->
        <Resource name="jdbc/TestDB" type="javax.sql.XADataSource"
                  factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
                  auth="Container" 
                  username="postgres"
                  password="postgres"
                  maxActive="100"
                  minIdle="10"
                  jmxEnabled="true"
                  driverClassName="org.postgresql.Driver"
                  url="jdbc:postgresql://localhost:5432/test" />
      
      </Context>
      

      It looks o.a.c.core.NamingContextListener checks "javax.sql.DataSource" and register MBean only for "javax.sql.DataSource" resource. I think this should allow "javax.sql.XADataSource", too.

      java/org/apache/catalina/core/NamingContextListener.java
      1058     /**
      1059      * Set the specified resources in the naming context.
      1060      */
      1061     public void addResource(ContextResource resource) {
      1062 
       : 
      1086
      1087         if ("javax.sql.DataSource".equals(ref.getClassName()) &&      // <--- This only passes when resource is "javax.sql.DataSource" !!!
      1088                 resource.getSingleton()) {
      1089             try {
      1090                 ObjectName on = createObjectName(resource);
      1091                 Object actualResource = envCtx.lookup(resource.getName());
      1092                 Registry.getRegistry(null, null).registerComponent(actualResource, on, null);   // <-- Register MBean here 
      1093                 objectNames.put(resource.getName(), on);
      1094             } catch (Exception e) {
      1095                 logger.warn(sm.getString("naming.jmxRegistrationFailed", e));
      1096             }
      1097         }
      1098 
      1099     }
      

      The following is a proposed patch for Tomcat 8. I confirmed this resolved the issue in my local testing. Also same patch worked on Tomcat 7.

      diff --git a/java/org/apache/catalina/core/NamingContextListener.java b/java/org/apache/catalina/core/NamingContextListener.java
      index f4c91f5..6ba346f 100644
      --- a/java/org/apache/catalina/core/NamingContextListener.java
      +++ b/java/org/apache/catalina/core/NamingContextListener.java
      @@ -1084,7 +1084,8 @@ public class NamingContextListener
                   logger.error(sm.getString("naming.bindFailed", e));
               }
       
      -        if ("javax.sql.DataSource".equals(ref.getClassName()) &&
      +        if (("javax.sql.DataSource".equals(ref.getClassName()) ||
      +            "javax.sql.XADataSource".equals(ref.getClassName())) &&
                       resource.getSingleton()) {
                   try {
                       ObjectName on = createObjectName(resource);
      

            rhn-support-csutherl Coty Sutherland
            rhn-support-mmiura Masafumi Miura
            Matus Madzin Matus Madzin
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: