0

I'm trying to unit test struts2 actions (hitting a real database), but I haven't been able to connect to the db successfully.

I'm new to Spring, and the project setup uses jdbctemplate in multiple beans and DAO classes.

Here's my attempt so far:

Test Class:

    public class Test extends StrutsSpringTestCase {

    private static final String serverURL = "jdbc:db2://xxxx.xxx.com:----/xxxx";
    private static final String username = "xxxxxxx";
    private static final String password = "xxxxxxx";

    @Override
    public String[] getContextLocations() {

    SimpleNamingContextBuilder s = new SimpleNamingContextBuilder();

    DB2SimpleDataSource db=new DB2SimpleDataSource(); 

    try {
    DriverManager.registerDriver( new com.ibm.db2.jcc.DB2Driver() );
    } catch (SQLException e2) {
    // TODO Auto-generated catch block
    e2.printStackTrace();
    }

    try {
    Class.forName("com.ibm.db2.jcc.DB2DataSource");
    } catch (ClassNotFoundException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }

    db.setServerName(serverURL);
    db.setPortNumber(----);
    db.setUser(username);
    db.setPassword(password);

    try {

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
     "com.ibm.websphere.naming.WsnInitialContextFactory");
    env.put(Context.PROVIDER_URL, "iiop://xxxx.xxx.com:----");
    Context ctx = new InitialContext(env);

    Context javaCtx = ctx.createSubcontext("jdbc");
    javaCtx.bind("xxx", db);
    ctx.bind("java:", javaCtx);

    } catch (IllegalStateException e) {
    e.printStackTrace();
    } catch (NamingException e) {
    e.printStackTrace();
    }

    String[] locations = new String[1];

    locations[0] = "xxxx.xml";

    return locations;
    }

    public void test() throws Exception {

    ActionProxy proxy = getActionProxy("/test");

    testAction rd = (testAction) proxy.getAction();

    System.out.println(rd.testMethod());

    }
    }

ApplicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<bean name="jndi" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/XXX" />
</bean>

<bean name="dataSource"     class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver"/>
<property name="url" value="jdbc:db2://----.---.com:xxxx/xxxx"/>
<property name="username" value="xxxxxxxx"/>
<property name="password" value="xxxxxxxx"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg>
    <ref bean="dataSource" />
</constructor-arg>

</bean>

<bean id="xxxxDao"
    class="xxxx">
    <property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>

(continues on with other DAO-related beans).

Many classes rely on JdbcTemplate, as seen below, so I'd like to find a solution that includes it:

private JdbcTemplate jdbcTemplate;
private String schemaName = "xxxxxx";
private String procedureName = "xxxxxx";

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
}

public RDResponseBO browseRD(RDRequestBO rdReqBO) {
    SimpleJdbcCall storedProc = new SimpleJdbcCall(jdbcTemplate)
            .withSchemaName(schemaName)
            .withoutProcedureColumnMetaDataAccess().withProcedureName(
                    procedureName); .........

My applicationContext.xml includes a datasource and a jndi bean, which is a little redundant. I don't know if it's possible to combine them both in JdbcTemplate in order to have the connection succeed.

Using the datasource alone results in a missing metadata/jdbc exception...and while i'd like to use the jndiobjectfactorybean class, the bean does not initialize in JUnit without running it through the server.

I tried including the jndi bean (after calling simplenamingcontextbuilder) in the jdbctemplate bean, which resulted in a matching constructor exception.

Ideas/Suggestions?

P.S. I apologize if the question format is a little off, I'm new to stackoverflow as well.

Stacktrace for jndi bean error:

            .springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcTemplate' defined in class path resource [beans.xml]: Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)
            at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:250)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
            at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
            at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
            at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
            at org.apache.struts2.StrutsSpringTestCase.setupBeforeInitDispatcher(StrutsSpringTestCase.java:39)
            at org.apache.struts2.StrutsTestCase.setUp(StrutsTestCase.java:187)
            at junit.framework.TestCase.runBare(TestCase.java:128)
            at junit.framework.TestResult$1.protect(TestResult.java:106)
            at junit.framework.TestResult.runProtected(TestResult.java:124)
            at junit.framework.TestResult.run(TestResult.java:109)
            at junit.framework.TestCase.run(TestCase.java:120)
            at junit.framework.TestSuite.runTest(TestSuite.java:230)
            at junit.framework.TestSuite.run(TestSuite.java:225)
            at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
            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)

