-
15. Re: Universal Connection Pooling in JBoss 7.1.1
snjv180 Dec 3, 2012 6:57 AM (in response to sourcedev)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 Dec 3, 2012 7:33 AM (in response to snjv180)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 Dec 10, 2012 11:49 AM (in response to 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 May 22, 2013 3:25 AM (in response to sourcedev)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 ???