Wednesday, December 3, 2008

Injecting JNDI datasource for JUnit test cases in Hibernate/JBoss environment

Recently a project in which I am working with had faced a little bit nuisance in having to maintain a seperate set of hibernate configuration for JUnit test cases.

The application is using JBoss application server, so the hibernate.cfg.xml has data source and transaction lookup class configuration specific to JBoss.

Since JUnit test cases are run outside the container, it had to be replaced with hibernate's default transaction and Database Connection pool configurations.

Snippet of Production configuration

<property name="hibernate.connection.datasource">java:/mysqldatasource</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<property name="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>

What was used for the JUnit run

<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mysqldb</property>
<property name="hibernate.connection.username">someuser</property>
<property name="hibernate.connection.password">somepwd</property>

The problem with using the actual configuration is that for datasource and transaction manager jndi lookup, the respective object must be bound in a JNDI server.

The following blog explains how to do it.

I am going explain further in JBoss context.

It is a common practice that when Hibernate is used with JBoss the transaction manager used will be that of JBoss. This is done in Hibernate using the following hibernate properties.

 <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<property name="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>

JBossTransactionManagerLooup class in Hibernate does two jndi looups using "java:/TransactionManager" and "UserTransaction" for obvious objects. This necessitates that TransactionManager and UserTransaction implementation from JBoss has to be bound against those names respectively.

A few minutes of searching says following are the classes

import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple;
import com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple;

It possed another issue. Both of them are not Serializable and transient objects can not be bound to JNDI!!.

Well the only solution I found was to create dummy extesion classes and implement Serializable interface

//Created to avoid serialization error while binding to the jndi
private static class CustomTXNManager extends TransactionManagerImple implements Serializable {

private static final long serialVersionUID = 1L;

public CustomTXNManager() {

// Created to avoid serialization error while binding to the jndi
private static class CustomUserTransaction extends UserTransactionImple implements Serializable {

private static final long serialVersionUID = 1L;

public CustomUserTransaction() {

TransactionManager tm = new CustomTXNManager();
ic.bind("java:/TransactionManager", tm);

UserTransaction ut = new CustomUserTransaction();

These can be included in a base JUnit class with a static block. The properties can be externalized in a properties file to reduce the hard coded parts. Below is the entire static block declaration and a static util method I have used.

    static {

try {
// Create initial context

Properties props = new Properties();

System.setProperty(Context.URL_PKG_PREFIXES, props

System.setProperty(Context.INITIAL_CONTEXT_FACTORY, props

// to avoid discoverServer error
NamingServer server = new NamingServer();

// Construct DataSource
MysqlConnectionPoolDataSource ds = new MysqlConnectionPoolDataSource();
// For Oracle database use the following (no common interface, hence
// can't generalize; well reflection would help)
// OracleConnectionPoolDataSource ds = new
// OracleConnectionPoolDataSource();

InitialContext ic = new InitialContext();

String dsName = props.getProperty("");

String[] cxts = dsName.split("/");

String inCxt = cxts[0];
createSubcontext(ic, inCxt);
for (int i = 1; i < cxts.length - 1; i++) {
// if the data source name is like java:/comp/mysqldatasource
// this takes care of creating subcontexts in jndi
inCxt = inCxt + "/" + cxts[i];
createSubcontext(ic, inCxt);

ic.bind(dsName, ds);

// The following binding is done to support the hibernate properties
// hibernate.transaction.factory_class and transaction.manager_lookup_class

// the following requires JBoss dependent class. May be sth can be done
// to generalize this
TransactionManager tm = new CustomTXNManager();
ic.bind("java:/TransactionManager", tm);

UserTransaction ut = new CustomUserTransaction();

} catch (Exception e) {
// what can be done?


// copied from org.jboss.naming.Util
private static Context createSubcontext(Context ctx, String cxtName)
throws NamingException {
//System.out.println(" creating subcontext " + cxtName);
Context subctx = ctx;
Name name = ctx.getNameParser("").parse(cxtName);
for (int pos = 0; pos < name.size(); pos++) {
String ctxName = name.get(pos);
try {
subctx = (Context) ctx.lookup(ctxName);
} catch (NameNotFoundException e) {
subctx = ctx.createSubcontext(ctxName);
// The current subctx will be the ctx for the next name component
ctx = subctx;
return subctx;

Property file contents

Hope this information helps solving some of the issues you are facing. If you need some clarifications let me know.

Saturday, July 26, 2008

Getting exposed: My first blog

True to being a lazy person, after a few years since I first thought of writing blogs, today I have taken the plunge. Everything happened quickly, there wasn't any planning at all - so the weird name of the Blog.

Why do I want to write blog? - to impress others? to become famous? to educate others? to share my knowledge?. None of these, I just wanted to cement/enhance whatever I have already learned;by writing about them :). Till now I haven't done much writing other than coming up with work related documents though I am a voracious reader.

A recent talk I had attended made me realize the importance of writing vis-a-vis reading. The speaker was making a point that writing enhances ones knowledge and that it's not just about describing something one already know. In order to write something meaningful, one has to do a lot of research, update knowledge etc. Also the effort required is high; one has to structure the narration, articulate the content properly, use proper words.

So, what am I going to write about?

About my random thoughts :)
About movies.
About books.
About Software Technologies
About what I think one can do to better human lives.
About my country, countrymen.
And may be some other topics