JNDI error before using SimpleNamingContextBuilder:

            org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jndi' defined in class path resource [beans.xml]: Invocation of init method failed; nested exception is com.ibm.websphere.naming.CannotInstantiateObjectException: Exception occurred while the JNDI NamingManager was processing a javax.naming.Reference object. [Root exception is java.lang.NoClassDefFoundError: com.ibm.wsspi.runtime.service.WsServiceRegistry]
                at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
                at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
                at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
                at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
                at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
                at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
                at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
                at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
                at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
                at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
                at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
                at org.apache.struts2.StrutsSpringTestCase.setupBeforeInitDispatcher(StrutsSpringTestCase.java:39)
                at org.apache.struts2.StrutsTestCase.setUp(StrutsTestCase.java:187)
                at junit.framework.TestCase.runBare(TestCase.java:128)
                at junit.framework.TestResult$1.protect(TestResult.java:106)
                at junit.framework.TestResult.runProtected(TestResult.java:124)
                at junit.framework.TestResult.run(TestResult.java:109)
                at junit.framework.TestCase.run(TestCase.java:120)
                at junit.framework.TestSuite.runTest(TestSuite.java:230)
                at junit.framework.TestSuite.run(TestSuite.java:225)
                at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
                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)
            Caused by: com.ibm.websphere.naming.CannotInstantiateObjectException: Exception occurred while the JNDI NamingManager was processing a javax.naming.Reference object. [Root exception is java.lang.NoClassDefFoundError: com.ibm.wsspi.runtime.service.WsServiceRegistry]
                at com.ibm.ws.naming.util.Helpers.processSerializedObjectForLookupExt(Helpers.java:1033)
                at com.ibm.ws.naming.util.Helpers.processSerializedObjectForLookup(Helpers.java:730)
                at com.ibm.ws.naming.jndicos.CNContextImpl.processResolveResults(CNContextImpl.java:3691)
                at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1861)
                at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1762)
                at com.ibm.ws.naming.jndicos.CNContextImpl.lookupExt(CNContextImpl.java:1513)
                at com.ibm.ws.naming.jndicos.CNContextImpl.lookup(CNContextImpl.java:645)
                at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:166)
                at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:180)
                at javax.naming.InitialContext.lookup(InitialContext.java:455)
                at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
                at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
                at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
                at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
                at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
                at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
                at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:201)
                at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:187)
                at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
                at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
                ... 25 more
            Caused by: java.lang.NoClassDefFoundError: com.ibm.wsspi.runtime.service.WsServiceRegistry
                at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl$2.run(WSManagedConnectionFactoryImpl.java:835)
                at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
                at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.<init>(WSManagedConnectionFactoryImpl.java:840)
                at java.lang.J9VMInternals.newInstanceImpl(Native Method)
                at java.lang.Class.newInstance(Class.java:1325)
                at com.ibm.ejs.j2c.ConnectionFactoryBuilderImpl.createMCF(ConnectionFactoryBuilderImpl.java:1491)
                at com.ibm.ejs.j2c.ConnectionFactoryBuilderImpl.processObjectInstance(ConnectionFactoryBuilderImpl.java:746)
                at com.ibm.ejs.j2c.ConnectionFactoryBuilderImpl.processObjectInstance(ConnectionFactoryBuilderImpl.java:705)
                at com.ibm.ejs.j2c.ConnectionFactoryBuilderImpl.getObjectInstance(ConnectionFactoryBuilderImpl.java:664)
                at javax.naming.spi.NamingManager.getObjectInstanceByFactoryInReference(NamingManager.java:485)
                at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:350)
                at com.ibm.ws.naming.util.Helpers.processSerializedObjectForLookupExt(Helpers.java:927)
                ... 44 more
            Caused by: java.lang.ClassNotFoundException: com.ibm.wsspi.runtime.service.WsServiceRegistry
                at java.lang.ClassNotFoundException.<init>(ClassNotFoundException.java:77)
                at java.net.URLClassLoader.findClass(URLClassLoader.java:383)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:652)
                at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:346)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:618)
                ... 56 more

            javax.naming.CommunicationException: A communication failure occurred while attempting to obtain an initial context with the provider URL: "iiop://xxxx.xxx.com:----".  Make sure that any bootstrap address information in the URL is correct and that the target name server is running.  A bootstrap address with no port specification defaults to port 2809.  Possible causes other than an incorrect bootstrap address or unavailable name server include the network environment and workstation network configuration. [Root exception is org.omg.CORBA.COMM_FAILURE: purge_calls:1988 Reason: CONN_ABORT (1), State: ABORT (5)  vmcid: IBM  minor code: 306 completed: Maybe]
                at com.ibm.ws.naming.util.WsnInitCtxFactory.mapInitialReferenceFailure(WsnInitCtxFactory.java:2269)
                at com.ibm.ws.naming.util.WsnInitCtxFactory.getWsnNameService(WsnInitCtxFactory.java:1457)
                at com.ibm.ws.naming.util.WsnInitCtxFactory.getRootContextFromServer(WsnInitCtxFactory.java:987)
                at com.ibm.ws.naming.util.WsnInitCtxFactory.getRootJndiContext(WsnInitCtxFactory.java:909)
                at com.ibm.ws.naming.util.WsnInitCtxFactory.getInitialContextInternal(WsnInitCtxFactory.java:581)
                at com.ibm.ws.naming.util.WsnInitCtx.getContext(WsnInitCtx.java:124)
                at com.ibm.ws.naming.util.WsnInitCtx.getContextIfNull(WsnInitCtx.java:799)
                at com.ibm.ws.naming.util.WsnInitCtx.createSubcontext(WsnInitCtx.java:370)
                at com.ibm.ws.naming.util.WsnInitCtx.createSubcontext(WsnInitCtx.java:385)
                at javax.naming.InitialContext.createSubcontext(InitialContext.java:523)
                at junit.Test.getContextLocations(Test.java:88)
                at org.apache.struts2.StrutsSpringTestCase.setupBeforeInitDispatcher(StrutsSpringTestCase.java:39)
                at org.apache.struts2.StrutsTestCase.setUp(StrutsTestCase.java:187)
                at junit.framework.TestCase.runBare(TestCase.java:132)
                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.OldTestClassRunner.run(OldTestClassRunner.java:76)
                at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
                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)
            Caused by: org.omg.CORBA.COMM_FAILURE: purge_calls:1988 Reason: CONN_ABORT (1), State: ABORT (5)  vmcid: IBM  minor code: 306 completed: Maybe
                at com.ibm.rmi.iiop.Connection.purge_calls(Connection.java:1987)
                at com.ibm.rmi.iiop.Connection.doReaderWorkOnce(Connection.java:3134)
                at com.ibm.rmi.transport.ReaderThread.run(ReaderPoolImpl.java:138)
Dax
  • 3
  • 4

1 Answers1

0

Replace your been with this

 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource" />
 </bean>
Ashish Gupta
  • 1,651
  • 14
  • 30
  • It produced the same result that I got with the format. The test class does not throw an exception...the project just spits back "Exception" from proxy.execute. I suspect that, due to the corporate environment, I need to set a bunch of properties to make the datasource connection succeed. I will attempt to log a useful stacktrace if I can – Dax Jun 12 '12 at 19:57
  • how can it show same error. The above error was pointing to the constructor argument. Try clean build.:) – Ashish Gupta Jun 12 '12 at 20:06
  • Solved the constructor error at least. I'd +1 the suggestion, but I don't have 15 rep yet. – Dax Jun 14 '12 at 18:05
  • what is the new error?? if problem got solved .accept the answer – Ashish Gupta Jun 14 '12 at 18:07
  • Oh, didn't realize accepting and marking useful were different. I changed the test class significantly...it seems that I have to configure the initial context for the JNDI to be picked up. Normally Websphere handles the context, so right now I'm trying to replicate what Websphere is doing. There is just a java.nullpointerexception because the DAO is null, it's a matter of getting the configuration down. Then the connection will be successful – Dax Jun 15 '12 at 14:00
  • Edited code (removed JndiHelper.java, changed test class), added new stack trace - will post solution if I find it. – Dax Jun 15 '12 at 15:26