Monday, January 11, 2010

Share a datasource among several applications in Tomcat using Atomikos

In a previous post I discussed about how to use Atomikos JTA implementation in Tomcat. We had a requirement of sharing a globally defined datasource among several applications deployed in Tomcat container. The datasource lookup from the one application (whichever does the lookup first) succeeds but it always fails from the second application with an error message like-

Another resource already exists with name DATA_SOURCE_NAME - pick a different name

Why? We were using the sample bean factory available at Atomikos' site, which tries to recreate the datasource on each lookup. Within an application one can cache the datasource after initial JNDI lookup call. But what about doing a lookup of same resource from multiple applications?

After poking around for a while in Atomikos source code I found that after creation, datasource instance is cached by the Atomikos. With a minor modification in bean factory as shown below, the cached instance can be retrieved instead of recreating it.
// see if this DataSource is already initialized then return cached object
// if available, else Atomikos will throw an exception
try {
    bean = IntraVmObjectRegistry.getResource(((AbstractDataSourceBean) bean).getUniqueResourceName());
    if (log.isInfoEnabled())
        log.info("Returning cached value of AbstractDataSourceBean (Atomikos): " + bean);

    return bean;
} catch (NameNotFoundException nfe) {
    // OK, it is not available go ahead and create one
}
With this change a globally defined datasource can be used by multiple applications inside a Tomcat container to use Atomikos JTA implementation.

6 Comments:

Prashanth said...

Hi Vinod,

Could u please suggest me how do I consume a web service, using J2SE.

I have googled enough, but everywhere i see people suggesting to use JAX-RPC or JAX-WS. But, i guess these are not readily-available jars in jdk/jre. Are these licensed jars?
Correct me if I am wrong.

My scenario is as follows:
* I have a WSDL URL,(which is not my localhost running App)
* I need to read the WSDL to know the SOAP req and SOAP resp of a specific method
* then invoke a web service/method.
* the limitation for me is i shouldnt use a licensed jar

Please also suggest me where can i find the required jars.

Thanks in advance.

Anonymous said...

@Prashant,

This Building JAX-Ws Web Service might be of your interest.

Rik said...

Hi Vinod,
I tried to insert your code snippet into BeanFactory, but still get the error:
Caused by: javax.naming.NamingException: Another resource already exists with name ...

Can you indicate exactly where in BeanFactory your code snippet should be inserted?

Thanks,
Rik

Anonymous said...

@Rik,

The source code available at JTA Transactions with Atomkios in Tomcat contains an implementation of BeanFactory, please have a look at that.

Rik said...

Thanks, Vinod! I will check it out.

Anonymous said...

Hi,

This post was really a big improvement, because now i got a way for removing old / stale names from atomikos. Many thanks :)

Bogdab