Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Problem running JUNIT test with JNDI datasource

  1. #1
    Join Date
    Apr 2005
    Posts
    6

    Default Problem running JUNIT test with JNDI datasource

    I am trying to run the junit test outside the container and having a problem running it with a jndi datasource specified in the applicationContext file for spring.

    In my unit test, I create an application context and include the spring files to use the same jndi data source my application uses. This fails during initalization itself as the jndi datasource is not available outside the j2ee container.

    I tried using org.springframework.mock.jndi, this creates a datasource and binds it to the same name specified in the spring context file. I dont know if I should then put that in any other place so that the spring context file can recognize this jndi datasource.

    I need to some how get in between that and initialize the datasource before it fails for my unit tests. Any suggestions on how to do the same?

    I get the following error:

    java.lang.ExceptionInInitializerError
    at sun.reflect.NativeConstructorAccessorImpl.newInsta nce0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInsta nce(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newI nstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Construc tor.java:274)
    at junit.framework.TestSuite.createTest(TestSuite.jav a:131)
    at junit.framework.TestSuite.addTestMethod(TestSuite. java:114)
    at junit.framework.TestSuite.<init>(TestSuite.java:75 )
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.getTest(RemoteTestRunner.java:360)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:398)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.run(RemoteTestRunner.java:305)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.main(RemoteTestRunner.java:186)
    Caused by: org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'serverJndiDataSource' defined in class path resource [edu/northwestern/snuper/dao/spring-data.xml]: Initialization of bean failed; 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
    at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:318)
    at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:223)
    at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:236)
    at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:159)
    at org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons(Defaul tListableBeanFactory.java:255)
    at org.springframework.context.support.AbstractApplic ationContext.refresh(AbstractApplicationContext.ja va:317)
    at org.springframework.context.support.ClassPathXmlAp plicationContext.<init>(ClassPathXmlApplicationCon text.java:80)
    at org.springframework.context.support.ClassPathXmlAp plicationContext.<init>(ClassPathXmlApplicationCon text.java:65)
    at edu.northwestern.snuper.core.BaseDatabaseTestCase. <clinit>(BaseDatabaseTestCase.java:76)

  2. #2
    Join Date
    Aug 2004
    Posts
    1,110

    Default

    Use a local datasource for testing rather than a JNDI one - there are plenty of examples in the samples - this is from jpetstore

    Code:
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    		<property name="driverClassName" value="$&#123;jdbc.driverClassName&#125;"/>
    		<property name="url" value="$&#123;jdbc.url&#125;"/>
    		<property name="username" value="$&#123;jdbc.username&#125;"/>
    		<property name="password" value="$&#123;jdbc.password&#125;"/>
    	</bean>
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

  3. #3
    Join Date
    Apr 2005
    Posts
    6

    Default

    I have all my beans in the context files which I use for the JUnit tests, to test my DAO's. I initialize the context files in the JUnit test as follows:

    String[] springFiles = {"spring-data.xml","spring-service.xml" };
    applicationContext = new ClassPathXmlApplicationContext(springFiles);

    I have to comment the JNDI datasource in the spring-data.xml and then run the tests as it fails to initialize, which I am trying to find a way around or I have to put the datasources in another file and not include it in the application context. Is there anyother way?

  4. #4

    Default

    have the application server running.

    i usually use the PropertyPlaceholderCOnfigure to hold the jndi settings.

    do this in your junit applicationCOntext.xml
    Code:
    <bean id="applicationServerEnviromentProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="properties">
        <props>
            <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
            <prop key="java.naming.provider.url">iiop&#58;//localhost&#58;9999</prop>
        </props>
    </property>
    
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
          <property name="jndiName"><value>yourDataSource</value></property>
    <property name="jndiEnvironment"><ref local="applicationServerEnviromentProperties"/></property>
    </bean>

    check your application server documentation for the correct naming factory, and provider url syntax.

    hope this helps.
    /^\\ Pharaoh /^\\
    http://pharaohofkush.blogspot.com/

    Jeryl Cook

  5. #5
    Join Date
    Aug 2004
    Location
    San Mateo, CA
    Posts
    1,265

    Default

    You don't need the app server running. Use a local datasource. Just pull out the DataSource/TransactionManager definition into a separate XML file, and use that instead of the JNDI/JTA one during testing. You can still use all the rest of your configuration.

    Try the org.springframework.test package in spring-mock.jar. This is designed for 100% out of container testing.
    Rod Johnson - GM, SpringSource Division, VMware
    http://www.springsource.com
    Spring From the Source

  6. #6

    Default

    I noticed this thread from a couple of years ago and I'm wondering if anything has changed as a result of SimpleNamingContextBuilder

    Any help appreciated

    Code:
    public class SomethingServiceTest extends AbstractTransactionalSpringContextTests {
    
        @Override
        @BeforeClass
        protected void onSetUpInTransaction() throws Exception {
    
            final SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
            final ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass("oracle.jdbc.OracleDriver");
            ds.setJdbcUrl("jdbc:oracle:thin:@128.129.145.88:1521:ANDDEVA");
            ds.setUser("CMS");
            ds.setPassword("CMS");
            ds.setMaxPoolSize(1);
            ds.setMaxPoolSize(15);
            ds.setAcquireIncrement(3);
            ds.setMaxStatementsPerConnection(100);
            ds.setAutomaticTestTable("c3p0_test_table");
            ds.setNumHelperThreads(20);
            builder.bind("java:comp/env/and/jdbc/WPSPool", ds);
            builder.activate();
        }
    Code:
        <bean id="dataSource"
            class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName" value="and/jdbc/WPSPool"/>
        </bean>
            
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
                    <prop key="hibernate.query.substitutions">true=1 false=0</prop>
                    <!--  <prop key="hibernate.cglib.use_reflection_optimizer">false</prop>				-->
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.jdbc.batch_size">0</prop>
                    <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
                    <prop key="hibernate.cache.use_query_cache">true</prop>
                </props>
            </property>
            <property name="mappingResources">
                <list>
                    <value>/uk/co/somewhere/domain/Answer.hbm.xml</value>
                </list>
            </property>
        </bean>
    Code:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor': Cannot create inner bean '(inner bean)' of type [org.springframework.transaction.interceptor.TransactionInterceptor] while setting bean property 'transactionInterceptor'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot resolve reference to bean 'transactionManager' while setting bean property 'transactionManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [transactional-context.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [persistence-context.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [persistence-context.xml]: Invocation of init method failed; 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
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot resolve reference to bean 'transactionManager' while setting bean property 'transactionManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [transactional-context.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [persistence-context.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [persistence-context.xml]: Invocation of init method failed; 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
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [transactional-context.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [persistence-context.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [persistence-context.xml]: Invocation of init method failed; 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
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [persistence-context.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [persistence-context.xml]: Invocation of init method failed; 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
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [persistence-context.xml]: Invocation of init method failed; 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
    Caused by: 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:645)
    
    
    ...
    
    	at org.springframework.test.AbstractSingleSpringContextTests.createApplicationContext(AbstractSingleSpringContextTests.java:199)
    	at org.springframework.test.AbstractSingleSpringContextTests.loadContextLocations(AbstractSingleSpringContextTests.java:179)
    	at org.springframework.test.AbstractSingleSpringContextTests.loadContext(AbstractSingleSpringContextTests.java:158)
    	at org.springframework.test.AbstractSpringContextTests.getContext(AbstractSpringContextTests.java:105)
    	at org.springframework.test.AbstractSingleSpringContextTests.setUp(AbstractSingleSpringContextTests.java:87)
    	at junit.framework.TestCase.runBare(TestCase.java:132)
    	at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
    	at junit.framework.TestResult$1.protect(TestResult.java:110)
    	at junit.framework.TestResult.runProtected(TestResult.java:128)
    	at junit.framework.TestResult.run(TestResult.java:113)
    	at junit.framework.TestCase.run(TestCase.java:124)
    	at junit.framework.TestSuite.runTest(TestSuite.java:232)
    	at junit.framework.TestSuite.run(TestSuite.java:227)
    	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:81)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

  7. #7

    Default

    AbstractTransactionalSpringContextTests was initializing context before my onSetUpInTransaction() was being called. So JNDI wasn't being initialized. Moved initialization code to Constructor

  8. #8
    Join Date
    Sep 2008
    Posts
    2

    Default

    Terrific solution with the SimpleNamingContextBuilder. Works for me. I chose to put this into a static constructor for my extended AbstractTransactionalDataSourceSpringContextTests base class since the datasource can only be bound once. Thanks!

  9. #9
    Join Date
    Sep 2004
    Posts
    602

    Default

    Quote Originally Posted by sudarshan_k View Post
    I have all my beans in the context files which I use for the JUnit tests, to test my DAO's. I initialize the context files in the JUnit test as follows:

    String[] springFiles = {"spring-data.xml","spring-service.xml" };
    applicationContext = new ClassPathXmlApplicationContext(springFiles);

    I have to comment the JNDI datasource in the spring-data.xml and then run the tests as it fails to initialize, which I am trying to find a way around or I have to put the datasources in another file and not include it in the application context. Is there anyother way?
    You can also code it so that you try and use a JNDI datasource, and if that is not there, use a DBCP one that is not in a JNDI namespace. To me this is the best solution, as you have a single context file for your datasource, that uses the JNDI datasource for running in the real world, and the test datasource for running in unit tests. Look at this example, specifically the defaultObject property on the JndiObjectFactoryBean :

    Code:
    <bean id="dataSource"
    		class="org.springframework.jndi.JndiObjectFactoryBean">
    
    		<property name="jndiName"
    			ref="applicationProperties[datasourceJNDIName]" />
    		<property name="defaultObject" ref="developmentDataSource" />
    	</bean>
    
    	<!-- fall back datasource if JNDI look up of main datasource fails -->
    
    	<bean id="developmentDataSource"
    		class="org.apache.commons.dbcp.BasicDataSource"
    		destroy-method="close">
    		<property name="driverClassName"
    			ref="applicationProperties[database.jdbc.driverClassName]" />
    		<property name="url" ref="applicationProperties[database.url]" />
    		<property name="username"
    			ref="applicationProperties[database.username]" />
    		<property name="password"
    			ref="applicationProperties[database.password]" />
    
    		<property name="initialSize">
    			<value>10</value>
    		</property>
    
    		<property name="maxActive">
    			<value>0</value>
    		</property>
    
    		<property name="maxWait">
    			<value>5000</value>
    		</property>
    
    	</bean>

  10. #10

    Default javax.naming.NoInitialContextException

    So I'm trying to follow Paul NewPort's suggestion of using a fallback default in order to run my integration tests but I'm getting a NoInitialContextException error.

    Here's the top of the stack trace:
    Code:
    WARN  2009-06-05 17:23:51,947 [main] impl.SessionFactoryObjectFactory  - Could not bind factory to JNDI
    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(Unknown Source)
    	at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
    	at javax.naming.InitialContext.getURLOrDefaultInitCtx(Unknown Source)
    	at javax.naming.InitialContext.getNameParser(Unknown Source)
    	at org.hibernate.util.NamingHelper.bind(NamingHelper.java:52)
    	at org.hibernate.impl.SessionFactoryObjectFactory.addInstance(SessionFactoryObjectFactory.java:90)
    	at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:306)
    	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294)
    	at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:814)
    	at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:732)
    	at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
    My spring config looks like this:
    Code:
    <bean id="dsWRITE" class="org.springframework.jndi.JndiObjectFactoryBean">
    	<property name="jndiName">
    		<value>java:jdbc/DSWriteSybaseServer</value>
    	</property>
    	<!--  fallback to a local datasource if we are not in the container -->
    	<property name="defaultObject" ref="developmentDataSource" />
    </bean>
    
    <bean id="developmentDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    	<property name="driverClassName" value="com.sybase.jdbc3.jdbc.SybDriver" />
    	<property name="url" value="jdbc:sybase:Tds:127.0.0.1:5000/asdf?charset=utf8" />
    	<property name="username" value="XXXX" />
    	<property name="password" value="XXXX" />
    
    	<property name="initialSize" value="10" />
    	<property name="maxActive" value="0" />
    	<property name="maxWait" value="5000" />
    </bean>
    
    <bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    	<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
    	<property name="dataSource" ref="dsWRITE" />
    </bean>
    and my hibernate.cfg.xml looks like this:
    Code:
    <session-factory name="hibernate/HibernateFactory">
    	<property name="hibernate.cache.use_query_cache">true</property>
    	<property name="hibernate.cache.use_second_level_cache">true</property>
    	<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
    	<property name="hibernate.cache.use_structured_entries">true</property>
    	<property name="current_session_context_class">jta</property>
    	<property name="hibernate.show_sql">false</property>
    	<property name="hibernate.dialect">org.hibernate.dialect.SybaseDialect</property>
    	
    	<!-- mappings here -->
    	
    </session-factory>
    Does anyone know what I'm doing wrong?

Similar Threads

  1. ApplicationContext returns null in Junit Test Case
    By penku in forum Spring-Modules
    Replies: 2
    Last Post: Sep 17th, 2005, 01:28 PM
  2. JBoss DataSource not found
    By moacsjr in forum Data
    Replies: 10
    Last Post: Aug 25th, 2005, 01:26 PM
  3. Replies: 5
    Last Post: May 4th, 2005, 10:49 PM
  4. Replies: 1
    Last Post: Feb 12th, 2005, 07:30 AM
  5. Ignoring missing Jndi DataSource within IDE?
    By Bill Pearce in forum Container
    Replies: 2
    Last Post: Oct 27th, 2004, 09:06 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
  •