jndi lookup issue

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

jndi lookup issue

gersav
I have been trying to configure my Spring\Hibernate\Tomcat application for use with BTM, and have been following, as close as possible, the example discussed in thread

Hibernate-JTATransactionFactory-and-BTMTransactionManagerLookup

with the same objective of constraining the configuration within Spring.

However, I get the following exception on startup,

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource-x: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1260)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:438)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:383)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:353)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:245)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:169)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:242)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:269)
        ... 70 more
Caused by: javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
        at org.apache.naming.NamingContext.lookup(NamingContext.java:770)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
        at org.apache.naming.SelectorContext.lookup(SelectorContext.java:137)
        at javax.naming.InitialContext.lookup(Unknown Source)
        at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:132)
        at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:88)
        at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:130)
        at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:155)
        at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:93)
        at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
        at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:197)
        at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:184)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1288)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1257)
        ... 79 more

The dataSource is defined as follows,

    <bean id="dataSource-x class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init" destroy-method="close">
                 <property name="className" value="com.microsoft.sqlserver.jdbc.SQLServerXADataSource" /> 
                 <property name="uniqueName" value="jdbc/datasource-X" /> 
                 <property name="minPoolSize" value="1" /> 
                 <property name="maxPoolSize" value="10" /> 
                 <property name="acquisitionInterval" value="1" /> 
                 <property name="acquisitionTimeout" value="15" /> 
                 <property name="maxIdleTime" value="15" /> 
                 <property name="testQuery" value="select count(*) from dbo.sysobjects" /> 
                 <property name="automaticEnlistingEnabled" value="true" /> 
                 <property name="allowLocalTransactions" value="true" /> 
                 <property name="driverProperties" >
                  <props>
                  <prop key="user">sa</prop>
                  <prop key="password">sa</prop>
                  <prop key="serverName">testServer</prop>
                  <prop key="databaseName">dbName</prop>
                  <prop key="uRL">jdbc:sqlserver://testServer/dbName</prop>

                  </props> 
                 </property>
  </bean>       

The Hibernate config is,
        <property name="connection.datasource">jdbc/datasource-X</property>
        <property name="hibernate.current_session_context_class">jta</property>
        <property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
        <property name="hibernate.transaction.manager_lookup_class">com.test.jtatomcatinfrastructure.server.service.BtmTransactionManagerLookup</property>
        <property name="hibernate.connection.release_mode">after_statement</property>
        <property name="hibernate.jndi.class">bitronix.tm.jndi.BitronixInitialContextFactory</property>
        <property name="jta.UserTransaction">btmUserTransaction</property>

       
and the Spring Persistence Unit Manager is,

        <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
                <property name="dataSources">
                        <map>
                                <entry key="jdbc/dataSource-x"
                                        value-ref="datasource-X" />
                                <entry key="jdbc/dataSource-y"
                                        value-ref="dataSource-Y" />
                        </map>
                </property>
                <property name="defaultDataSource" ref="dataSource-xl" />
        </bean>


Although the configuration tells Hibernate to use the BTM jndi provider, I think the exception is caused because Spring is not configured to  use the BTM jndi provider.

I can't find an example of how to configure Spring to use the BTM jndi provider. As I mentioned before, I'd prefer to contain any configuration within Spring, rather than have to adapt Tomcat to use the BTM jndi provider.

Any suggestions
Reply | Threaded
Open this post in threaded view
|

Re: jndi lookup issue

gersav
for info, I avoided this by not using jndi to reference any data source within Spring. This meant removing the Spring PersistenceUnitManager I was using to associate the dataSource with its associated Spring LocalContainerEntityManagerFactoryBean. using the LocalContainerEntityManagerFactoryBean dataSource property to wire the datsource directly avoided the jndi issue.

One other interesting thing I found during this is that, even though I was configuring the JtaTransactionManager to 'depends-on' the bitronix TransactionManagerServices to load the configuration,

<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices">
        <property name="serverId" value="vision-server-id"></property>
        <property name="jndiUserTransactionName" value="btmUserTransaction"></property>
        <property name="defaultTransactionTimeout" value="120"></property>
</bean>

<bean id="bitronixTransactionManager" factory-method="getTransactionManager"
        class="bitronix.tm.TransactionManagerServices"
        depends-on="btmConfig" destroy-method="shutdown" /> 

<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"
        depends-on="btmConfig,bitronixTransactionManager">
        <property name="transactionManager" ref="bitronixTransactionManager"/>
       <property name="userTransaction" ref="bitronixTransactionManager"/>               
</bean>

I was still getting an exception as follows on startup,
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'serverId' threw exception; nested exception is java.lang.IllegalStateException: cannot change the configuration while the transaction manager is running
PropertyAccessException 2: org.springframework.beans.MethodInvocationException: Property 'jndiUserTransactionName' threw exception; nested exception is java.lang.IllegalStateException: cannot change the configuration while the transaction manager is running
PropertyAccessException 3: org.springframework.beans.MethodInvocationException: Property 'defaultTransactionTimeout' threw exception; nested exception is java.lang.IllegalStateException: cannot change the configuration while the transaction manager is running

I think this was because, although the dependency order had been mapped out in Spring, the TransactionManager was being created when the Hibernate SessionFactory was being created. Hibernate SessionFactoryImpl calls BtmTransactionManagerLookup which calls, in turn TransactionManagerServices.getTransactionManager.

So, I guess the workaround for this is either to replace the btmConfig Spring bean with the btm properties file to ensure the configuration is set when the Configuration class is instantiated, or to override the Hibernate BtmTransactionManagerLookup class behaviour