Results 1 to 8 of 8

Thread: JTA UserTransaction is not available at JNDI location [java

  1. #1

    Default JTA UserTransaction is not available at JNDI location [java

    Hi everybody,
    I am getting an exception related with jta when I am unit testing DAO objects that I created.
    My conf:
    - using spring+hibernate
    - using JTA as trans. mgm.
    - I have multiple datasources (Oracle,SQL Server)

    I am getting the following exception while I try to unit test my DAO class...
    Code:
    junit.framework.AssertionFailedError: Exception in constructor: testSaveAndRemoveUser (org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in URL [file:D:/Workspaces/SpringTestWS/SpringTemplate/WebContent/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception is [b]org.springframework.transaction.TransactionSystemException: JTA UserTransaction is not available at JNDI location [java:comp/UserTransaction];[/b] nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    org.springframework.transaction.TransactionSystemException: JTA UserTransaction is not available at JNDI location [java:comp/UserTransaction]; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:652)
    	at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:255)
    	at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:292)
    	at javax.naming.InitialContext.lookup(InitialContext.java:359)
    	at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:123)
    	at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:85)
    	at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:121)
    	at org.springframework.transaction.jta.JtaTransactionManager.lookupUserTransaction(JtaTransactionManager.java:346)
    	at org.springframework.transaction.jta.JtaTransactionManager.afterPropertiesSet(JtaTransactionManager.java:311)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:991)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:288)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:208)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:136)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:230)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:284)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;80&#41;
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;65&#41;
    	at com.elikasu.springtemplate.dao.BaseDAOTestCase.<init>&#40;BaseDAOTestCase.java&#58;20&#41;
    	at com.elikasu.springtemplate.dao.UserDAOTest.<init>&#40;UserDAOTest.java&#58;11&#41;
    	at java.lang.reflect.Constructor.newInstance&#40;Native Method&#41;
    	at junit.framework.TestSuite.createTest&#40;TestSuite.java&#58;131&#41;
    	at junit.framework.TestSuite.addTestMethod&#40;TestSuite.java&#58;114&#41;
    	at junit.framework.TestSuite.<init>&#40;TestSuite.java&#58;75&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.getTest&#40;RemoteTestRunner.java&#58;331&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests&#40;RemoteTestRunner.java&#58;369&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run&#40;RemoteTestRunner.java&#58;276&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main&#40;RemoteTestRunner.java&#58;167&#41;
    &#41;
    	at junit.framework.Assert.fail&#40;Assert.java&#58;47&#41;
    	at junit.framework.TestSuite$1.runTest&#40;TestSuite.java&#58;263&#41;
    	at junit.framework.TestCase.runBare&#40;TestCase.java&#58;127&#41;
    	at junit.framework.TestResult$1.protect&#40;TestResult.java&#58;106&#41;
    	at junit.framework.TestResult.runProtected&#40;TestResult.java&#58;124&#41;
    	at junit.framework.TestResult.run&#40;TestResult.java&#58;109&#41;
    	at junit.framework.TestCase.run&#40;TestCase.java&#58;118&#41;
    	at junit.framework.TestSuite.runTest&#40;TestSuite.java&#58;208&#41;
    	at junit.framework.TestSuite.run&#40;TestSuite.java&#58;203&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests&#40;RemoteTestRunner.java&#58;392&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run&#40;RemoteTestRunner.java&#58;276&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main&#40;RemoteTestRunner.java&#58;167&#41;

  2. #2
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    You should run your Tests inside a container that provide a UserTransaction or use an external OTM like JTOM.
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

  3. #3

    Default

    I am using WebSphere AppServer 5.1 . My tests work fine when using CactusStrutsTestCase for struts actions testing.
    This works fine:
    Code:
    public class UserActionTest extends CactusStrutsTestCase &#123;
    	public UserActionTest&#40;String arg0&#41; &#123;
    		super&#40;arg0&#41;;
    	&#125;
    
    	public static void main&#40;String&#91;&#93; args&#41; &#123;
    		junit.textui.TestRunner.run&#40;UserActionTest.class&#41;;
    	&#125;
    
    	public void testAddUser&#40;&#41;&#123;		
    		setRequestPathInfo&#40;"/user"&#41;;
    		addRequestParameter&#40;"method","save"&#41;;
    		addRequestParameter&#40;"user.firstName","Simon"&#41;;
    		addRequestParameter&#40;"user.lastName","Simon"&#41;;
    		actionPerform&#40;&#41;;
    		verifyForward&#40;"listUsers"&#41;;
    		verifyNoActionErrors&#40;&#41;;
    	&#125;
    &#125;
    But when I want to test my DAO classes which are defined in applicationContext.xml, I get the exception which is in my previous post. Dao test class:
    Code:
    public class UserDAOTest extends BaseDAOTestCase &#123;
    	private User user=null;
    	private UserDAO dao=null;
    	/* &#40;non-Javadoc&#41;
    	 * @see junit.framework.TestCase#setUp&#40;&#41;
    	 */
    
    	protected void setUp&#40;&#41; throws Exception &#123;
    		super.setUp&#40;&#41;;
    		logger=Logger.getLogger&#40;UserDAOTest.class&#41;;
    		dao=&#40;UserDAO&#41;ctx.getBean&#40;"userDAO"&#41;;
    	&#125;
    	public void testSaveUser&#40;&#41;&#123;
    		user=new User&#40;&#41;;
    		user.setFirstName&#40;"Meggie"&#41;;
    		user.setLastName&#40;"Glynhall"&#41;;
    		
    		dao.saveUser&#40;user&#41;;
    		assertTrue&#40;"primarykey assigned&#58;",user.getId&#40;&#41;!=null&#41;;
    		logger.info&#40;user&#41;;	
    		assertTrue&#40;user.getFirstName&#40;&#41;!=null&#41;;
    	&#125;
    &#125;
    and BaseDaoTestCase:

    Code:
    public class BaseDAOTestCase extends TestCase &#123;
    	protected static Logger logger = Logger.getLogger&#40;BaseDAOTestCase.class&#41;;
    	protected ApplicationContext ctx = null;
    
    	public BaseDAOTestCase&#40;&#41; &#123;		
    		String&#91;&#93; paths = &#123;"file&#58;D&#58;/Workspaces/SpringTestWS/SpringTemplate/WebContent/WEB-INF/applicationContext.xml"&#125;;
    		ctx = new ClassPathXmlApplicationContext&#40;paths&#41;;
    	&#125;
    &#125;
    Are there any examples of in-container testing with Spring...
    Thanks for your helps...

  4. #4
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    UserDAOTest / BaseDAOTestCase do not seem to be running inside a container. So one thing you can do is to extract the UserTransaction from Jndi and configure a JtaTransactionManager:
    Code:
    <bean id="userTransaction" class="org.springframework.jndi.JndiObjectFactoryBean"> 
        <property name="jndiName"> 
          <value>java&#58;comp/UserTransaction</value> 
        </property> 
        <property name="environment"> 
          <props> 
            <!-- provide WebSphere AppServer 5.1 environment properties here -->
            <prop key="key1">value1</prop> 
            <prop key="key2">value2</prop> 
            <prop key="key3">value3</prop> 
          </props> 
        </property> 
      </bean>
    
      <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <constructor-arg><ref local="userTransaction" /></contructor-arg>
      </bean>
    I never tried this before...
    I have however a question with regards to your Tests: Why are you Unit Testing your class inside the container? Did you consider UnitTesting the class outside of the container using a plain HibernateTransactionManager?

    HTH
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

  5. #5

    Default

    Thanks Omar,
    regarding to your question:
    I have however a question with regards to your Tests: Why are you Unit Testing your class inside the container?
    I don't really want to test my classes inside a container but I have defined my dataSources(3 XA DataSources) in my web-server (WebSphere 5.1). And I reach them through jndi:
    Code:
    <bean id="DB2DataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName">
            	<value>jdbc/DB2DS_XA</value>
            </property>
        </bean>
        <bean id="DB2DataSource2" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName">
            	<value>jdbc/DB2DS_XA2</value>
            </property>
        </bean>
        <bean id="SQLSRVDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName">
            	<value>jdbc/SQLSRV_XA</value>
            </property>
        </bean>
    How can I remove this dependency from container. How can I define my XA dataSources in applicationContext without depending on the container.
    Thanks,

  6. #6
    Join Date
    Aug 2004
    Location
    Linz, Austria
    Posts
    391

    Default

    If you don't actually need XA, i.e. in the case of a single DataSource respectively SessionFactory, you could use Spring's DataSourceTransactionManager or HibernateTransactionManager (just for test environments or also for production).

    In your case where you need XA for your three DataSources, you could use a local JOTM instance (ObjectWeb's JTA implementation) with locally defined XADataSources (instead of fetching DataSources from JNDI). This is directly supported in Spring: Have a look at JotmFactoryBean's javadoc.

    Obviously, you'd need to duplicate your DataSource configuration for the latter scenario (once for WebSphere, once for the local XADataSources), but as a benefit you'll be able to run your business code (depending on XA transactions) completely outside the J2EE server.

    Juergen

  7. #7
    Join Date
    Aug 2004
    Location
    Columbus, OH, USA
    Posts
    133

    Default

    Juergen, what if you used per-datasource transaction management (DataSourceTransactionManager or HibernateTransactionManager) just during development and unit testing, then to switch your Spring config to use JTA (JtaTransactionManager) when doing full integrated testing? Do you see a problem with this or is it just as easy to use JotmFactoryBean from the start? I'm in the same boat - I need JTA across multiple datasources, but I don't want to make testing a pain.

    Thanks in advance, Scott

  8. #8
    Join Date
    Aug 2004
    Location
    Toronto, Canada
    Posts
    736

    Default

    Well there's nothing wrong with switching your config later, per se, but you'll be going from non XA/2PC to XA/2PC with multiple datasources, then there are obviously differences in how things can interact. If you need to work with multiple datasources and XA, then going that route from the start might ensure you don't have surprises later. On the other hand, if somebody is eventually going to run in a container and need JTA, but currently don't really need it, as they only use one datasource, then it's very common to develop with something like HibernateTransactionManager, and later switch to JTATransactionManager when you switch containers...
    Colin Sampaleanu
    SpringSource - http://www.springsource.com

Similar Threads

  1. Replies: 3
    Last Post: Oct 5th, 2005, 08:39 AM
  2. Replies: 6
    Last Post: Sep 29th, 2005, 04:25 AM
  3. Replies: 0
    Last Post: Jul 11th, 2005, 05:49 PM
  4. Stack Overflow
    By rayho222 in forum Container
    Replies: 6
    Last Post: May 17th, 2005, 03:42 AM
  5. How to JNDI to Datasource?
    By wowo in forum Data
    Replies: 3
    Last Post: May 12th, 2005, 06:22 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •