1 2 Previous Next 18 Replies Latest reply on May 22, 2013 3:25 AM by fillg1 Go to original post
      • 15. Re: Universal Connection Pooling in JBoss 7.1.1
        snjv180

        Hello Source Dev,

         

        Could you please post some of your code and procedure so that people may get some help for solving this issue. I hope people will get some help by using your method.

         

        Thanks for the update even after such a long time. I will be very thankful for this because the number of views in this issue has been overwhelming. I think a lot of us would be enthusiastic to know your method.

         

        Thanks.

         

        Cheers,

        Sanjeev

        • 16. Re: Universal Connection Pooling in JBoss 7.1.1
          sourcedev

          Hi,

           

          The crux of it is actually binding the UCP.  But here's the lot. 

           

          I defined the pools and their JNDI bind name in spring.  Here's a single pool example:

           


          <util:map id="ucpDatasourceByJndiName" >
            <entry key="myDataSourceJNDI" value-ref="myUcp"/>

          </util:map>

           


          <bean id="myUcp" class="oracle.ucp.jdbc.PoolDataSourceImpl">
              <property name="ConnectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/>
              <property name="ConnectionPoolName" value="myPoolName"/>
              <property name="URL" value="jdbc:oracle:thin:@host:1234/SERVICE"/>
              <property name="User" value="user"/>
              <property name="Password" value="password"/>
              <property name="MinPoolSize" value="20"/>
              <property name="MaxPoolSize" value="50"/>
              <property name="InitialPoolSize" value="20"/>
              <property name="connectionWaitTimeout" value="20"/>
              <property name="InactiveConnectionTimeout" value="20"/>
              <property name="TimeoutCheckInterval" value="60"/>
             

          <property name="ValidateConnectionOnBorrow" value="true"/>

              <property name="maxStatements" value="0"/>

          </bean>

           

          Then defined a ServiceActivator class to read the pool from the spring context and bind it.  Had to work around a TCCL bug here too.

           

          package mypackage;

           

          import java.util.Map;

           

          import oracle.ucp.UniversalConnectionPoolAdapter;

          import oracle.ucp.UniversalConnectionPoolException;

          import oracle.ucp.admin.UniversalConnectionPoolManager;

          import oracle.ucp.admin.UniversalConnectionPoolManagerImpl;

          import oracle.ucp.jdbc.PoolDataSource;

           

          import org.apache.commons.logging.Log;

          import org.apache.commons.logging.LogFactory;

          import org.jboss.as.naming.ManagedReference;

          import org.jboss.as.naming.ManagedReferenceFactory;

          import org.jboss.as.naming.ServiceBasedNamingStore;

          import org.jboss.as.naming.deployment.ContextNames;

          import org.jboss.as.naming.service.BinderService;

          import org.jboss.msc.service.ServiceActivator;

          import org.jboss.msc.service.ServiceActivatorContext;

          import org.jboss.msc.service.ServiceBuilder;

          import org.jboss.msc.service.ServiceName;

          import org.jboss.msc.service.ServiceRegistryException;

          import org.springframework.context.ApplicationContext;

          import org.springframework.context.support.ClassPathXmlApplicationContext;

           

          public class UcpJBossServiceActivator implements ServiceActivator {

             

              private static final Log LOG = LogFactory.getLog(ServiceActivator.class);

             

              @Override

              public void activate(ServiceActivatorContext serviceActivatorContext) throws ServiceRegistryException {

                 

                  LOG.info("Activating UCP Datasource Registration Service...");

                         

                  // JBoss does not set the TCCL for some reason so we need to do this before

                  // we try to load resources on the sar-specific classpath or we won't find them

                  ClassLoader previousTCCL = Thread.currentThread().getContextClassLoader();

           

                  try {

                      Thread.currentThread().setContextClassLoader(UcpJBossServiceActivator.class.getClassLoader());

           

                      for (Map.Entry<String, PoolDataSource> entry : getUcpDataSourcesByJndiName().entrySet()) {

           

                          String jndiName = entry.getKey();

                          PoolDataSource ucpDatasource = entry.getValue();

           

                          // UCP construction

                          try {

                              createConnectionPool(ucpDatasource);

                              startConnectionPool(ucpDatasource);

                          }

                          catch (UniversalConnectionPoolException e) {

                              throw new ServiceRegistryException(e);

                          }

           

                          // UCP JNDI bind

                          bindUcpDataSource(serviceActivatorContext, jndiName, ucpDatasource);

                         

                      }

           

                  } finally {

           

                      Thread.currentThread().setContextClassLoader(previousTCCL);

           

                  }

           

              }

                 

              /***********************************************************************************************/

              /*                                                                                             */

              /*                              UCP CONSTRUCTION METHODS                                       */

              /*                                                                                             */

              /***********************************************************************************************/

             

              /*

               * Reads the list of UCP datasources and their jndi binding name from the spring config

               */

              @SuppressWarnings("unchecked")

              private Map<String, PoolDataSource> getUcpDataSourcesByJndiName() {  

                 

                  ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-oracle-ucp-datasources.xml");

                  return (Map<String,PoolDataSource>) ctx.getBean("ucpDatasourceByJndiName");       

              }

             

              /*

               * Asks the UCP Manager to create the connection pool

               */

              private void createConnectionPool(PoolDataSource ucpDatasource) throws UniversalConnectionPoolException {

                 

                  String poolName = ucpDatasource.getConnectionPoolName();

                  LOG.info((new StringBuilder()).append("Creating UCP DS (").append(poolName).append(")...").toString());

                 

                  getUcpManager().createConnectionPool((UniversalConnectionPoolAdapter) ucpDatasource);

                 

                  LOG.info((new StringBuilder()).append("Created UCP DS (").append(poolName).append(")").toString());

              }

           

              /*

               * Asks the UCP Manager to start the connection pool

               */

              private void startConnectionPool(PoolDataSource ucpDatasource) throws UniversalConnectionPoolException {

                 

                  String poolName = ucpDatasource.getConnectionPoolName();

                  LOG.info((new StringBuilder()).append("Staring UCP DS (").append(poolName).append(")...").toString());

                 

                  getUcpManager().startConnectionPool(poolName);

                 

                  LOG.info((new StringBuilder()).append("Started UCP DS (").append(poolName).append(")").toString());

              }

           

              /*

               * Asks the UCP Manager to destory the connection pool

               */

              private void destroyConnectionPool(PoolDataSource ucpDatasource) throws UniversalConnectionPoolException {

                 

                  String poolName = ucpDatasource.getConnectionPoolName();

                  LOG.info((new StringBuilder()).append("Destroying UCP DS (").append(poolName).append(")...").toString());

                 

                  getUcpManager().destroyConnectionPool(poolName);

                 

                  LOG.info((new StringBuilder()).append("Destroyed UCP DS (").append(poolName).append(")").toString());

              }

           

              private UniversalConnectionPoolManager getUcpManager() throws UniversalConnectionPoolException {

                  return UniversalConnectionPoolManagerImpl.getUniversalConnectionPoolManager();

              }

             

              /***********************************************************************************************/

              /*                                                                                             */

              /*                                UCP JNDI BIND METHODS                                        */

              /*                                                                                             */

              /***********************************************************************************************/

           

              /*

               * Binds a UCP datasource to the jndi context using the name provided

               */

              private void bindUcpDataSource (ServiceActivatorContext serviceActivatorContext, String jndiName, PoolDataSource ucpDatasource) {

                 

                  String poolName = ucpDatasource.getConnectionPoolName();

                  LOG.info((new StringBuilder()).append("Binding UCP DS (").append(poolName).append(") to JNDI (").append(jndiName).append(")...").toString());

           

                  final ServiceName bindingServiceName = ContextNames.JAVA_CONTEXT_SERVICE_NAME.append("datasource").append(jndiName);

                  final BinderService binderService = new BinderService(jndiName);

                  ServiceBuilder<ManagedReferenceFactory> builder = serviceActivatorContext.getServiceTarget().addService(bindingServiceName, binderService);

                  builder.addDependency(ContextNames.JAVA_CONTEXT_SERVICE_NAME, ServiceBasedNamingStore.class, binderService.getNamingStoreInjector());

                  binderService.getManagedObjectInjector().inject(new UcpDsManagedReferenceFactory(ucpDatasource));

                  builder.install();

                 

                  LOG.info((new StringBuilder()).append("Bound UCP DS (").append(poolName).append(") to JNDI (").append(jndiName).append(")").toString());

              }

           

              /*

               * All bindable objects must be provided to JBoss via a ManagedReferenceFactory

               */

              private class UcpDsManagedReferenceFactory implements ManagedReferenceFactory {

           

                  private final PoolDataSource ucpDs;

           

                  public UcpDsManagedReferenceFactory(final PoolDataSource ucpDs) {

                      this.ucpDs = ucpDs;

                  }

           

                  public ManagedReference getReference() {

           

                      return new ManagedReference() {

                         

                          public void release() {

                             

                              try {

                                  destroyConnectionPool(ucpDs);

                              } catch (UniversalConnectionPoolException e) {

                                  LOG.error((new StringBuilder()).append("Failed to destroy UCP DS (").append(ucpDs.getConnectionPoolName()).append(")"), e);

                              }

                          }

           

                          public Object getInstance() {

                             

                              return ucpDs;

                          }

                      };

                  }

              }

           

          }

           

          Then I wrapped the service activator class and spring config into a .sar file, ensuring that the service activator was defined in the META-INF/services/org.jboss.msc.service file.  On top of that, I defined a module containing the usual Oracle ons, ucp and jdbc jars (com.oracle.ucp), another for spring (org.springframework.spring), and configured the sar's jboss-deployment-structure.xml to have dependencies like so:

           

          <dependencies>
              <module name="javax.api"/>
              <module name="org.jboss.as.naming"/>
              <module name="org.jboss.msc"/>
              <module name="org.apache.commons.logging"/>
          <module name="com.oracle.ucp"/>
              <module name="org.springframework.spring">
                  <imports>
                      <include path="META-INF**"/>
                      <include path="org**"/>
                  </imports>
              </module>
          </dependencies>

           

          Hope it helps.

           

          Cheers,

           

          Alex

          • 17. Re: Universal Connection Pooling in JBoss 7.1.1
            sourcedev

            Hi,

             

            One final point - I have not been able to get UCP working for an XA connection on JBoss 6 EAP. 

             

            The issue here is that:

            a) if you initialise a UCP pool outside the JBoss JCA container, you have to jump through hoops to enlist (and recover) resources with the transaction manager (no idea how but assume not easy)

            b) if you initialise a UCP pool inside the JBoss JCA container, you get a nasty LinkageError where the UCP is trying to load the XAResource interface from a different location than the boot classloader:

             

            Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of <bootloader>) previously initiated loading for a different type with name "javax/transaction/xa/XAResource"

            at java.lang.Class.getDeclaredMethods0(Native Method) [rt.jar:1.6.0_31]

            at java.lang.Class.privateGetDeclaredMethods(Class.java:2427) [rt.jar:1.6.0_31]

            at java.lang.Class.privateGetPublicMethods(Class.java:2547) [rt.jar:1.6.0_31]

            at java.lang.Class.getMethods(Class.java:1410) [rt.jar:1.6.0_31]

            at sun.misc.ProxyGenerator.generateClassFile(ProxyGenerator.java:409) [rt.jar:1.6.0_31]

            at sun.misc.ProxyGenerator.generateProxyClass(ProxyGenerator.java:306) [rt.jar:1.6.0_31]

            at java.lang.reflect.Proxy.getProxyClass(Proxy.java:501) [rt.jar:1.6.0_31]

            at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581) [rt.jar:1.6.0_31]

            at oracle.ucp.jdbc.proxy.XAConnectionProxyFactory.createConnectionProxy(XAConnectionProxyFactory.java:78) [ucp.jar:11.2.0.1.0]

            at oracle.ucp.jdbc.PoolXADataSourceImpl.getXAConnection(PoolXADataSourceImpl.java:219) [ucp.jar:11.2.0.1.0]

            at oracle.ucp.jdbc.PoolXADataSourceImpl.getXAConnection(PoolXADataSourceImpl.java:163) [ucp.jar:11.2.0.1.0]

            at org.jboss.jca.adapters.jdbc.xa.XAManagedConnectionFactory.getXAManagedConnection(XAManagedConnectionFactory.java:430)  ... 17 more 

             

            So for XA support using UCP, I think JBoss 5 EAP is the final version where it will work.  Managed to get over numerous jumps trying to get to EAP 6 (HornetQ dropping JDBC support being one of them) but this is a bit of a show-stopper for us and I don't have the 'know how' to resolve using either of the two routes above.

             

            Hopefully someone else will or we will be limited to upgrading from JBoss 4.3 EAP to JBoss 5 EAP, which makes me rather depressed when there's a nice shiny EAP 6 available.

             

            Cheers,

             

            A

            • 18. Re: Universal Connection Pooling in JBoss 7.1.1
              fillg1

              Any news on this issue ?

               

              I'm trying this on EAP 6 with with no success

               

              I've defined and deployed an oracle.jdbc module

               

              <?xml version="1.0" encoding="UTF-8"?>

              <module xmlns="urn:jboss:module:1.0" name="oracle.jdbc">

                  <resources>

                      <resource-root path="ojdbc6-11.2.0.1.0-Patch11814893.jar"/>

                      <resource-root path="ucp-11.2.jar"/>

                      <resource-root path="ons-11.2.jar"/>

                  </resources>

                  <dependencies>

                      <module name="javax.api"/>

                      <module name="javax.transaction.api"/>

                  </dependencies>

              </module>

               

              then I define a new DS

               

              <datasources>

                  <xa-datasource jndi-name="java:jboss/datasources/myDS" pool-name="myDS" enabled="true" use-ccm="false">

                       <driver>oracle.jdbc</driver>

                      <xa-datasource-property name="URL">

                          jdbc:oracle:thin:XXXX:1521:XXXXX

                      </xa-datasource-property>

                      <xa-datasource-property name="ConnectionFactoryClassName">

                          oracle.jdbc.xa.client.OracleXADataSource

                      </xa-datasource-property>

                      <xa-datasource-class>oracle.ucp.jdbc.PoolXADataSourceImpl</xa-datasource-class>

                      <xa-pool>

                          <is-same-rm-override>false</is-same-rm-override>

                          <interleaving>false</interleaving>

                          <pad-xid>false</pad-xid>

                          <wrap-xa-resource>false</wrap-xa-resource>

                      </xa-pool>

                      <security>

                          <user-name>XXX</user-name>

                          <password>xxx</password>

                      </security>

                      <validation>

                          <validate-on-match>false</validate-on-match>

                          <background-validation>false</background-validation>

                      </validation>

                      <statement>

                          <share-prepared-statements>false</share-prepared-statements>

                      </statement>

                  </xa-datasource>

                  <drivers>

                      <driver name="oracle.jdbc" module="oracle.jdbc">

                          <xa-datasource-class>oracle.ucp.jdbc.PoolXADataSourceImpl</xa-datasource-class>

                      </driver>

                  </drivers>

              </datasources>

               

              I got an exception after "Test Connection"

               

              Caused by: java.lang.ClassNotFoundException: oracle.jdbc.xa.client.OracleXADataSource from [Module "org.jboss.as.connector:main" from local module loader @6425b780 (roots: D:\Tools\jbdevstudio\runtimes\jboss-eap\modules)]

                  at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190) [jboss-modules.jar:1.1.3.GA-redhat-1]

                  at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468) [jboss-modules.jar:1.1.3.GA-redhat-1]

                  at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456) [jboss-modules.jar:1.1.3.GA-redhat-1]

                  at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) [jboss-modules.jar:1.1.3.GA-redhat-1]

                  at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120) [jboss-modules.jar:1.1.3.GA-redhat-1]

                  at java.lang.Class.forName0(Native Method) [rt.jar:1.7.0_17]

                  at java.lang.Class.forName(Class.java:266) [rt.jar:1.7.0_17]

                  at oracle.ucp.jdbc.PoolDataSourceImpl.initConnectionFactory(PoolDataSourceImpl.java:2440)

                  ... 48 more

               

              Obviously the PoolDataSourceImpl class is located in the ucp.jar and can't find  the OracleXADataSource from the ojdbc6.jar of the same module ??? 

              1 2 Previous Next